Primo display selling items
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
namespace EgwCoreLib.Lux.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Filtro selezione items
|
||||
/// </summary>
|
||||
public class FiltSelect
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string SearchVal { get; set; } = "";
|
||||
public string SelCodGroup { get; set; } = "";
|
||||
public EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS Envir { get; set; } = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.NULL;
|
||||
public Enums.ItemClassType SelType { get; set; } = Enums.ItemClassType.ND;
|
||||
public Enums.ItemSourceType SourceType { get; set; } = Enums.ItemSourceType.ND;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (!(obj is FiltSelect item))
|
||||
return false;
|
||||
|
||||
if (Envir != item.Envir)
|
||||
return false;
|
||||
|
||||
if (SelCodGroup != item.SelCodGroup)
|
||||
return false;
|
||||
|
||||
if (SelType != item.SelType)
|
||||
return false;
|
||||
|
||||
if (SourceType != item.SourceType)
|
||||
return false;
|
||||
|
||||
if (SearchVal != item.SearchVal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -2568,7 +2568,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
// recupero il subset item da BOM...
|
||||
var bomGenList = dbCtx
|
||||
.DbSetItem
|
||||
//.Where(x => x.ItemType == Core.Enums.ItemClassType.Bom)
|
||||
//.Where(x => x.sourceType == Core.Enums.ItemClassType.Bom)
|
||||
.Where(x => (x.ItemType == Core.Enums.ItemClassType.Bom || x.ItemType == Core.Enums.ItemClassType.BomAlt))
|
||||
.ToList();
|
||||
|
||||
@@ -4357,6 +4357,33 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco item da ricerca filtro x gruppo/tipo Async
|
||||
/// </summary>
|
||||
/// <param name="envir"></param>
|
||||
/// <param name="sourceType"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<List<SellingItemModel>> SellingItemGetFiltAsync(EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir, ItemSourceType sourceType)
|
||||
{
|
||||
List<SellingItemModel> dbResult = new List<SellingItemModel>();
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = await dbCtx
|
||||
.DbSetSellItem
|
||||
.Where(x => (x.Envir == envir || envir == Constants.EXECENVIRONMENTS.NULL) && (sourceType == ItemSourceType.ND || x.SourceType == sourceType))
|
||||
.ToListAsync();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante SellingItemGetFiltAsync{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce elenco SellingItem dato sEnvir
|
||||
/// </summary>
|
||||
@@ -4385,6 +4412,55 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
return dbRec;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inserisce o aggiorna il record
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<bool> SellingItemUpsertAsync(SellingItemModel currRec)
|
||||
{
|
||||
bool result = false;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
//try
|
||||
//{
|
||||
var dbResult = await dbCtx
|
||||
.DbSetSellItem
|
||||
.Where(x => x.SellingItemID == currRec.SellingItemID)
|
||||
.FirstOrDefaultAsync();
|
||||
if (dbResult != null)
|
||||
{
|
||||
//dbCtx.DbSetItem.Remove(newCount);
|
||||
dbResult.Cost = currRec.Cost;
|
||||
dbResult.Description = currRec.Description;
|
||||
dbResult.Envir = currRec.Envir;
|
||||
dbResult.ExtItemCode = currRec.ExtItemCode;
|
||||
dbResult.IsService = currRec.IsService;
|
||||
dbResult.ItemCode = currRec.ItemCode;
|
||||
dbResult.ItemSteps = currRec.ItemSteps;
|
||||
dbResult.JobID = currRec.JobID;
|
||||
dbResult.Margin = currRec.Margin;
|
||||
dbResult.SerStruct = currRec.SerStruct;
|
||||
dbResult.SourceType = currRec.SourceType;
|
||||
dbResult.SupplCode = currRec.SupplCode;
|
||||
dbResult.UM = currRec.UM;
|
||||
dbCtx.Entry(dbResult).State = EntityState.Modified;
|
||||
}
|
||||
else
|
||||
{
|
||||
dbCtx.DbSetSellItem.Add(currRec);
|
||||
}
|
||||
await dbCtx.SaveChangesAsync();
|
||||
//}
|
||||
//catch (Exception exc)
|
||||
//{
|
||||
// Log.Error($"Eccezione durante ItemUpsertAsync{Environment.NewLine}{exc}");
|
||||
//}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Ritorna direttamente 1 riga offerta
|
||||
@@ -5066,6 +5142,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua update serStruct per il Template indicato
|
||||
/// </summary>
|
||||
|
||||
@@ -2557,6 +2557,59 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce elenco SellingItem dato envir e ricerca completa Async
|
||||
/// </summary>
|
||||
/// <param name="envir"></param>
|
||||
/// <param name="sourceType"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<SellingItemModel>> SellingItemGetFiltAsync(Constants.EXECENVIRONMENTS envir, ItemSourceType sourceType)
|
||||
{
|
||||
using var activity = StartActivity();
|
||||
string source = "DB";
|
||||
List<SellingItemModel>? result = new List<SellingItemModel>();
|
||||
// cerco in redis...
|
||||
string currKey = $"{redisBaseKey}:SellingItem:{envir}:{sourceType}";
|
||||
RedisValue rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<SellingItemModel>>($"{rawData}");
|
||||
source = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await dbController.SellingItemGetFiltAsync(envir, sourceType);
|
||||
// serializzo e salvo con config x evitare loop...
|
||||
rawData = JsonConvert.SerializeObject(result, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<SellingItemModel>();
|
||||
}
|
||||
activity?.SetTag("data.source", source);
|
||||
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update / Insert record SellingItem
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> SellingItemUpsertAsync(SellingItemModel currRec)
|
||||
{
|
||||
using var activity = StartActivity();
|
||||
string source = "DB+REDIS";
|
||||
bool result = await dbController.SellingItemUpsertAsync(currRec);
|
||||
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Item:*");
|
||||
activity?.SetTag("data.source", source);
|
||||
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco completo Tags disponibili
|
||||
/// </summary>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>1.1.2603.0910</Version>
|
||||
<Version>1.1.2603.0911</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Lux.UI.Components.Compo.Item
|
||||
|
||||
#region Public Classes
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Filtro selezione items
|
||||
/// </summary>
|
||||
@@ -60,7 +61,8 @@ namespace Lux.UI.Components.Compo.Item
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Public Classes
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<h3>SellingItem</h3>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Lux.UI.Components.Compo.Item
|
||||
{
|
||||
public partial class SellingItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
@if (isLoading || ListRecords == null)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-info text-center display-4">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (editRecord != null)
|
||||
{
|
||||
@* <ItemEdit CurrRecord="editRecord" ListItemGroup="ListItemGroup" EC_Updated="DoSave" EC_Close="DoCancel"></ItemEdit> *@
|
||||
}
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-sm btn-primary" title="Reset selezione" @onclick="DoReset"><i class="fa-solid fa-arrow-rotate-right"></i></button>
|
||||
</th>
|
||||
<th>ID</th>
|
||||
<th>Envir</th>
|
||||
<th>Source</th>
|
||||
<th class="text-end">Job ID</th>
|
||||
<th>Serv</th>
|
||||
<th>Codice</th>
|
||||
<th>ItemCode</th>
|
||||
<th>Suppl.Code</th>
|
||||
<th>Descrizione</th>
|
||||
<th class="text-end">Costo</th>
|
||||
<th class="text-end">Margine</th>
|
||||
<th class="text-end">UM</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr>
|
||||
<td class="text-start text-nowrap">
|
||||
<button class="btn btn-sm btn-primary" @onclick="() => DoSelect(item)"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
<button class="btn btn-sm btn-info" @onclick="() => DoEdit(item)"><i class="fa-solid fa-pencil"></i></button>
|
||||
<button class="btn btn-sm @doCloneCss(item)" @onclick="() => DoClone(item)"><i class="fa-solid fa-clone"></i></button>
|
||||
</td>
|
||||
<td>@item.SellingItemID</td>
|
||||
<td>
|
||||
@item.Envir
|
||||
</td>
|
||||
<td>@item.SourceType</td>
|
||||
<td class="text-end text-nowrap">
|
||||
@item.JobID
|
||||
</td>
|
||||
<td>@item.IsService</td>
|
||||
<td>@item.ItemCode</td>
|
||||
<td>@item.ExtItemCode</td>
|
||||
<td>@item.SupplCode</td>
|
||||
<td>@item.Description</td>
|
||||
<td class="text-end text-nowrap">
|
||||
@item.Cost.ToString("C3")
|
||||
</td>
|
||||
<td class="text-end">@item.Margin.ToString("P1")</td>
|
||||
<td class="text-end">@item.UM</td>
|
||||
<td>
|
||||
@if (false)
|
||||
{
|
||||
<button class="btn btn-sm btn-danger" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash-can"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled"><i class="fa-solid fa-trash-can"></i></button>
|
||||
|
||||
}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="15">
|
||||
<EgwCoreLib.Razor.DataPager currPage="@currPage" PageSize="@numRecord" totalCount="@totalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using EgwCoreLib.Lux.Core;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Items;
|
||||
using EgwCoreLib.Lux.Data.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Lux.UI.Components.Compo.Item
|
||||
{
|
||||
public partial class SellingItemMan
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public List<ItemGroupModel> ListItemGroup { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public FiltSelect SelFilt { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Classes
|
||||
|
||||
|
||||
#endregion Public Classes
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected List<SellingItemModel> AllRecords = new List<SellingItemModel>();
|
||||
protected List<SellingItemModel> ListRecords = new List<SellingItemModel>();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected DataLayerServices DLService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Clona articolo
|
||||
/// </summary>
|
||||
/// <param name="curRec"></param>
|
||||
protected void DoClone(SellingItemModel curRec)
|
||||
{
|
||||
editRecord = new SellingItemModel()
|
||||
{
|
||||
Cost = curRec.Cost,
|
||||
Description = $"{curRec.Description} - CLONE",
|
||||
Envir = curRec.Envir,
|
||||
ExtItemCode = curRec.ExtItemCode,
|
||||
IsService = curRec.IsService,
|
||||
ItemCode = curRec.ItemCode,
|
||||
ItemSteps = curRec.ItemSteps,
|
||||
JobID = curRec.JobID,
|
||||
Margin = curRec.Margin,
|
||||
SerStruct = curRec.SerStruct,
|
||||
SourceType = curRec.SourceType,
|
||||
SupplCode = curRec.SupplCode,
|
||||
UM = curRec.UM
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// impossta record x eliminazione
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
protected async Task DoDelete(SellingItemModel selRec)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler eliminare il record? Dettagli: {selRec.SellingItemID} | {selRec.Envir} | {selRec.ExtItemCode} | {selRec.Description}"))
|
||||
return;
|
||||
//// esegue eliminazione del record...
|
||||
//await CDService.SellingItemDeleteAsync(selRec);
|
||||
|
||||
editRecord = null;
|
||||
selRecord = null;
|
||||
await ReloadData();
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edit articolo selezionato
|
||||
/// </summary>
|
||||
/// <param name="curRec"></param>
|
||||
protected void DoEdit(SellingItemModel curRec)
|
||||
{
|
||||
editRecord = curRec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset selezione
|
||||
/// </summary>
|
||||
protected void DoReset()
|
||||
{
|
||||
editRecord = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selezione articolo x display info
|
||||
/// </summary>
|
||||
/// <param name="curRec"></param>
|
||||
protected void DoSelect(SellingItemModel curRec)
|
||||
{
|
||||
selRecord = curRec;
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (!SelFilt.Equals(actFilt) || true)
|
||||
{
|
||||
actFilt = SelFilt;
|
||||
await ReloadData();
|
||||
UpdateTable();
|
||||
}
|
||||
}
|
||||
|
||||
protected void SaveNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
protected void SavePage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private FiltSelect actFilt = new FiltSelect();
|
||||
|
||||
private int currPage = 1;
|
||||
|
||||
private SellingItemModel? editRecord = null;
|
||||
|
||||
private bool isLoading = false;
|
||||
|
||||
private int numRecord = 10;
|
||||
|
||||
private SellingItemModel? selRecord = null;
|
||||
|
||||
private int totalCount = 0;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task DoCancel()
|
||||
{
|
||||
await ResetEdit();
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
private string doCloneCss(SellingItemModel item)
|
||||
{
|
||||
return item.SourceType == Enums.ItemSourceType.ND ? "btn-warning" : "btn-success";
|
||||
}
|
||||
|
||||
private async Task DoSave(SellingItemModel currRec)
|
||||
{
|
||||
// salvo
|
||||
await DLService.SellingItemUpsertAsync(currRec);
|
||||
await ResetEdit();
|
||||
UpdateTable();
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
AllRecords = await DLService.SellingItemGetFiltAsync(actFilt.Envir, actFilt.SourceType);
|
||||
// se ho ricerca testuale faccio filtro ulteriore...
|
||||
if (!string.IsNullOrEmpty(actFilt.SearchVal))
|
||||
{
|
||||
AllRecords = AllRecords
|
||||
.Where(x =>
|
||||
x.Description.Contains(actFilt.SearchVal, StringComparison.InvariantCultureIgnoreCase) ||
|
||||
x.ExtItemCode.Contains(actFilt.SearchVal, StringComparison.InvariantCultureIgnoreCase) ||
|
||||
x.SupplCode.Contains(actFilt.SearchVal, StringComparison.InvariantCultureIgnoreCase))
|
||||
.ToList();
|
||||
}
|
||||
totalCount = AllRecords.Count;
|
||||
}
|
||||
|
||||
private async Task ResetEdit()
|
||||
{
|
||||
// reset edit
|
||||
editRecord = null;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filtro e paginazione
|
||||
/// </summary>
|
||||
private void UpdateTable()
|
||||
{
|
||||
// fix paginazione
|
||||
ListRecords = AllRecords
|
||||
.Skip(numRecord * (currPage - 1))
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<SellingItem></SellingItem>
|
||||
<SellingItemMan SelFilt="CurrFilt" ListItemGroup="ListItemGroup"></SellingItemMan>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
using EgwCoreLib.Lux.Core;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Items;
|
||||
using EgwCoreLib.Lux.Data.Services;
|
||||
using Lux.UI.Components.Compo.Item;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Lux.UI.Components.Pages
|
||||
@@ -15,7 +15,7 @@ namespace Lux.UI.Components.Pages
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected ItemMan.FiltSelect CurrFilt { get; set; } = new ItemMan.FiltSelect();
|
||||
protected FiltSelect CurrFilt { get; set; } = new FiltSelect();
|
||||
|
||||
[Inject]
|
||||
protected DataLayerServices DLService { get; set; } = null!;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50</UserSecretsId>
|
||||
<Version>1.1.2603.0910</Version>
|
||||
<Version>1.1.2603.0911</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>LUX - Web Windows MES</i>
|
||||
<h4>Versione: 1.1.2603.0910</h4>
|
||||
<h4>Versione: 1.1.2603.0911</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.1.2603.0910
|
||||
1.1.2603.0911
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.1.2603.0910</version>
|
||||
<version>1.1.2603.0911</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user