Continuo gestione ricette conf/archivio

This commit is contained in:
Samuele Locatelli
2023-04-03 17:28:45 +02:00
parent 03a8910399
commit 5d3f39cff0
6 changed files with 445 additions and 14 deletions
+16 -7
View File
@@ -25,7 +25,7 @@ else
<th>Cod</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
@if (!showRecipe)
@if (!(showRecipeConf || showRecipeArch))
{
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-solid fa-circle-info"></i> Info ciclo</th>
@@ -39,7 +39,7 @@ else
{
<tr class="@checkSelect(@record)">
<td class="text-nowrap" style="width: 8rem;">
@if (!showRecipe)
@if (!showRecipeConf)
{
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm mx-1" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
@if (record.IdxOdl == 0)
@@ -120,7 +120,7 @@ else
</div>
}
</td>
@if (!showRecipe)
@if (!(showRecipeConf || showRecipeArch))
{
<td>
@record.IdxMacchina
@@ -152,11 +152,20 @@ else
</tbody>
</table>
</div>
@if (showRecipe && currRecord != null)
@if (currRecord != null)
{
<div class="col-6 ps-0">
<RecipeMan IdxPODL="@currRecord.IdxPromessa" RecipePath="@currRecipePath" CancelEvent="resetSel"></RecipeMan>
</div>
@if (showRecipeConf)
{
<div class="col-6 ps-0">
<RecipeConfMan IdxPODL="@currRecord.IdxPromessa" RecipePath="@currRecipePath" CancelEvent="resetSel"></RecipeConfMan>
</div>
}
else if(showRecipeArch)
{
<div class="col-6 ps-0">
<RecipeArchMan IdxPODL="@currRecord.IdxPromessa" RecipeArchPath="@currRecipePath" CancelEvent="resetSel"></RecipeArchMan>
</div>
}
}
</div>
}
+8 -6
View File
@@ -112,15 +112,15 @@ namespace MP.SPEC.Components
{
currRecord = selRec;
currRecipePath = await MDService.MacchineRecipeConf(selRec.IdxMacchina);
showRecipe = true;
showRecipeConf = true;
}
protected async Task doShowRecipeArch(PODLExpModel selRec)
{
currRecord = selRec;
currRecipeArchPath = await MDService.MacchineRecipeArchive(selRec.IdxMacchina);
showRecipe = true;
showRecipeArch = true;
}
protected override async Task OnInitializedAsync()
{
@@ -158,7 +158,8 @@ namespace MP.SPEC.Components
{
currRecord = null;
currRecipePath = "";
showRecipe = false;
showRecipeArch = false;
showRecipeConf = false;
await RecordSel.InvokeAsync(null);
}
@@ -257,7 +258,8 @@ namespace MP.SPEC.Components
private List<PODLExpModel>? SearchRecords;
private bool showRecipe = false;
private bool showRecipeConf = false;
private bool showRecipeArch = false;
#endregion Private Fields
@@ -289,7 +291,7 @@ namespace MP.SPEC.Components
private string mainCss
{
get => showRecipe ? "col-6" : "col-12";
get => (showRecipeConf || showRecipeArch) ? "col-6" : "col-12";
}
private int numRecord
+268
View File
@@ -0,0 +1,268 @@
using Microsoft.AspNetCore.Components;
using MP.Data.MgModels;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class RecipeArchMan
{
#region Public Properties
[Parameter]
public EventCallback<bool> CancelEvent { get; set; }
[Parameter]
public int IdxPODL { get; set; } = 0;
[Parameter]
public string RecipeArchPath { get; set; } = "";
#endregion Public Properties
#region Protected Fields
protected bool isLoading = false;
#endregion Protected Fields
#region Protected Properties
protected RecipeModel? CurrRecipe { get; set; } = null;
[Inject]
protected MpDataService MDService { get; set; } = null!;
protected RecipeModel? OrigRecipe { get; set; } = null;
#endregion Protected Properties
#region Protected Methods
protected async Task CancelHeadData()
{
await ReloadData();
}
protected Dictionary<string, string> GetHeadListByType(string DictType)
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// in primis il "selezionare"
answ.Add("", "--- Selezionare ---");
// cerco tipo in enums...
if (CurrRecipe != null && CurrRecipe.HeadConf.EnumVal.ContainsKey(DictType))
{
foreach (var item in CurrRecipe.HeadConf.EnumVal[DictType])
{
answ.Add(item.Key, item.Value);
}
}
return answ;
}
protected Dictionary<string, string> GetRowListByType(string DictType)
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// in primis il "selezionare"
answ.Add("", "--- Selezionare ---");
// cerco tipo in enums...
if (CurrRecipe != null && CurrRecipe.RowsConf.EnumVal.ContainsKey(DictType))
{
foreach (var item in CurrRecipe.RowsConf.EnumVal[DictType])
{
answ.Add(item.Key, item.Value);
}
}
return answ;
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SaveHeadData()
{
if (CurrRecipe != null)
{
await MDService.RecipeSetByPODL(CurrRecipe);
await ReloadData();
}
}
#endregion Protected Methods
#region Private Fields
private bool showAllRows = false;
private bool showHead = true;
private Dictionary<string, bool> showRows = new Dictionary<string, bool>();
#endregion Private Fields
#region Private Properties
private bool needSave
{
get
{
bool answ = false;
if (CurrRecipe != null && OrigRecipe != null)
{
answ = !(CurrRecipe.HeadVal.SequenceEqual(OrigRecipe.HeadVal));
if (!answ)
{
// verifico nu righe...
answ = (CurrRecipe.RowsVal.Count != OrigRecipe.RowsVal.Count);
if (!answ)
{
try
{
foreach (var item in CurrRecipe.RowsVal)
{
answ = !(item.Value.SequenceEqual(OrigRecipe.RowsVal[item.Key]));
if (answ)
{
break;
}
}
}
catch (Exception exc)
{
answ = true;
}
}
}
}
return answ;
}
}
#endregion Private Properties
#region Private Methods
private async Task addRow()
{
isLoading = true;
if (CurrRecipe != null)
{
// preparo dizionario valori calcolati
Dictionary<string, string> CalcArgs = await getCalcArgs();
int newNumRow = CurrRecipe.RowsVal.Count + 1;
CalcArgs.Add("RowNum", $"{newNumRow}");
CalcArgs.Add("RowTot", $"{newNumRow}");
// metodo x avere nuova
var rowElem = CurrRecipe.getNewRow(CalcArgs);
// effettuo aggiunta riga...
CurrRecipe.RowsVal.Add($"{newNumRow}", rowElem);
fixRowsShowStatus();
}
isLoading = false;
await Task.Delay(1);
}
/// <summary>
/// Elimino riga (ultima)...
/// </summary>
/// <param name="rowNum"></param>
/// <returns></returns>
private async Task deleteRow(string rowNum)
{
isLoading = true;
if (CurrRecipe != null)
{
// verifico esista...
if (CurrRecipe.RowsVal.ContainsKey(rowNum))
{
CurrRecipe.RowsVal.Remove(rowNum);
fixRowsShowStatus();
}
}
isLoading = false;
await Task.Delay(1);
}
private void fixRowsShowStatus()
{
// sistemo lista bool x righe
showRows = new Dictionary<string, bool>();
if (CurrRecipe != null)
{
for (int i = 1; i <= CurrRecipe.RowsVal.Count; i++)
{
showRows.Add($"{i}", false);
}
}
}
/// <summary>
/// Prepara Dict args calcolati x creazione ricetta
/// </summary>
/// <returns></returns>
private async Task<Dictionary<string, string>> getCalcArgs()
{
// preparo dizionario valori calcolati
Dictionary<string, string> CalcArgs = new Dictionary<string, string>();
// aggiungo dati PODL
CalcArgs.Add("IdxPODL", $"{IdxPODL}");
CalcArgs.Add("CodePODL", $"PODL{IdxPODL:00000000}");
// recupero altri dati da PODL
var rowPodl = await MDService.PODL_getByKey(IdxPODL);
if (rowPodl != null)
{
CalcArgs.Add("CodArticolo", rowPodl.CodArticolo);
CalcArgs.Add("DescArticolo", rowPodl.ArticoloNav.DescArticolo);
}
return CalcArgs;
}
private async Task ReloadData()
{
await Task.Delay(1);
isLoading = true;
if (IdxPODL != 0 && !string.IsNullOrEmpty(RecipeArchPath))
{
CurrRecipe = new RecipeModel();
// effettua ricerca ricetta su MongoDb
CurrRecipe = await MDService.RecipeGetByPODL(IdxPODL);
// se non trova crea nuova...
if (CurrRecipe == null)
{
Dictionary<string, string> CalcArgs = await getCalcArgs();
CurrRecipe = MDService.InitRecipe(RecipeArchPath, IdxPODL, CalcArgs);
// la salvo...
await MDService.RecipeSetByPODL(CurrRecipe);
}
// rileggo la default
OrigRecipe = await MDService.RecipeGetByPODL(IdxPODL);
fixRowsShowStatus();
}
await Task.Delay(1);
isLoading = false;
}
private void toggleHead()
{
showHead = !showHead;
}
private async Task toggleRow(string rowNum)
{
showRows[rowNum] = !showRows[rowNum];
await Task.Delay(1);
}
private async Task toggleRows()
{
showAllRows = !showAllRows;
foreach (var item in showRows)
{
showRows[item.Key] = showAllRows;
}
await Task.Delay(1);
}
#endregion Private Methods
}
}
+152
View File
@@ -0,0 +1,152 @@
@using MP.Data.MgModels;
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<div class="card shadow p-0 mb-5 bg-body rounded">
<div class="card-header">
<div class="d-flex justify-content-between">
<div>
<h4>Testata Ricetta</h4>
</div>
<div>
<a href="api/Recipe/GetRecipeXML?idxPODL=@IdxPODL" target="_blank" class="btn btn-sm btn-success">XML <i class="fa-solid fa-file-export"></i></a>
<a href="api/Recipe/GetRecipe?idxPODL=@IdxPODL" target="_blank" class="btn btn-sm btn-success">json <i class="fa-solid fa-file-export"></i></a>
@if (!showHead)
{
<span class="px-2"><b>@CurrRecipe?.HeadVal.Count</b> par</span>
}
@if (needSave)
{
<button class="btn btn-sm btn-success" @onclick="() => SaveHeadData()"><i class="fa-regular fa-floppy-disk"></i> Save</button>
<button class="btn btn-sm btn-warning" @onclick="() => CancelHeadData()"><i class="fa-solid fa-xmark"></i> Cancel</button>
}
<button class="btn btn-sm btn-outline-dark" @onclick="toggleHead">
@if (showHead)
{
<i class="fa-solid fa-chevron-up"></i>
}
else
{
<i class="fa-solid fa-chevron-down"></i>
}
</button>
</div>
</div>
@if (showHead && CurrRecipe?.HeadVal != null)
{
<div class="row g-1">
@foreach (var item in CurrRecipe.HeadVal)
{
<div class="col-3">
<div class="form-floating">
@if (item.Type == RecipeModel.Element.KeyType.Fixed || item.Type == RecipeModel.Element.KeyType.Calc)
{
<input type="text" class="form-control" @bind="@item.Value" disabled>
}
else if (item.Type == MP.Data.MgModels.RecipeModel.Element.KeyType.Enum)
{
<select class="form-select" @bind="@item.Value">
@foreach (var enumItem in GetHeadListByType(item.EnumType))
{
<option value="@enumItem.Key">@enumItem.Value</option>
}
</select>
}
else
{
<input type="text" class="form-control" placeholder="@item.Key" @bind="@item.Value">
}
<label>@item.Key</label>
</div>
</div>
}
</div>
}
</div>
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h5>Righe Ricetta</h5>
</div>
<div>
<button class="btn btn-sm btn-success" @onclick="addRow" title="Aggiunta Nuova Riga"><i class="fa-solid fa-plus"></i> Add</button>
<button class="btn btn-sm btn-outline-dark" @onclick="toggleRows">
@if (showAllRows)
{
<i class="fa-solid fa-chevron-up"></i>
}
else
{
<i class="fa-solid fa-chevron-down"></i>
}
</button>
</div>
</div>
@if (CurrRecipe?.RowsVal != null)
{
int rowTot = CurrRecipe.RowsVal.Count;
int rowNum = 0;
@foreach (var riga in CurrRecipe.RowsVal)
{
rowNum++;
<div class="d-flex justify-content-between">
<div>
# <b>@riga.Key</b>
</div>
<div>
@if (rowNum == rowTot)
{
<button class="btn btn-sm btn-danger" @onclick="() => deleteRow(riga.Key)" title="Rimuovi Ultima Riga"><i class="fa-solid fa-minus"></i></button>
}
<button class="btn btn-sm" @onclick="() => toggleRow(riga.Key)">
@if (showRows[riga.Key])
{
<i class="fa-solid fa-chevron-up"></i>
}
else
{
<i class="fa-solid fa-chevron-down"></i>
}
</button>
</div>
</div>
@if (showRows[riga.Key])
{
<div class="row g-1">
@foreach (var item in riga.Value)
{
<div class="col-3">
<div class="form-floating">
@if (item.Type == RecipeModel.Element.KeyType.Fixed || item.Type == RecipeModel.Element.KeyType.Calc)
{
<input type="text" class="form-control" @bind="@item.Value" disabled>
}
else if (item.Type == MP.Data.MgModels.RecipeModel.Element.KeyType.Enum)
{
<select class="form-select" @bind="@item.Value">
@foreach (var enumItem in GetRowListByType(item.EnumType))
{
<option value="@enumItem.Key">@enumItem.Value</option>
}
</select>
}
else
{
<input type="text" class="form-control" placeholder="@item.Key" @bind="@item.Value">
}
<label>@item.Key</label>
</div>
</div>
}
</div>
}
}
}
</div>
</div>
}
@@ -7,7 +7,7 @@ using Newtonsoft.Json;
namespace MP.SPEC.Components
{
public partial class RecipeMan
public partial class RecipeConfMan
{
#region Public Properties