From 417aaa9d28e88b9b406080b415ba6179d2d71dfe Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 22 Oct 2024 18:37:30 +0200 Subject: [PATCH 1/9] PROG - fix gestione display versioni fix update in selezione --- MP.FileData/Controllers/FileController.cs | 38 +++++++ MP.Prog/Components/DiffView.razor | 11 +- MP.Prog/Components/DiffView.razor.cs | 21 ++-- MP.Prog/Components/FileEditor.razor | 97 ++++++++++++----- MP.Prog/Components/FileEditor.razor.cs | 120 ++++++++++++++++++++-- MP.Prog/Components/TagSearch.razor | 2 +- MP.Prog/Data/FileArchDataService.cs | 11 ++ MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Pages/Archive.razor | 23 ++--- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.Prog/appsettings.Development.json | 2 +- 13 files changed, 267 insertions(+), 66 deletions(-) diff --git a/MP.FileData/Controllers/FileController.cs b/MP.FileData/Controllers/FileController.cs index acdb8df1..3cea0400 100644 --- a/MP.FileData/Controllers/FileController.cs +++ b/MP.FileData/Controllers/FileController.cs @@ -331,6 +331,11 @@ namespace MP.FileData.Controllers return done; } + /// + /// Cerca il file x chiave ID + /// + /// + /// public FileModel FileGetByKey(int FileId) { FileModel thisFile = null; @@ -344,6 +349,39 @@ namespace MP.FileData.Controllers return thisFile; } + /// + /// Cerca un file dato un fice successivo specificando rev richiesta) + /// + /// + /// + /// + public FileModel FileGetByKeyRev(int FileId, int Rev) + { + FileModel oFile = null; + FileModel tFile = null; + using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) + { + oFile = localDbCtx + .DbSetProgFile + .Where(x => x.FileId == FileId) + .FirstOrDefault(); + // se la rev è diversa --> la cerco! + if (oFile.Rev == Rev) + { + tFile = oFile; + } + else + { + tFile = localDbCtx + .DbSetProgFile + .Where(x => x.Name == oFile.Name && x.IdxMacchina == oFile.IdxMacchina && x.Path == oFile.Path) + .FirstOrDefault(); + } + } + return tFile; + } + + public List FileGetByPath(string path, bool onlyActive) { List dbResult = new List(); diff --git a/MP.Prog/Components/DiffView.razor b/MP.Prog/Components/DiffView.razor index f1c3b368..76624666 100644 --- a/MP.Prog/Components/DiffView.razor +++ b/MP.Prog/Components/DiffView.razor @@ -6,7 +6,7 @@
-

Archivio

+

@OldTitle

@@ -18,7 +18,14 @@
-

Attuale

+ @if(CompareVers) + { +

@NewTitle

+ } + else + { +

@NewTitle

+ }
diff --git a/MP.Prog/Components/DiffView.razor.cs b/MP.Prog/Components/DiffView.razor.cs index 73e490dc..098e1d94 100644 --- a/MP.Prog/Components/DiffView.razor.cs +++ b/MP.Prog/Components/DiffView.razor.cs @@ -12,23 +12,32 @@ namespace MP.Prog.Components { #region Public Properties + [Parameter] + public bool CompareVers { get; set; } = false; + [Parameter] public EventCallback diffDone { get; set; } [Parameter] - public string newText + public string NewText { get => _newText; set => _newText = value; } [Parameter] - public string oldText + public string NewTitle { get; set; } = "Attuale"; + + [Parameter] + public string OldText { get => _oldText; set => _oldText = value; } + [Parameter] + public string OldTitle { get; set; } = "Archivio"; + #endregion Public Properties #region Protected Fields @@ -69,7 +78,7 @@ namespace MP.Prog.Components numChanges = 0; // calcolo diff diff_match_patch dmp = new diff_match_patch(); - List diff = dmp.diff_main(oldText, newText); + List diff = dmp.diff_main(OldText, NewText); //List diff = dmp.diff_main(oldTextFix, newTextFix); dmp.diff_cleanupSemantic(diff); @@ -86,12 +95,12 @@ namespace MP.Prog.Components switch (item.operation) { case Operation.DELETE: - sbOld.Append($"{HttpUtility.HtmlEncode(item.text)}"); + sbOld.Append($"{HttpUtility.HtmlEncode(item.text)}"); numChanges++; break; case Operation.INSERT: - sbNew.Append($"{HttpUtility.HtmlEncode(item.text)}"); + sbNew.Append($"{HttpUtility.HtmlEncode(item.text)}"); numChanges++; break; @@ -129,8 +138,6 @@ namespace MP.Prog.Components string fixVal = origVal.Trim() .Replace(" ", "  ") .Replace(Environment.NewLine, sepDest); - //.Replace("\r", sepDest) - //.Replace("\n", sepDest); return new MarkupString(fixVal); } diff --git a/MP.Prog/Components/FileEditor.razor b/MP.Prog/Components/FileEditor.razor index be370606..8f4b4f58 100644 --- a/MP.Prog/Components/FileEditor.razor +++ b/MP.Prog/Components/FileEditor.razor @@ -1,43 +1,86 @@ 
-
-
+
+
-

Dettaglio modifiche

+
+
+

Dettaglio modifiche

+
+
- @if (_currItem.Active) - { - @if (_currItem.DiskStatus != FileData.FileState.Ok) +
+ @if (_currItem.Rev > 0) { -
-
- +
+ @if (CompareRev) + { +
+ SX + + DX + + +
+ } + else + { + + } +
+ } + @if (_currItem.Active) + { + @if (_currItem.DiskStatus != FileData.FileState.Ok) + { +
+
+
+ +
+
+ +
+
-
- + } + } + else + { +
+
+
+ +
+
+
} - } - else - { -
-
- -
-
-
-
- } +
-
-
-
- +
+
- +
\ No newline at end of file diff --git a/MP.Prog/Components/FileEditor.razor.cs b/MP.Prog/Components/FileEditor.razor.cs index 20f5e634..b8fc6a45 100644 --- a/MP.Prog/Components/FileEditor.razor.cs +++ b/MP.Prog/Components/FileEditor.razor.cs @@ -47,6 +47,86 @@ namespace MP.Prog.Components #endregion Public Properties + private bool CompareRev = false; + protected int SelRevSx + { + get => _selRevSx; + set + { + if (_selRevSx != value) + { + _selRevSx = value; + // ricarico file SX + var pUpd = Task.Run(async () => + { + await LoadRevision(); + }); + pUpd.Wait(); + FixTitles(); + } + } + } + protected int SelRevDx + { + get => _selRevDx; + set + { + if (_selRevDx != value) + { + _selRevDx = value; + // ricarico file DX + var pUpd = Task.Run(async () => + { + await LoadRevision(); + }); + pUpd.Wait(); + FixTitles(); + } + } + } + private int _selRevSx = 0; + private int _selRevDx = 0; + + private List ListRevSx + { + get + { + List answ = new List() { 0 }; + for (int i = 1; i < SelRevDx; i++) + { + answ.Add(i); + } + return answ; + } + } + private List ListRevDx + { + get + { + List answ = new List(); + for (int i = 0; i <= _currItem.Rev; i++) + { + answ.Add(i); + } + return answ; + } + } + + + private async Task DoCompare() + { + CompareRev = !CompareRev; + await LoadRevision(); + FixTitles(); + } + + private void FixTitles() + { + // sistemo titoli + TitleSx = CompareRev ? $"Rev. {SelRevSx}" : "Archivio"; + TitleDx = CompareRev ? $"Rev. {SelRevDx}" : "Attuale"; + } + #region Public Methods public string CurrFileContent(string fullPath) @@ -91,12 +171,6 @@ namespace MP.Prog.Components #endregion Protected Methods - //private string userName = ""; - //protected override void OnInitialized() - //{ - // userName = MServ.UserName; - //} - #region Private Methods private async Task ApproveChange() @@ -150,7 +224,7 @@ namespace MP.Prog.Components await DataReset.InvokeAsync(0); await FDService.FileExport(_currItem); await DataReset.InvokeAsync(0); - await FDService.UpdateMachineArchive(_currItem.IdxMacchina, 1, false, false,MServ.UserName); + await FDService.UpdateMachineArchive(_currItem.IdxMacchina, 1, false, false, MServ.UserName); await DataUpdated.InvokeAsync(1); } else @@ -188,6 +262,38 @@ namespace MP.Prog.Components } } + private string FileContSx { get; set; } = ""; + private string FileContDx { get; set; } = ""; + + private string TitleSx { get; set; } = "Archivio"; + private string TitleDx { get; set; } = "Attuale"; + + + protected override void OnParametersSet() + { + FileContSx = _currItem.FileStringContent; + FileContDx = CurrFileContent(_currItem.Path); + SelRevDx = _currItem.Rev; + FixTitles(); + } + + private async Task LoadRevision() + { + if (CompareRev) + { + var reqSx = await FDService.FileGetByKeyRev(_currItem.FileId, SelRevSx); + var reqDx = await FDService.FileGetByKeyRev(_currItem.FileId, SelRevDx); + FileContSx = reqSx.FileStringContent; + FileContDx = reqDx.FileStringContent; + } + else + { + FileContSx = _currItem.FileStringContent; + FileContDx = CurrFileContent(_currItem.Path); + } + FixTitles(); + } + #endregion Private Methods } } \ No newline at end of file diff --git a/MP.Prog/Components/TagSearch.razor b/MP.Prog/Components/TagSearch.razor index d1bf7e85..c16def20 100644 --- a/MP.Prog/Components/TagSearch.razor +++ b/MP.Prog/Components/TagSearch.razor @@ -14,7 +14,7 @@
- @if (TagList != null) { foreach (var item in TagList) diff --git a/MP.Prog/Data/FileArchDataService.cs b/MP.Prog/Data/FileArchDataService.cs index e5a352af..c01312cc 100644 --- a/MP.Prog/Data/FileArchDataService.cs +++ b/MP.Prog/Data/FileArchDataService.cs @@ -169,6 +169,17 @@ namespace MP.Prog.Data { return Task.FromResult(dbController.FileGetByKey(FileId)); } + /// + /// Restituisce il file dato un ID + revisione + /// cerca a pari nome, macchina + REV specifica) + /// + /// Id del file originale + /// Rev specifica richiesta + /// + public Task FileGetByKeyRev(int FileId, int Rev) + { + return Task.FromResult(dbController.FileGetByKeyRev(FileId, Rev)); + } public async Task> FileGetFilt(SelectData CurrFilter) { diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 5c77f33a..6aa9bb42 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net6.0 MP.Prog - 6.16.2410.2211 + 6.16.2410.2218 diff --git a/MP.Prog/Pages/Archive.razor b/MP.Prog/Pages/Archive.razor index 2039d0c7..dfeeeedc 100644 --- a/MP.Prog/Pages/Archive.razor +++ b/MP.Prog/Pages/Archive.razor @@ -123,18 +123,7 @@ { - @if (currRecord == null) - { - - } - else - { - - } +
@@ -150,11 +139,11 @@ @record.Rev
- - - @record.DiskStatus - - + + + @record.DiskStatus + +
@CalcSize(record.Size) diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index b2c82f16..b605f0cc 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

Versione: 6.16.2410.2211

+

Versione: 6.16.2410.2218


Note di rilascio:
    diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 608c2973..ec69c37d 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2211 +6.16.2410.2218 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index bfe55f7a..a5145f6a 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2211 + 6.16.2410.2218 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/appsettings.Development.json b/MP.Prog/appsettings.Development.json index 9645b0c6..fb218b9a 100644 --- a/MP.Prog/appsettings.Development.json +++ b/MP.Prog/appsettings.Development.json @@ -1,5 +1,5 @@ { - //"DetailedErrors": true, + "DetailedErrors": true, "Logging": { "LogLevel": { "Default": "Information", From 18c58522a2c24f3a8d5c5cc1a8ec594a629d5093 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 22 Oct 2024 19:25:48 +0200 Subject: [PATCH 2/9] PROG; - Fix filtro file e username --- MP.FileData/Controllers/FileController.cs | 6 ++- MP.Prog/Components/FileEditor.razor.cs | 1 + MP.Prog/Data/FileArchDataService.cs | 5 +-- MP.Prog/Data/SelectData.cs | 7 ++- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Pages/Archive.razor | 23 ++++++---- MP.Prog/Pages/Archive.razor.cs | 55 ++++++++++++++++++----- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- 10 files changed, 74 insertions(+), 31 deletions(-) diff --git a/MP.FileData/Controllers/FileController.cs b/MP.FileData/Controllers/FileController.cs index 3cea0400..a1e46967 100644 --- a/MP.FileData/Controllers/FileController.cs +++ b/MP.FileData/Controllers/FileController.cs @@ -247,7 +247,7 @@ namespace MP.FileData.Controllers dbCtx.Dispose(); } - public int FileCountFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string Tag, string SearchVal) + public int FileCountFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal) { int answ = 0; using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) @@ -259,6 +259,7 @@ namespace MP.FileData.Controllers && (x.Active == OnlyActive || !OnlyActive) && (x.Tags.Count() == 0 || !OnlyNoTag) && (!OnlyMod || x.DiskStatus != FileState.Ok) && (x.Path.Equals(FileName) || string.IsNullOrEmpty(FileName)) + && (x.UserAppr.Equals(UserName) || string.IsNullOrEmpty(UserName)) && (x.Tags.Where(t => t.TagId == Tag).Count() > 0 || string.IsNullOrEmpty(Tag)) && ((!string.IsNullOrEmpty(SearchVal) && (x.Path.Contains(SearchVal) || x.Tags.Where(t => t.TagId.Contains(SearchVal)).Count() > 0)) || string.IsNullOrEmpty(SearchVal)) ).Count(); @@ -397,7 +398,7 @@ namespace MP.FileData.Controllers return dbResult; } - public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string Tag, string SearchVal, int NumStart, int NumRecords) + public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal, int NumStart, int NumRecords) { List dbResult = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) @@ -411,6 +412,7 @@ namespace MP.FileData.Controllers && (x.Active == OnlyActive || !OnlyActive) && (x.Tags.Count() == 0 || !OnlyNoTag) && (!OnlyMod || x.DiskStatus != FileState.Ok) && (x.Path.Equals(FileName) || string.IsNullOrEmpty(FileName)) + && (x.UserAppr.Equals(UserName) || string.IsNullOrEmpty(UserName)) && (x.Tags.Where(t => t.TagId == Tag).Count() > 0 || string.IsNullOrEmpty(Tag)) && ((!string.IsNullOrEmpty(SearchVal) && (x.Path.Contains(SearchVal) || x.Tags.Where(t => t.TagId.Contains(SearchVal)).Count() > 0)) || string.IsNullOrEmpty(SearchVal)) ).OrderByDescending(x => x.LastMod) diff --git a/MP.Prog/Components/FileEditor.razor.cs b/MP.Prog/Components/FileEditor.razor.cs index b8fc6a45..40dd4f56 100644 --- a/MP.Prog/Components/FileEditor.razor.cs +++ b/MP.Prog/Components/FileEditor.razor.cs @@ -30,6 +30,7 @@ namespace MP.Prog.Components set { _currItem = value; + CompareRev = false; } } diff --git a/MP.Prog/Data/FileArchDataService.cs b/MP.Prog/Data/FileArchDataService.cs index c01312cc..5fb05c99 100644 --- a/MP.Prog/Data/FileArchDataService.cs +++ b/MP.Prog/Data/FileArchDataService.cs @@ -158,7 +158,7 @@ namespace MP.Prog.Data int numCount = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - numCount = dbController.FileCountFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal); + numCount = dbController.FileCountFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.UserName, CurrFilter.Tag, CurrFilter.SearchVal); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per FileCountFilt: {ts.TotalMilliseconds} ms"); @@ -186,8 +186,7 @@ namespace MP.Prog.Data List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal, CurrFilter.NumSkip, CurrFilter.PageSize).ToList(); - //dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.FirstRecord, CurrFilter.PageSize * 10, CurrFilter.SearchVal).ToList(); + dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.UserName, CurrFilter.Tag, CurrFilter.SearchVal, CurrFilter.NumSkip, CurrFilter.PageSize).ToList(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per FileGetFilt: {ts.TotalMilliseconds} ms"); diff --git a/MP.Prog/Data/SelectData.cs b/MP.Prog/Data/SelectData.cs index 577fdcdf..581a7aba 100644 --- a/MP.Prog/Data/SelectData.cs +++ b/MP.Prog/Data/SelectData.cs @@ -14,6 +14,8 @@ namespace MP.Prog.Data public string FileName { get; set; } = ""; + public string UserName { get; set; } = ""; + /// /// Primo record x selezione paginata, tipicamente primo della "decina" della pagina corrente /// @@ -67,7 +69,8 @@ namespace MP.Prog.Data { DateEnd = endRounded, DateStart = endRounded.AddDays(-numDayPrev), - SearchVal = "" + SearchVal = "", + UserName="" }; return answ; } @@ -91,6 +94,8 @@ namespace MP.Prog.Data return false; if (FileName != item.FileName) return false; + if (UserName != item.UserName) + return false; if (IdxMacchina != item.IdxMacchina) return false; if (Tag != item.Tag) diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 6aa9bb42..89755597 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net6.0 MP.Prog - 6.16.2410.2218 + 6.16.2410.2219 diff --git a/MP.Prog/Pages/Archive.razor b/MP.Prog/Pages/Archive.razor index dfeeeedc..3214dbaa 100644 --- a/MP.Prog/Pages/Archive.razor +++ b/MP.Prog/Pages/Archive.razor @@ -50,28 +50,28 @@
-
+
@if (!string.IsNullOrEmpty(SelFileName)) { - @TextReduce(SelFileName, 20) + @TextReduce(SelFileName, 20) + } + @if (!string.IsNullOrEmpty(SelUserName)) + { + @TextReduce(SelUserName, 20) }
-
+
Tags -
+
@if (!string.IsNullOrEmpty(SelTag)) { @SelTag } - else - { -   ...   - }
+}
diff --git a/MP.Prog/Pages/Archive.razor.cs b/MP.Prog/Pages/Archive.razor.cs index e79a7898..20e47c48 100644 --- a/MP.Prog/Pages/Archive.razor.cs +++ b/MP.Prog/Pages/Archive.razor.cs @@ -106,7 +106,7 @@ namespace MP.Prog.Pages #region Protected Methods - protected async Task AsyncReload() + protected async Task ReloadAsync() { isLoading = true; currRecord = null; @@ -146,6 +146,15 @@ namespace MP.Prog.Pages isLoading = false; } + protected async Task FilterUserName(string userName) + { + SelUserName = userName; + currPage = 1; + //await ReloadAllData(); + await Task.Delay(1); + isLoading = false; + } + protected async Task FilterTag(string searchVal) { SelTag = searchVal; @@ -215,10 +224,8 @@ namespace MP.Prog.Pages // importante altrimenti NON mostra update UI await Task.Delay(1); totalCount = await FDService.FileCountFilt(MServ.File_Filter); - //SearchRecords = await FDService.FileGetFilt(MServ.File_Filter); - //// faccio paginazione SOLO NELLA DECINA attuale... (quindi non tutte le pagine ma solo subset) - //ListRecords = SearchRecords.Skip(numRecord * (currPage % 10 - 1)).Take(numRecord).ToList(); + // valutare recupero info + redis + pagiazione EX POST... ListRecords = await FDService.FileGetFilt(MServ.File_Filter); await Task.Delay(1); } @@ -336,7 +343,7 @@ namespace MP.Prog.Pages MServ.File_Filter.OnlyActive = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -361,7 +368,7 @@ namespace MP.Prog.Pages MServ.File_Filter.OnlyMod = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -386,7 +393,7 @@ namespace MP.Prog.Pages MServ.File_Filter.OnlyNoTag = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -411,7 +418,7 @@ namespace MP.Prog.Pages MServ.File_Filter.SearchVal = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -436,7 +443,31 @@ namespace MP.Prog.Pages MServ.File_Filter.FileName = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); + }); + pUpd.Wait(); + } + } + } + private string SelUserName + { + get + { + string answ = ""; + if (MServ.File_Filter != null) + { + answ = MServ.File_Filter.UserName; + } + return answ; + } + set + { + if (!MServ.File_Filter.UserName.Equals(value)) + { + MServ.File_Filter.UserName = value; + var pUpd = Task.Run(async () => + { + await ReloadAsync(); }); pUpd.Wait(); } @@ -461,7 +492,7 @@ namespace MP.Prog.Pages MServ.File_Filter.IdxMacchina = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -486,7 +517,7 @@ namespace MP.Prog.Pages MServ.File_Filter.Tag = value; var pUpd = Task.Run(async () => { - await AsyncReload(); + await ReloadAsync(); }); pUpd.Wait(); } @@ -532,7 +563,7 @@ namespace MP.Prog.Pages { DeleteDialogOpen = false; currPage = 1; - await AsyncReload(); + await ReloadAsync(); //StateHasChanged(); } diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index b605f0cc..a3ed871e 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

Versione: 6.16.2410.2218

+

Versione: 6.16.2410.2219


Note di rilascio:
    diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index ec69c37d..3cfca690 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2218 +6.16.2410.2219 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index a5145f6a..af79ea5d 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2218 + 6.16.2410.2219 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false From b4275d84c820a886f22459489155c0956751fbe6 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 22 Oct 2024 19:38:13 +0200 Subject: [PATCH 3/9] PROG - fix display elenco --- MP.Prog/Pages/Archive.razor | 56 ++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/MP.Prog/Pages/Archive.razor b/MP.Prog/Pages/Archive.razor index 3214dbaa..967f76db 100644 --- a/MP.Prog/Pages/Archive.razor +++ b/MP.Prog/Pages/Archive.razor @@ -108,9 +108,17 @@ - + - + + @@ -128,43 +136,41 @@ - + - - @**@ @@ -162,21 +161,30 @@
    @CalcSize(record.Size)
    -
    +
    @if (!string.IsNullOrEmpty(record.UserAppr)) { - } + else + { + + + }
    - + } @@ -197,6 +212,6 @@ } \ No newline at end of file diff --git a/MP.Prog/Pages/Archive.razor.cs b/MP.Prog/Pages/Archive.razor.cs index af50582a..7d5039fd 100644 --- a/MP.Prog/Pages/Archive.razor.cs +++ b/MP.Prog/Pages/Archive.razor.cs @@ -106,15 +106,6 @@ namespace MP.Prog.Pages #region Protected Methods - protected async Task ReloadAsync() - { - isLoading = true; - currRecord = null; - ListRecords = null; - await ReloadData(); - isLoading = false; - } - /// /// Restituisce size calcolata /// @@ -137,6 +128,41 @@ namespace MP.Prog.Pages currRecord = await FDService.FileGetByKey(selRecord.FileId); } + /// + /// forza approvazione utente corrente + /// + /// + protected async Task FileSetUserApp(FileModel CurrRec) + { + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler approvare il salvataggio automatico della nuova revisione?")) + return; + + await FDService.FileSetUserApp(CurrRec, MServ.UserName); + isLoading = true; + await ReloadData(); + isLoading = false; + } + + /// + /// Elimina record (non approvato) corrente e riattiva precedente + /// + /// + protected async Task DeleteRec(FileModel CurrRec) + { + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record e riattivare la revisione antecedente? Il file potrebbe risultare modificato")) + return; + + // elimino + await FDService.FileDelete(CurrRec); + //// verifico eventuali modifiche + //var numCheck = await FDService.UpdateMachineArchive(CurrRec.IdxMacchina, 30, false, false, ""); + + isLoading = true; + await ReloadData(); + isLoading = false; + } + + protected async Task FilterPath(string searchVal) { SelFileName = searchVal; @@ -146,6 +172,14 @@ namespace MP.Prog.Pages isLoading = false; } + protected async Task FilterTag(string searchVal) + { + SelTag = searchVal; + currPage = 1; + await ReloadData(); + isLoading = false; + } + protected async Task FilterUserName(string userName) { SelUserName = userName; @@ -155,27 +189,48 @@ namespace MP.Prog.Pages isLoading = false; } - protected async Task FilterTag(string searchVal) - { - SelTag = searchVal; - currPage = 1; - await ReloadData(); - isLoading = false; - } - + /// + /// Esegue comparazione tra dati DB e filesystem (modificati entro numDays) + /// + /// + /// protected async Task ForceCheck(int numDays) { currRecord = null; ListRecords = null; // importante altrimenti NON mostra update UI await Task.Delay(1); - //MServ.File_Filter = SelectData.Init(5, 10); - var numCheck = await FDService.UpdateAllArchive(numDays, false, MServ.UserName); + var numCheck = await FDService.UpdateAllArchive(numDays, false, MServ.UserName, false); await ReloadAllData(); await Task.Delay(1); await RefreshDisplayLoading(); } + /// + /// effettua approvazione di ttute le modifiche visualizzate + /// + /// + protected async Task MassAppr() + { + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler procedere approvando una nuova revisione di ogni file modificato visualizzato?")) + return; + + //verifico che sia cliccato solo modificati... + if(OnlyMod) + { + foreach (var item in ListRecords) + { + await FDService.FileModApprove(item, MServ.UserName); + } + } + // rileggo! + ResetData(); + await ResetFilter(); + await Task.Delay(1); + await ReloadData(); + isLoading = false; + } + protected override async Task OnInitializedAsync() { SearchTag = defTag; @@ -188,20 +243,6 @@ namespace MP.Prog.Pages isLoading = false; } - protected async Task PagerReloadNum(int newNum) - { - numRecord = newNum; - await ReloadData(); - isLoading = false; - } - - protected async Task PagerReloadPage(int newNum) - { - currPage = newNum; - await ReloadData(); - isLoading = false; - } - protected async Task RefreshDisplayLoading() { await Task.Delay(1); @@ -218,6 +259,15 @@ namespace MP.Prog.Pages await ReloadData(); } + protected async Task ReloadAsync() + { + isLoading = true; + currRecord = null; + ListRecords = null; + await ReloadData(); + isLoading = false; + } + protected async Task ReloadData() { isLoading = true; @@ -230,19 +280,6 @@ namespace MP.Prog.Pages await Task.Delay(1); } - /// - /// effettua approvazione di ttute le modifiche visualizzate - /// - /// - protected async Task MassAppr() - { - ResetData(); - await ResetFilter(); - await Task.Delay(1); - await ReloadData(); - isLoading = false; - } - protected void ResetData() { FDService.rollBackEdit(currRecord); @@ -278,6 +315,30 @@ namespace MP.Prog.Pages currRecord = selRecord; } + /// + /// Imposta pagina corrente + /// + /// + /// + protected async Task SetNumPage(int newNum) + { + currPage = newNum; + await ReloadData(); + isLoading = false; + } + + /// + /// Imposta num record x pagina + /// + /// + /// + protected async Task SetRecPage(int newNum) + { + numRecord = newNum; + await ReloadData(); + isLoading = false; + } + protected string TextReduce(string textOriginal, int maxChar) { string answ = textOriginal; @@ -462,30 +523,6 @@ namespace MP.Prog.Pages } } } - private string SelUserName - { - get - { - string answ = ""; - if (MServ.File_Filter != null) - { - answ = MServ.File_Filter.UserName; - } - return answ; - } - set - { - if (!MServ.File_Filter.UserName.Equals(value)) - { - MServ.File_Filter.UserName = value; - var pUpd = Task.Run(async () => - { - await ReloadAsync(); - }); - pUpd.Wait(); - } - } - } private string SelIdxMacc { @@ -537,6 +574,31 @@ namespace MP.Prog.Pages } } + private string SelUserName + { + get + { + string answ = ""; + if (MServ.File_Filter != null) + { + answ = MServ.File_Filter.UserName; + } + return answ; + } + set + { + if (!MServ.File_Filter.UserName.Equals(value)) + { + MServ.File_Filter.UserName = value; + var pUpd = Task.Run(async () => + { + await ReloadAsync(); + }); + pUpd.Wait(); + } + } + } + #endregion Private Properties #region Private Methods diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index c017c782..8fc47a9f 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

    Versione: 6.16.2410.2311

    +

    Versione: 6.16.2410.2317


    Note di rilascio:
      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index d39e7196..87e7119a 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2311 +6.16.2410.2317 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index d2730839..7422f1c2 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2311 + 6.16.2410.2317 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false From b3b81de6a8a7ae92014f670f1dafd4d4f9d9237a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 23 Oct 2024 18:14:55 +0200 Subject: [PATCH 6/9] PROG - correzione disabilitazione filtro path file e username --- MP.Prog/Components/SearchMod.razor | 5 +-- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Pages/Archive.razor | 6 +-- MP.Prog/Pages/Archive.razor.cs | 69 ++++++++++++++++++++++-------- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/MP.Prog/Components/SearchMod.razor b/MP.Prog/Components/SearchMod.razor index 1e5d7677..b1d4e49e 100644 --- a/MP.Prog/Components/SearchMod.razor +++ b/MP.Prog/Components/SearchMod.razor @@ -6,10 +6,7 @@
      - -
      - -
      +
      @code { diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 8a1a91a0..5bf46fe1 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net6.0 MP.Prog - 6.16.2410.2317 + 6.16.2410.2318 True diff --git a/MP.Prog/Pages/Archive.razor b/MP.Prog/Pages/Archive.razor index 51bf960a..9908e1b8 100644 --- a/MP.Prog/Pages/Archive.razor +++ b/MP.Prog/Pages/Archive.razor @@ -6,7 +6,7 @@

      Elenco Programmi

      - @if (OnlyMod && totalCount >= 0) @@ -60,11 +60,11 @@
      @if (!string.IsNullOrEmpty(SelFileName)) { - @TextReduce(SelFileName, 20) + } @if (!string.IsNullOrEmpty(SelUserName)) { - @TextReduce(SelUserName, 20) + }
      diff --git a/MP.Prog/Pages/Archive.razor.cs b/MP.Prog/Pages/Archive.razor.cs index 7d5039fd..934a7bf3 100644 --- a/MP.Prog/Pages/Archive.razor.cs +++ b/MP.Prog/Pages/Archive.razor.cs @@ -116,6 +116,25 @@ namespace MP.Prog.Pages return MeasureUtils.SizeSuffix(origSize, 1); } + /// + /// Elimina record (non approvato) corrente e riattiva precedente + /// + /// + protected async Task DeleteRec(FileModel CurrRec) + { + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record e riattivare la revisione antecedente? Il file potrebbe risultare modificato")) + return; + + // elimino + await FDService.FileDelete(CurrRec); + //// verifico eventuali modifiche + //var numCheck = await FDService.UpdateMachineArchive(CurrRec.IdxMacchina, 30, false, false, ""); + + isLoading = true; + await ReloadData(); + isLoading = false; + } + protected async Task Edit(FileModel selRecord) { if (!selRecord.Active) @@ -144,25 +163,10 @@ namespace MP.Prog.Pages } /// - /// Elimina record (non approvato) corrente e riattiva precedente + /// Esegue filtraggio sul Path di ricerca /// + /// /// - protected async Task DeleteRec(FileModel CurrRec) - { - if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record e riattivare la revisione antecedente? Il file potrebbe risultare modificato")) - return; - - // elimino - await FDService.FileDelete(CurrRec); - //// verifico eventuali modifiche - //var numCheck = await FDService.UpdateMachineArchive(CurrRec.IdxMacchina, 30, false, false, ""); - - isLoading = true; - await ReloadData(); - isLoading = false; - } - - protected async Task FilterPath(string searchVal) { SelFileName = searchVal; @@ -172,6 +176,21 @@ namespace MP.Prog.Pages isLoading = false; } + /// + /// Elimina il filtro x path file + /// + /// + protected async Task FilterPathRemove() + { + await FilterPath(""); + OnlyActive = true; + } + + /// + /// Imposta filtro x Tags + /// + /// + /// protected async Task FilterTag(string searchVal) { SelTag = searchVal; @@ -180,6 +199,11 @@ namespace MP.Prog.Pages isLoading = false; } + /// + /// Imposta filtro x utente + /// + /// + /// protected async Task FilterUserName(string userName) { SelUserName = userName; @@ -189,6 +213,15 @@ namespace MP.Prog.Pages isLoading = false; } + /// + /// Resetta filtro x utente + /// + /// + protected async Task FilterUserNameRemove() + { + await FilterUserName(""); + } + /// /// Esegue comparazione tra dati DB e filesystem (modificati entro numDays) /// @@ -216,7 +249,7 @@ namespace MP.Prog.Pages return; //verifico che sia cliccato solo modificati... - if(OnlyMod) + if (OnlyMod) { foreach (var item in ListRecords) { diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 8fc47a9f..16ff1099 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

      Versione: 6.16.2410.2317

      +

      Versione: 6.16.2410.2318


      Note di rilascio:
        diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 87e7119a..608cd781 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2317 +6.16.2410.2318 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 7422f1c2..d54cba42 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2317 + 6.16.2410.2318 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false From e4fd85c9cb32fde092f57682bde9010e217cabc4 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 23 Oct 2024 19:21:11 +0200 Subject: [PATCH 7/9] LAND - import scheduler da STATS - ok compilazione (da completare con esecuzione REST call) --- MP-LAND.sln | 8 + MP.Data/Controllers/MpLandController.cs | 421 ++++++++++++++++++++++++ MP.Data/MoonProContext.cs | 9 + MP.Data/Services/TaskService.cs | 324 ++++++++++++++++++ MP.Land/Components/TLResult.razor | 7 + MP.Land/Components/TLResult.razor.cs | 56 ++++ MP.Land/Components/TaskEdit.razor | 101 ++++++ MP.Land/Components/TaskEdit.razor.cs | 47 +++ MP.Land/Components/TaskExeList.razor | 85 +++++ MP.Land/Components/TaskExeList.razor.cs | 113 +++++++ MP.Land/MP.Land.csproj | 3 +- MP.Land/Pages/TaskScheduler.razor | 166 ++++++++++ MP.Land/Pages/TaskScheduler.razor.cs | 355 ++++++++++++++++++++ MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.Land/Shared/NavMenu.razor | 8 + MP.Land/Startup.cs | 4 +- MP.Land/appsettings.json | 2 + MP.Stats/Components/TLResult.razor | 2 +- MP.Stats/Components/TaskExeList.razor | 25 +- MP.Stats/MP.Stats.csproj | 4 +- MP.Stats/Pages/TaskScheduler.razor | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 26 files changed, 1732 insertions(+), 22 deletions(-) create mode 100644 MP.Data/Controllers/MpLandController.cs create mode 100644 MP.Data/Services/TaskService.cs create mode 100644 MP.Land/Components/TLResult.razor create mode 100644 MP.Land/Components/TLResult.razor.cs create mode 100644 MP.Land/Components/TaskEdit.razor create mode 100644 MP.Land/Components/TaskEdit.razor.cs create mode 100644 MP.Land/Components/TaskExeList.razor create mode 100644 MP.Land/Components/TaskExeList.razor.cs create mode 100644 MP.Land/Pages/TaskScheduler.razor create mode 100644 MP.Land/Pages/TaskScheduler.razor.cs diff --git a/MP-LAND.sln b/MP-LAND.sln index 7c54065e..85bcdda1 100644 --- a/MP-LAND.sln +++ b/MP-LAND.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.AppAuth", "MP.AppAuth\MP EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Egw.Core", "Egw.Core\Egw.Core.csproj", "{D3D348EF-1313-43DF-94FB-28CD38B68212}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.csproj", "{EE871AE5-9B5E-493E-8E59-F77234979AD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_LiManDebug|Any CPU = Debug_LiManDebug|Any CPU @@ -34,6 +36,12 @@ Global {D3D348EF-1313-43DF-94FB-28CD38B68212}.Debug|Any CPU.Build.0 = Debug|Any CPU {D3D348EF-1313-43DF-94FB-28CD38B68212}.Release|Any CPU.ActiveCfg = Release|Any CPU {D3D348EF-1313-43DF-94FB-28CD38B68212}.Release|Any CPU.Build.0 = Release|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug_LiManDebug|Any CPU.ActiveCfg = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug_LiManDebug|Any CPU.Build.0 = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MP.Data/Controllers/MpLandController.cs b/MP.Data/Controllers/MpLandController.cs new file mode 100644 index 00000000..10112783 --- /dev/null +++ b/MP.Data/Controllers/MpLandController.cs @@ -0,0 +1,421 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Data.DatabaseModels; +using MP.Data.Objects; +using NLog; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using static MP.Data.Objects.Enums; + +namespace MP.Data.Controllers +{ + public class MpLandController : IDisposable + { + #region Public Constructors + + public MpLandController(IConfiguration configuration) + { + _configuration = configuration; + Log.Info("Avviato MpLandController"); + } + + #endregion Public Constructors + + #region Public Methods + + public DateTime CalcNextExe(TaskListModel taskRec) + { + DateTime dtNext = DateTime.Today; + try + { + // calcolo next exec da tipo... + switch (taskRec.Freq) + { + case TaskFreqType.ND: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + + case TaskFreqType.Sec: + dtNext = taskRec.DtLastExec.AddSeconds(taskRec.Cad); + break; + + case TaskFreqType.Min: + dtNext = taskRec.DtLastExec.AddMinutes(taskRec.Cad); + break; + + case TaskFreqType.Hour: + dtNext = taskRec.DtLastExec.AddHours(taskRec.Cad); + break; + + case TaskFreqType.Day: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + + case TaskFreqType.Week: + dtNext = taskRec.DtLastExec.AddDays(7 * taskRec.Cad); + break; + + case TaskFreqType.Month: + dtNext = taskRec.DtLastExec.AddMonths(taskRec.Cad); + break; + + case TaskFreqType.Year: + dtNext = taskRec.DtLastExec.AddYears(taskRec.Cad); + break; + + default: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in CalcNextExe{Environment.NewLine}{exc}"); + } + return dtNext; + } + + /// + /// Elenco da tabella Config + /// + /// + public List ConfigGetAll() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToList(); + } + return dbResult; + } + + public void Dispose() + { + _configuration = null; + } + + /// + /// Elenco operatori + /// + /// + public List ElencoOperatori() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbOperatori + .Where(s => s.MatrOpr > 0) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToList(); + } + return dbResult; + } + + /// + /// Chiamata esecuzione di un singolo task programmato + /// + /// + /// Se true rischedula successiva chiamata + /// + public TaskResultModel ExecuteTask(int TaskId, bool SchedNext) + { + TaskResultModel callRes = new TaskResultModel(); + using (var dbCtx = new MoonPro_STATSContext(_configuration)) + { + // imposto timeout a 5 min + //var currTimeout = dbCtx.Database.GetCommandTimeout(); + dbCtx.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); + try + { + DateTime dtStart = DateTime.Now; + // recupero i dati da richiamare... + var currRec = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == TaskId) + .FirstOrDefault(); + if (currRec != null) + { + // recupero comando + string sqlCommand = currRec.Command; + string rawParams = currRec.Args; + callRes = dbCtx + .DbSetTaskResult + .FromSqlRaw($"EXEC {sqlCommand} {rawParams}") + .AsNoTracking() + .AsEnumerable() + .FirstOrDefault(); + DateTime dtEnd = DateTime.Now; + + // preparo record esecuzione... + TaskExecModel resRec = new TaskExecModel() + { + TaskId = TaskId, + DtStart = dtStart, + DtEnd = dtEnd, + IsError = callRes.ExecResult < 0, + Result = callRes.TextResult + }; + dbCtx + .DbSetTaskExe + .Add(resRec); + + // aggiorno record chiamata... + currRec.DtLastExec = dtStart; + currRec.LastResult = resRec.Result; + currRec.LastIsError = resRec.IsError; + currRec.LastDuration = dtEnd.Subtract(dtStart).TotalSeconds; + // solo se richiesto rischedulazione ricalcola chiamata + if (SchedNext) + { + // calcolo prossima esecuzione... + currRec.DtNextExec = CalcNextExe(currRec); + } + // segno modificato + dbCtx.Entry(currRec).State = EntityState.Modified; + + // salvo modifiche! + dbCtx.SaveChanges(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in ExecuteSqlCommand{Environment.NewLine}{exc}"); + } + } + return callRes; + } + + /// + /// Annulla modifiche su una specifica entity (cancel update) + /// + /// + /// + public bool RollBackEntity(object item) + { + bool answ = false; + using (var dbCtx = new MoonPro_STATSContext(_configuration)) + { + try + { + if (dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Deleted || dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Modified) + { + dbCtx.Entry(item).Reload(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Ricerca task dato tipo + num max (desc) + /// + /// TaskId da cui deriva + /// + public List TaskExecGetFilt(int TaskId, int maxRec) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetTaskExe + .Include(x => x.TaskListNav) + .Where(x => (x.TaskId == TaskId)) + .OrderByDescending(x => x.DtStart) + .Take(maxRec) + .ToList(); + } + return dbResult; + } + + /// + /// Upsert record TaskExec + /// + /// Record da aggiornare/inserire + /// + public bool TaskExecUpsert(TaskExecModel rec2upd) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskExe + .Where(x => x.TaskExecId == rec2upd.TaskExecId) + .FirstOrDefault(); + if (currData != null) + { + currData.TaskId = rec2upd.TaskId; + currData.DtStart = rec2upd.DtStart; + currData.DtEnd = rec2upd.DtEnd; + currData.IsError = rec2upd.IsError; + currData.Result = rec2upd.Result; + dbCtx.Entry(currData).State = EntityState.Modified; + } + else + { + dbCtx + .DbSetTaskExe + .Add(rec2upd); + } + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskExecUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + /// + /// Ricerca task dato tipo e + /// + /// + /// + public List TaskListGetAll(Task2ExeType TType) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetTaskList + .Where(x => (TType == Task2ExeType.ND || x.TType == TType)) + .OrderBy(x => x.Ordinal) + .ToList(); + } + return dbResult; + } + + /// + /// Update ordinamento task + /// + /// Record da spostare x priorità + /// + public bool TaskListMove(TaskListModel rec2upd, bool moveUp) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == rec2upd.TaskId) + .FirstOrDefault(); + if (currData != null) + { + int actOrdinal = currData.Ordinal; + TaskListModel? otherRec = null; + // cerco, secondo richiesta, precedente o successivo + if (moveUp) + { + otherRec = dbCtx + .DbSetTaskList + .Where(x => x.Ordinal < currData.Ordinal) + .OrderByDescending(x => x.Ordinal) + .FirstOrDefault(); + } + else + { + otherRec = dbCtx + .DbSetTaskList + .Where(x => x.Ordinal > currData.Ordinal) + .OrderBy(x => x.Ordinal) + .FirstOrDefault(); + } + // inverto ordinale SE ho record + if (otherRec != null) + { + currData.Ordinal = otherRec.Ordinal; + otherRec.Ordinal = actOrdinal; + dbCtx.Entry(currData).State = EntityState.Modified; + dbCtx.Entry(otherRec).State = EntityState.Modified; + } + } + //salvo + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskListUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + /// + /// Upsert record TaskList + /// + /// Record da aggiornare/inserire + /// + public bool TaskListUpsert(TaskListModel rec2upd) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == rec2upd.TaskId) + .FirstOrDefault(); + if (currData != null) + { + currData.Ordinal = rec2upd.Ordinal; + currData.Name = rec2upd.Name; + currData.Descript = rec2upd.Descript; + currData.Command = rec2upd.Command; + currData.Args = rec2upd.Args; + currData.Freq = rec2upd.Freq; + currData.Cad = rec2upd.Cad; + currData.DtLastExec = rec2upd.DtLastExec; + currData.DtNextExec = rec2upd.DtNextExec; + currData.LastDuration = rec2upd.LastDuration; + currData.LastResult = rec2upd.LastResult; + dbCtx.Entry(currData).State = EntityState.Modified; + } + else + { + dbCtx + .DbSetTaskList + .Add(rec2upd); + } + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskListUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + #endregion Public Methods + + #region Private Fields + + private static IConfiguration _configuration; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs index e8a2bb3c..99e1199b 100644 --- a/MP.Data/MoonProContext.cs +++ b/MP.Data/MoonProContext.cs @@ -99,6 +99,11 @@ namespace MP.Data public virtual DbSet DbSetParetoFluxLog { get; set; } + public virtual DbSet DbSetTaskList { get; set; } + public virtual DbSet DbSetTaskExe { get; set; } + public virtual DbSet DbSetTaskResult { get; set; } + + #endregion Public Properties #region Private Methods @@ -122,6 +127,10 @@ namespace MP.Data { connString = _configuration.GetConnectionString("MP.STATS"); } + if (string.IsNullOrEmpty(connString)) + { + connString = _configuration.GetConnectionString("MP.Land"); + } optionsBuilder.UseSqlServer(connString); //optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;"); diff --git a/MP.Data/Services/TaskService.cs b/MP.Data/Services/TaskService.cs new file mode 100644 index 00000000..f11cf152 --- /dev/null +++ b/MP.Data/Services/TaskService.cs @@ -0,0 +1,324 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using MP.Data.Controllers; +using MP.Data.DatabaseModels; +using Newtonsoft.Json; +using NLog; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static MP.Data.Objects.Enums; + +namespace MP.Data.Services +{ + public class TaskService : BaseServ, IDisposable + { + #region Public Constructors + + /// + /// Init servizio TAB + /// + /// + public TaskService(IConfiguration configuration) + { + _configuration = configuration; + + // setup compoenti REDIS + redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); + redisDb = redisConn.GetDatabase(); + + // conf DB + ConnStr = _configuration.GetConnectionString("MP.All"); + if (string.IsNullOrEmpty(ConnStr)) + { + Log.Error("ConnString empty!"); + } + else + { + StringBuilder sb = new StringBuilder(); + MLController = new MpLandController(configuration); + sb.AppendLine($"TaskService | MpLandController OK"); + Log.Info(sb.ToString()); + // sistemo i parametri x redHas... + CodModulo = _configuration.GetValue("ServerConf:CodModulo"); + var cstringArray = ConnStr.Split(";"); + foreach (var item in cstringArray) + { + var cData = item.Trim().Split("="); + if (cData.Length == 2) + { + if (!connStrParams.ContainsKey(cData[0])) + { + connStrParams.Add(cData[0], cData[1]); + } + } + } + // sistemo + DataSource = connStrParams["Server"]; + DataBase = connStrParams["Database"]; + } + } + + #endregion Public Constructors + + #region Public Events + + /// + /// Evento richiesta rilettura dati pagina (x refresh pagine aperte) + /// + public event EventHandler ReloadRequest = delegate { }; + + #endregion Public Events + + #region Public Methods + + public void Dispose() + { + // Clear database controller + MLController.Dispose(); + // redis dispose + redisConn = null; + redisDb = null; + } + + /// + /// Chiamata esecuzione di un singolo task programmato + /// + /// + /// Se true rischedula successiva chiamata + /// + public async Task ExecuteTask(int TaskId, bool SchedNext) + { + TaskResultModel dbResult = MLController.ExecuteTask(TaskId, SchedNext); + // svuoto cache! + await FlushCache("Task"); + return dbResult; + } + + /// + /// Pulizia cache Redis (tutta) + /// + /// + public async Task FlushCache() + { + RedisValue pattern = new RedisValue($"{redisBaseKey}:*"); + bool answ = await ExecFlushRedisPattern(pattern); + return answ; + } + + /// + /// Pulizia cache Redis per chiave specifica (da redisBaseKey...) + /// + /// + public async Task FlushCache(string KeyReq) + { + RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*"); + bool answ = await ExecFlushRedisPattern(pattern); + return answ; + } + + /// + /// Invio notifica rilettura (con parametro) + /// + /// + public void NotifyReloadRequest(string message) + { + if (ReloadRequest != null) + { + // messaggio + ReloadEventArgs rea = new ReloadEventArgs(message); + ReloadRequest.Invoke(this, rea); + } + } + + public void rollBackEdit(object item) + { + MLController.RollBackEntity(item); + } + + /// + /// Ricerca task dato tipo + num max (desc) + /// + /// TaskId da cui deriva + /// + public async Task> TaskExecGetFilt(int TaskId, int maxRec, string searchVal) + { + // setup parametri costanti + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List result = new List(); + // cerco in redis... + DateTime adesso = DateTime.Now; + string currKey = $"{redisBaseKey}:Task:ExecList:{TaskId}:{adesso:yyMMdd}:{adesso:HHmm}:{maxRec}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = MLController.TaskExecGetFilt(TaskId, maxRec); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, FastCache); + } + if (result == null) + { + result = new List(); + } + sw.Stop(); + Log.Debug($"TaskExecGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + + /// + /// Elenco TaskList gestiti + /// + /// + /// + /// + public async Task> TaskListAll(Task2ExeType TType, string searchVal = "") + { + // setup parametri costanti + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List result = new List(); + // cerco in redis... + DateTime adesso = DateTime.Now; + string currKey = $"{redisBaseKey}:Task:List:{TType}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = MLController.TaskListGetAll(TType); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, FastCache); + } + if (result == null) + { + result = new List(); + } + // se necessario filtro.. + if (!string.IsNullOrEmpty(searchVal)) + { + result = result + .Where(x => x.Name.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) + || x.Descript.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase)) + .ToList(); + } + sw.Stop(); + Log.Debug($"TaskListAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + + /// + /// Update ordinamento task + /// + /// Record da spostare x priorità + /// + public async Task TaskListMove(TaskListModel rec2upd, bool moveUp) + { + bool dbResult = MLController.TaskListMove(rec2upd, moveUp); + // svuoto cache! + await FlushCache("Task"); + return await Task.FromResult(dbResult); + } + + /// + /// Update/Insert record TaskList + /// + /// + /// + public async Task TaskListUpsert(TaskListModel rec2upd) + { + bool dbResult = MLController.TaskListUpsert(rec2upd); + // svuoto cache! + await FlushCache("Task"); + return await Task.FromResult(dbResult); + } + + #endregion Public Methods + + #region Protected Fields + + /// + /// Oggetto per connessione a REDIS + /// + protected ConnectionMultiplexer redisConn = null!; + + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + protected IDatabase redisDb = null!; + + #endregion Protected Fields + + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + private string CodModulo = ""; + + private string ConnStr = ""; + + private Dictionary connStrParams = new Dictionary(); + + private string DataBase = ""; + + private string DataSource = ""; + + private string redisBaseKey = "MP:TASK"; + + #endregion Private Fields + + #region Private Properties + + private static MpLandController MLController { get; set; } = null!; + + #endregion Private Properties + + #region Private Methods + + /// + /// Esegue flush memoria redis dato pattern + /// + /// + /// + private async Task ExecFlushRedisPattern(RedisValue pattern) + { + bool answ = false; + var listEndpoints = redisConn.GetEndPoints(); + foreach (var endPoint in listEndpoints) + { + //var server = redisConnAdmin.GetServer(listEndpoints[0]); + var server = redisConn.GetServer(endPoint); + if (server != null) + { + var keyList = server.Keys(redisDb.Database, pattern); + foreach (var item in keyList) + { + await redisDb.KeyDeleteAsync(item); + } + answ = true; + } + } + // notifico update ai client in ascolto x reset cache + NotifyReloadRequest($"FlushRedisCache | {pattern}"); + return answ; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/Components/TLResult.razor b/MP.Land/Components/TLResult.razor new file mode 100644 index 00000000..fe4d9b04 --- /dev/null +++ b/MP.Land/Components/TLResult.razor @@ -0,0 +1,7 @@ +
        + @($"{CurrRecord.LastDuration:N3}") sec +
        +@if (showDetail) +{ +
        @CurrRecord.LastResult
        +} diff --git a/MP.Land/Components/TLResult.razor.cs b/MP.Land/Components/TLResult.razor.cs new file mode 100644 index 00000000..466a9950 --- /dev/null +++ b/MP.Land/Components/TLResult.razor.cs @@ -0,0 +1,56 @@ +using Microsoft.AspNetCore.Components; +using MP.Data.DatabaseModels; +using System.Threading.Tasks; + +namespace MP.Land.Components +{ + public partial class TLResult + { + #region Public Properties + + [Parameter] + public TaskListModel CurrRecord { get; set; } = null!; + + #endregion Public Properties + + #region Protected Properties + + protected string alCss + { + get => CurrRecord.LastIsError ? "alert-danger" : "alert-success"; + } + + protected string btnCss + { + get + { + string answ = showDetail ? "btn-" : "btn-outline-"; + answ += CurrRecord.LastIsError ? "danger" : "success"; + return answ; + } + } + + protected string iconCss + { + get => CurrRecord.LastIsError ? "fa-thumbs-down" : "fa-thumbs-up"; + } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task toggleDetail() + { + showDetail = !showDetail; + await InvokeAsync(StateHasChanged); + } + + #endregion Protected Methods + + #region Private Properties + + private bool showDetail { get; set; } = false; + + #endregion Private Properties + } +} \ No newline at end of file diff --git a/MP.Land/Components/TaskEdit.razor b/MP.Land/Components/TaskEdit.razor new file mode 100644 index 00000000..69d6674a --- /dev/null +++ b/MP.Land/Components/TaskEdit.razor @@ -0,0 +1,101 @@ +@if (CurrRecord != null) +{ +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        + @*
        +
        + + +
        +
        +
        +
        + + +
        +
        *@ +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        +
        +
        + + +
        +
        +
        + +
        +
        +} + diff --git a/MP.Land/Components/TaskEdit.razor.cs b/MP.Land/Components/TaskEdit.razor.cs new file mode 100644 index 00000000..da8867a9 --- /dev/null +++ b/MP.Land/Components/TaskEdit.razor.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Components; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using System.Threading.Tasks; + +namespace MP.Land.Components +{ + public partial class TaskEdit + { + #region Public Properties + + [Parameter] + public TaskListModel? CurrRecord { get; set; } = null; + + [Parameter] + public EventCallback EC_update { get; set; } + + #endregion Public Properties + + #region Protected Properties + + [Inject] + protected TaskService TService { get; set; } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task doCancel() + { + await EC_update.InvokeAsync(false); + } + + protected async Task doSave() + { + bool fatto = false; + await Task.Delay(1); + if (CurrRecord != null) + { + fatto = await TService.TaskListUpsert(CurrRecord); + } + await EC_update.InvokeAsync(fatto); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/MP.Land/Components/TaskExeList.razor b/MP.Land/Components/TaskExeList.razor new file mode 100644 index 00000000..b74c56a3 --- /dev/null +++ b/MP.Land/Components/TaskExeList.razor @@ -0,0 +1,85 @@ + +
        +
        +
        +
        + History +
        +
        +
        + +
        +
        +
        +
        +
        + @if (ListRecords == null) + { + + } + else if (totalCount == 0) + { +
        Nessun record trovato
        + } + else + { +
        +
        +
    + @if (currRecord != null) + { + + } + FileRev / State / SizeRevSize / User Macchina Tags Modificato
    @record.Name
    -
    -
    -
    - @record.Rev -
    -
    - - - @record.DiskStatus - +
    + @record.Rev +
    + + + @record.DiskStatus -
    -
    - @CalcSize(record.Size) -
    + - -
    -
    +
    +
    + @CalcSize(record.Size) +
    +
    @if (!string.IsNullOrEmpty(record.UserAppr)) { -} + + @record.UserAppr + + }
    @record.Macchina.Nome
    @record.Macchina.Descrizione
    + @foreach (var item in record.Tags) { + @if (OnlyMod && totalCount >= 0) + { + + }
    diff --git a/MP.Prog/Pages/Archive.razor.cs b/MP.Prog/Pages/Archive.razor.cs index 20e47c48..af50582a 100644 --- a/MP.Prog/Pages/Archive.razor.cs +++ b/MP.Prog/Pages/Archive.razor.cs @@ -230,6 +230,19 @@ namespace MP.Prog.Pages await Task.Delay(1); } + /// + /// effettua approvazione di ttute le modifiche visualizzate + /// + /// + protected async Task MassAppr() + { + ResetData(); + await ResetFilter(); + await Task.Delay(1); + await ReloadData(); + isLoading = false; + } + protected void ResetData() { FDService.rollBackEdit(currRecord); diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index a3ed871e..c017c782 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

    Versione: 6.16.2410.2219

    +

    Versione: 6.16.2410.2311


    Note di rilascio:
      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 3cfca690..d39e7196 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2219 +6.16.2410.2311 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index af79ea5d..d2730839 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2219 + 6.16.2410.2311 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/Startup.cs b/MP.Prog/Startup.cs index fc459f4f..3f68ea0d 100644 --- a/MP.Prog/Startup.cs +++ b/MP.Prog/Startup.cs @@ -8,13 +8,17 @@ using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; using MP.Prog.Data; using NLog; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; +using System.Reflection; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace MP.Prog @@ -41,10 +45,24 @@ namespace MP.Prog // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - // aggiunt base URL x routing corretto app.UsePathBase(Configuration.GetValue("ServerConf:BaseUrl")); + if (env.IsDevelopment() || env.IsStaging()) + { + app.UseDeveloperExceptionPage(); + + // valido solo in sviluppo + app.UseSwagger(c => + { + c.RouteTemplate = "/swagger/{documentName}/swagger.json"; + }); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("v1/swagger.json", "MP-PROG.Api"); + }); + } + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); @@ -91,7 +109,7 @@ namespace MP.Prog app.UseEndpoints(endpoints => { - //endpoints.MapControllers(); + endpoints.MapControllers(); endpoints.MapBlazorHub(); //endpoints.MapHealthChecksUI(); //endpoints.MapHealthChecks("/health", new HealthCheckOptions @@ -107,6 +125,14 @@ namespace MP.Prog // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { + services.AddControllers(); + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", new OpenApiInfo { Title = "MP-PROG.Api", Version = "v1" }); + // Set the comments path for the Swagger JSON and UI. + var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"); + c.IncludeXmlComments(xmlPath); + }); // Aggiunta auth windows services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); @@ -147,6 +173,8 @@ namespace MP.Prog // avvio oggetto shared x redis... var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + services.AddControllers() + .AddJsonOptions(c => c.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve); services.AddLocalization(); From 4ee2ef1eb937b6b91b5f03889805a0cc6533bf20 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 23 Oct 2024 17:56:58 +0200 Subject: [PATCH 5/9] PROG - ok cancella - ok metodi API x check + approva salvando senza user - ok procedure insomnia salvate --- Insomnia/MAPO-IOC.json | 1 + Insomnia/MAPO-PROG.json | 1 + Insomnia/MAPO-SPEC.json | 2 +- MP.FileData/Controllers/FileController.cs | 74 +++++-- MP.Prog/Components/ArchiveStatus.razor.cs | 2 +- MP.Prog/Components/FileEditor.razor.cs | 4 +- MP.Prog/Controllers/FileChangeController.cs | 111 +++++++---- MP.Prog/Controllers/HealthController.cs | 4 +- MP.Prog/Data/FileArchDataService.cs | 28 ++- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Pages/Archive.razor | 27 ++- MP.Prog/Pages/Archive.razor.cs | 202 +++++++++++++------- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- 15 files changed, 316 insertions(+), 148 deletions(-) create mode 100644 Insomnia/MAPO-IOC.json create mode 100644 Insomnia/MAPO-PROG.json diff --git a/Insomnia/MAPO-IOC.json b/Insomnia/MAPO-IOC.json new file mode 100644 index 00000000..0db921f7 --- /dev/null +++ b/Insomnia/MAPO-IOC.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:46:37.409Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_d6789dcf78d94816bbd8572ed8e50c32","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272654,"created":1680674272654,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_e3f940b0e7364ede9659ddc904ed76da","parentId":null,"modified":1680674272619,"created":1680674272619,"name":"MP-IOC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_0990f1f8b8054c6aa775c08233beb68a","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272646,"created":1680674272646,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_86ef875060b240979a923807d5726572","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272651,"created":1680674272651,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_80ed4f0bb8ac463b90112c98d457c478","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680679124960,"created":1680679120652,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=999.xml","name":"GET FILE - not exists","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679462147031.9062,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ca021599ba8443c1a79a2eb69aa92128","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272620,"created":1680674272620,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_8fed13ca3e9a477dad1b0a6699c43b70","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272634,"created":1680674272634,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_aaf61ce728e747a89c242f3c012bb23c","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272662,"created":1680674272637,"fileName":"MP-IOC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_b5e3d19ecc18458b96877ecc73b04729","parentId":"env_ca021599ba8443c1a79a2eb69aa92128","modified":1680679494694,"created":1680674272621,"name":"DEV","data":{"BASE_URL":"https://localhost:7050"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_89e83800dd9d435ebe6745b4f80b2082","parentId":"env_ca021599ba8443c1a79a2eb69aa92128","modified":1680674621408,"created":1680674272628,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/IOC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file diff --git a/Insomnia/MAPO-PROG.json b/Insomnia/MAPO-PROG.json new file mode 100644 index 00000000..9258b930 --- /dev/null +++ b/Insomnia/MAPO-PROG.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:45:49.150Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_bb23a3e0a78f44999350ddcefebaaf82","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691634502,"created":1729691518776,"url":"{{ _.BASE_URL }}/api/Health","name":"Health","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","parentId":null,"modified":1729691518738,"created":1729691518738,"name":"MAPO-PROG","description":"","scope":"collection","_type":"workspace"},{"_id":"req_2b3ff677e75040ed9dfe30463fb5d408","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729691689274,"created":1729691666872,"url":"{{ _.BASE_URL }}/api/FileChange","name":"FileChange Health","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1729691677997,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_cf0e8b6c31334d67bc421487d31a5540","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691675552,"created":1729691673364,"name":"FileChange","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1680616270148.125,"_type":"request_group"},{"_id":"req_8fa584b2405b4c3588e1da50c6c02cbc","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729691870054,"created":1729691818717,"url":"{{ _.BASE_URL }}/api/FileChange/approve/ALL?numDayPrev=7","name":"FileChange AutoSave","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1726323968489,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_b28dbcb90b9f4a30ae621f46ca80abf1","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729698051601,"created":1729698043734,"url":"{{ _.BASE_URL }}/api/FileChange/check/ALL?numDayPrev=0","name":"FileChange CheckAll","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1724640113735,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_f533a867e5e74bc7a712974eb5185fe2","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518740,"created":1729691518740,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_52975036fdb946749a04bf8b105649dc","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518752,"created":1729691518752,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_034d8153209c43289ef94bb511a381e4","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518782,"created":1729691518757,"fileName":"MAPO-PROG","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_6acd2ea246a54f2fa42dfa7191704e4f","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691571662,"created":1729691518742,"name":"DEV","data":{"BASE_URL":"https://localhost:5001"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_add3f929a9774e949eaacdfef9669698","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691576277,"created":1729691518746,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/PROG"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"},{"_id":"env_78f831742ec84968878b6bb3e2dbbee3","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691592437,"created":1729691579006,"name":"PROD","data":{"BASE_URL":"https://iis01.egalware.com/MP/PROG"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1692979703520,"_type":"environment"}]} \ No newline at end of file diff --git a/Insomnia/MAPO-SPEC.json b/Insomnia/MAPO-SPEC.json index b14c98f9..65a34e4a 100644 --- a/Insomnia/MAPO-SPEC.json +++ b/Insomnia/MAPO-SPEC.json @@ -1 +1 @@ -{"_type":"export","__export_format":4,"__export_date":"2023-04-04T15:23:33.215Z","__export_source":"insomnia.desktop.app:v2023.1.0","resources":[{"_id":"req_cd57cb8728854cd5a7d026b9aba60047","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680616613886,"created":1680616613017,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","parentId":null,"modified":1680615228636,"created":1680615228636,"name":"MAPO-SPEC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_4d233d6fb970485ea929bdffdcfae05a","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621773464,"created":1680615246346,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_278d5f0a6555457e88ad2e58cfdaae23","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621754168,"created":1680615436433,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615377532,"created":1680615228640,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228642,"created":1680615228642,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_b61936e963e34a759001c6a22ad8da60","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228637,"created":1680615228637,"fileName":"MAPO-SPEC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_2757d8ba1b17435987847d0499e9369e","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616993850,"created":1680615301619,"name":"DEV","data":{"BASE_URL":"https://localhost:7212"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_f5b6aef3c2b444aab04c9056404d63f9","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616996428,"created":1680615328099,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/SPEC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:46:09.187Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_cd57cb8728854cd5a7d026b9aba60047","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680616613886,"created":1680616613017,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","parentId":null,"modified":1680615228636,"created":1680615228636,"name":"MAPO-SPEC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_4d233d6fb970485ea929bdffdcfae05a","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621773464,"created":1680615246346,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_278d5f0a6555457e88ad2e58cfdaae23","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621754168,"created":1680615436433,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615377532,"created":1680615228640,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228642,"created":1680615228642,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_b61936e963e34a759001c6a22ad8da60","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228637,"created":1680615228637,"fileName":"MAPO-SPEC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_2757d8ba1b17435987847d0499e9369e","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616993850,"created":1680615301619,"name":"DEV","data":{"BASE_URL":"https://localhost:7212"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_f5b6aef3c2b444aab04c9056404d63f9","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616996428,"created":1680615328099,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/SPEC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file diff --git a/MP.FileData/Controllers/FileController.cs b/MP.FileData/Controllers/FileController.cs index a1e46967..40a17543 100644 --- a/MP.FileData/Controllers/FileController.cs +++ b/MP.FileData/Controllers/FileController.cs @@ -115,8 +115,9 @@ namespace MP.FileData.Controllers /// Forza il controllo dei Tags /// Regole di ricerca applicate /// Utente connesso x approvazione + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public int CheckFileArchived(string idxMacchina, string path, int numDayPre, string searchPattern, bool forceTag, SearchRules currRule, string UserName) + public int CheckFileArchived(string idxMacchina, string path, int numDayPre, string searchPattern, bool forceTag, SearchRules currRule, string UserName, bool DoApprove) { Log.Info($"CheckFileArchived S00 | macchina: {idxMacchina} | path: {path} | pattern: {searchPattern} | # ExcludedFileExt: {currRule.ExcludedFileExt.Count()}"); int checkDone = 0; @@ -213,7 +214,7 @@ namespace MP.FileData.Controllers if (fileNew != null && fileNew.Count > 0) { checkDone += fileNew.Count; - FileInsert(idxMacchina, path, fileNew, UserName, 0, currRule); + FileInsert(idxMacchina, path, fileNew, UserName, 0, currRule, DoApprove); Log.Trace($"CheckFileArchived S03 | insert {fileNew.Count} files"); } // aggiorno i file modificati @@ -282,24 +283,26 @@ namespace MP.FileData.Controllers .DbSetProgFile .Where(x => x.FileId == currItem.FileId) .FirstOrDefault(); - localDbCtx - .DbSetProgFile - .Remove(file2del); // se ce ne fosse un altro precedente --> lo (ri)attiva var file2open = localDbCtx - .DbSetProgFile - .Where(x => x.Name == currItem.Name && x.IdxMacchina == currItem.IdxMacchina) - .OrderByDescending(y => y.Rev) - .FirstOrDefault(); + .DbSetProgFile + .Where(x => !x.Active && x.IdxMacchina == currItem.IdxMacchina && x.Path == currItem.Path) + .OrderByDescending(y => y.Rev) + .FirstOrDefault(); if (file2open != null) { file2open.Active = true; } + // elimino record! + localDbCtx + .DbSetProgFile + .Remove(file2del); + // salvo! - localDbCtx.SaveChanges(); - done = true; + int numDone = localDbCtx.SaveChanges(); + done = numDone != 0; } return done; } @@ -383,9 +386,9 @@ namespace MP.FileData.Controllers } - public List FileGetByPath(string path, bool onlyActive) + public List FileGetByPath(string path, bool onlyActive) { - List dbResult = new List(); + List dbResult = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { dbResult = localDbCtx @@ -398,9 +401,9 @@ namespace MP.FileData.Controllers return dbResult; } - public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal, int NumStart, int NumRecords) + public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal, int NumStart, int NumRecords) { - List dbResult = new List(); + List dbResult = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { dbResult = localDbCtx @@ -432,8 +435,9 @@ namespace MP.FileData.Controllers /// Utente che ha approvato la modifica, "" = NON confermata/eliminabile /// rev da usare x creazione /// Configuraizone ricerca + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public bool FileInsert(string idxMacchina, string basePath, List newFiles, string UserName, int rev, SearchRules currRule) + public bool FileInsert(string idxMacchina, string basePath, List newFiles, string UserName, int rev, SearchRules currRule, bool DoApprove) { // fare: lettura conf x macchina Log.Info($"FileInsert S01 per macchina {idxMacchina}: {newFiles.Count} files da valutare"); @@ -448,7 +452,7 @@ namespace MP.FileData.Controllers List newRec = newFiles.Select(o => new FileModel() { Active = true, - DiskStatus = FileState.Ok, + DiskStatus = DoApprove ? FileState.Ok : FileState.Changed, IdxMacchina = idxMacchina, LastCheck = adesso, LastMod = o.LastWriteTime, @@ -536,6 +540,38 @@ namespace MP.FileData.Controllers return answ; } + /// + /// Imposta utente approvazione + data modifica File + /// + /// + /// + /// + public bool FileSetUserApp(FileModel currFile, string UserName) + { + bool done = false; + List listUpdate = new List(); + using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) + { + FileModel currRec = localDbCtx + .DbSetProgFile + .Where(x => x.FileId == currFile.FileId) + .FirstOrDefault(); + if (currRec != null) + { + DateTime adesso = DateTime.Now; + currRec.UserAppr = UserName; + currRec.LastMod = adesso; + currRec.LastCheck = adesso; + //currFile.DiskStatus = FileState.Ok; + localDbCtx.Entry(currRec).State = EntityState.Modified; + // salvo DB + localDbCtx.SaveChanges(); + } + } + return done; + } + + /// /// Approvazione modifica File /// @@ -545,8 +581,6 @@ namespace MP.FileData.Controllers public bool FileModApprove(FileModel currFile, string UserName) { bool done = false; - // recupero file regole json da macchina.. - List listUpdate = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { @@ -575,7 +609,7 @@ namespace MP.FileData.Controllers if (currRule.Name != "ND") { // inserisco come REVISIONE - FileInsert(currFile.IdxMacchina, currMacchina.BasePath, listUpdate, UserName, currFile.Rev + 1, currRule); + FileInsert(currFile.IdxMacchina, currMacchina.BasePath, listUpdate, UserName, currFile.Rev + 1, currRule, true); // archivio vecchio file currFile.Active = false; diff --git a/MP.Prog/Components/ArchiveStatus.razor.cs b/MP.Prog/Components/ArchiveStatus.razor.cs index 6630245e..d464a198 100644 --- a/MP.Prog/Components/ArchiveStatus.razor.cs +++ b/MP.Prog/Components/ArchiveStatus.razor.cs @@ -162,7 +162,7 @@ namespace MP.Prog.Components sw.Restart(); // recupero elenco macchine percLoading += 100 / numMacchine; - numChecks = await FDService.UpdateMachineArchive(idxMacchina, numDays, true, false, MServ.UserName); + numChecks = await FDService.UpdateMachineArchive(idxMacchina, numDays, true, false, MServ.UserName, false); await Task.Delay(1); setupMessages.Add($"{idxMacchina}: {numChecks} files"); await InvokeAsync(StateHasChanged); diff --git a/MP.Prog/Components/FileEditor.razor.cs b/MP.Prog/Components/FileEditor.razor.cs index 40dd4f56..de286318 100644 --- a/MP.Prog/Components/FileEditor.razor.cs +++ b/MP.Prog/Components/FileEditor.razor.cs @@ -181,7 +181,7 @@ namespace MP.Prog.Components if (_currItem != null) { - await FDService.FileApprove(_currItem, MServ.UserName); + await FDService.FileModApprove(_currItem, MServ.UserName); await DataUpdated.InvokeAsync(1); } else @@ -225,7 +225,7 @@ namespace MP.Prog.Components await DataReset.InvokeAsync(0); await FDService.FileExport(_currItem); await DataReset.InvokeAsync(0); - await FDService.UpdateMachineArchive(_currItem.IdxMacchina, 1, false, false, MServ.UserName); + await FDService.UpdateMachineArchive(_currItem.IdxMacchina, 1, false, false, MServ.UserName, true); await DataUpdated.InvokeAsync(1); } else diff --git a/MP.Prog/Controllers/FileChangeController.cs b/MP.Prog/Controllers/FileChangeController.cs index 9ece29c0..7e7494da 100644 --- a/MP.Prog/Controllers/FileChangeController.cs +++ b/MP.Prog/Controllers/FileChangeController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MP.FileData.Controllers; using MP.Prog.Data; @@ -10,6 +11,7 @@ using System.Threading.Tasks; namespace MP.Prog.Controllers { + [AllowAnonymous] [Route("api/[controller]")] [ApiController] public class FileChangeController : ControllerBase @@ -31,25 +33,13 @@ namespace MP.Prog.Controllers #region Public Methods /// - /// Verifica Health servizi FileChange - /// GET api/FileChange - /// - /// - [HttpGet] - public ActionResult Get() - { - return "OK"; - } - - /// - /// Esegue controllo + approvazione modifiche x directory - /// GET api/FileChange/anagkeyval/[id]?[CodApp] + /// Esegue controllo + approvazione modifiche x directory GET api/FileChange/approve/[id]?[numDayPrev] /// /// Directory / IdxMacchina | 0/ALL = tutte /// Verifica file modificati da numDayPrev gg /// Elenco dei file approvati [HttpGet("approve/{id}")] - public async Task> approve(string id, int numDayPrev) + public async Task> Approve(string id, int numDayPrev) { List result = new List(); // verifico se una o tutte le macchine @@ -69,13 +59,78 @@ namespace MP.Prog.Controllers foreach (var currDir in listDir) { // eseguo singolo controllo, utente = "" (è auto-approvazione) - await FADService.UpdateMachineArchive(currDir, numDayPrev, false, false, ""); + await FADService.UpdateMachineArchive(currDir, numDayPrev, false, false, "", true); List listAppr = await ForceApproveMod(currDir, numDayPrev); result.AddRange(listAppr); } return result; } + /// + /// Esegue controllo + approvazione modifiche x directory GET api/FileChange/Approve/[id]?[numDayPrev] + /// + /// Directory / IdxMacchina | 0/ALL = tutte + /// Verifica file modificati da numDayPrev gg + /// Elenco dei file approvati + [HttpGet("check/{id}")] + public async Task> Check(string id, int numDayPrev) + { + List result = new List(); + // verifico se una o tutte le macchine + List listDir = new List(); + if (id == "ALL" || id == "0") + { + var machList = await FADService.ArchMaccGetAll(); + listDir = machList + .Where(x => !string.IsNullOrEmpty(x.BasePath)) + .Select(x => x.IdxMacchina).ToList(); + } + else + { + listDir.Add(id); + } + // ciclo su tutte le macchine e faccio verifica modificati... + foreach (var currDir in listDir) + { + // eseguo singolo controllo, utente = "" , SENZA auto-approvazione + int numCheks = await FADService.UpdateMachineArchive(currDir, numDayPrev, false, false, "", false); + result.Add($"{currDir} | {numCheks} files"); + } + return result; + } + + /// + /// Verifica Health servizi FileChange GET api/FileChange + /// + /// + [HttpGet] + public ActionResult Get() + { + return "OK"; + } + + #endregion Public Methods + + #region Protected Properties + + /// + /// Dataservice x accesso DB + /// + protected FileArchDataService FADService { get; set; } + + #endregion Protected Properties + + #region Private Fields + + /// + /// Classe per logging + /// + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + + #region Private Methods + /// /// Effettua approvazione file modificati, restituendo elenco /// @@ -97,8 +152,8 @@ namespace MP.Prog.Controllers // ciclo ogni file modificato foreach (var cFile in listChanged) { - // approvo il file modificato con utente anonimo (auto-approve) - bool fatto = await FADService.FileApprove(cFile, ""); + // approvo il file modificato con utente anonimo (auto-Approve) + bool fatto = await FADService.FileModApprove(cFile, ""); if (fatto) { answ.Add(cFile.Path); @@ -107,24 +162,6 @@ namespace MP.Prog.Controllers return answ; } - #endregion Public Methods - - #region Protected Properties - - /// - /// Dataservice x accesso DB - /// - protected FileArchDataService FADService { get; set; } - - #endregion Protected Properties - - #region Private Fields - - /// - /// Classe per logging - /// - private static Logger Log = LogManager.GetCurrentClassLogger(); - - #endregion Private Fields + #endregion Private Methods } } \ No newline at end of file diff --git a/MP.Prog/Controllers/HealthController.cs b/MP.Prog/Controllers/HealthController.cs index eb7e4144..edb99b62 100644 --- a/MP.Prog/Controllers/HealthController.cs +++ b/MP.Prog/Controllers/HealthController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MP.FileData.Controllers; using MP.Prog.Data; @@ -7,6 +8,7 @@ using System.Threading.Tasks; namespace MP.Prog.Controllers { + [AllowAnonymous] [Route("api/[controller]")] [ApiController] public class HealthController : ControllerBase diff --git a/MP.Prog/Data/FileArchDataService.cs b/MP.Prog/Data/FileArchDataService.cs index 5fb05c99..ab68d383 100644 --- a/MP.Prog/Data/FileArchDataService.cs +++ b/MP.Prog/Data/FileArchDataService.cs @@ -271,17 +271,18 @@ namespace MP.Prog.Data /// Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite /// Indica se forzare il tag /// Utente attivo + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public async Task UpdateAllArchive(int numDayPre, bool forceTag, string UserName) + public async Task UpdateAllArchive(int numDayPre, bool forceTag, string UserName, bool DoApprove) { int checkDone = 0; var listaMacchine = await ArchMaccGetAll(); foreach (var item in listaMacchine.Where(x => !string.IsNullOrEmpty(x.BasePath)).ToList()) { - checkDone += await UpdateMachineArchive(item.IdxMacchina, numDayPre, forceTag, false, UserName); + checkDone += await UpdateMachineArchive(item.IdxMacchina, numDayPre, forceTag, false, UserName, DoApprove); } - return await Task.FromResult(checkDone); + return checkDone; } /// @@ -294,8 +295,9 @@ namespace MP.Prog.Data /// Forza la riverifica dei tags (x update da setup) /// Scrittura log verboso macchina /// Utente attivo + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public async Task UpdateMachineArchive(string idxMacchina, int numDayPre, bool forceTag, bool fullLog, string UserName) + public async Task UpdateMachineArchive(string idxMacchina, int numDayPre, bool forceTag, bool fullLog, string UserName, bool DoApprove) { int checkDone = 0; Stopwatch stopWatch = new Stopwatch(); @@ -355,7 +357,7 @@ namespace MP.Prog.Data Log.Trace($"Conf rule generato:{Environment.NewLine}{rawRule}"); } } - checkDone = dbController.CheckFileArchived(macchina.IdxMacchina, macchina.BasePath, numDayPre, "*.*", forceTag, currRule, UserName); + checkDone = dbController.CheckFileArchived(macchina.IdxMacchina, macchina.BasePath, numDayPre, "*.*", forceTag, currRule, UserName, DoApprove); } } } @@ -383,7 +385,7 @@ namespace MP.Prog.Data /// /// /// - internal async Task FileApprove(FileModel currItem, string UserName) + internal async Task FileModApprove(FileModel currItem, string UserName) { bool answ = dbController.FileModApprove(currItem, UserName); // svuoto cache! @@ -391,6 +393,20 @@ namespace MP.Prog.Data return answ; } + /// + /// Forza registrazione della sola approvazione utente + data + /// + /// + /// + /// + internal async Task FileSetUserApp(FileModel currItem, string UserName) + { + bool answ = dbController.FileSetUserApp(currItem, UserName); + // svuoto cache! + await ResetArchiveCache(); + return answ; + } + /// /// Eliminazione file (x rifiuto modifica) /// diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 18a4c859..8a1a91a0 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net6.0 MP.Prog - 6.16.2410.2311 + 6.16.2410.2317 True diff --git a/MP.Prog/Pages/Archive.razor b/MP.Prog/Pages/Archive.razor index 873233f3..51bf960a 100644 --- a/MP.Prog/Pages/Archive.razor +++ b/MP.Prog/Pages/Archive.razor @@ -81,7 +81,7 @@
    @@ -128,7 +128,6 @@
    Macchina Tags ModificatoControllo
    @record.Macchina.Nome
    @record.Macchina.Descrizione
    + @foreach (var item in record.Tags) {
    @record.LastMod.ToString("yyyy.MM.dd")
    @record.LastMod.ToString("ddd HH:mm.ss")
    + +
    + @if (string.IsNullOrEmpty(record.UserAppr)) + { + + }
    + + + + + + + + + + @foreach (var record in ListRecords) + { + + + + + + + } + +
    #InizioFineEsito
    + @record.TaskExecId + + @($"{record.DtStart:HH:mm:ss.fff}") +
    @($"{record.DtStart:yyyy-MM.dd ddd}")
    +
    + @($"{record.DtEnd:HH:mm:ss.fff}") +
    @($"{record.DtEnd:yyyy-MM.dd ddd}")
    +
    +
    +
    + @if (@record.IsError) + { + + } + else + { + + } +
    +
    + @($"{record.Duration:N3}") sec +
    +
    +
    @record.Result
    +
    +
+
+ } +
+ +
\ No newline at end of file diff --git a/MP.Land/Components/TaskExeList.razor.cs b/MP.Land/Components/TaskExeList.razor.cs new file mode 100644 index 00000000..9eb8c672 --- /dev/null +++ b/MP.Land/Components/TaskExeList.razor.cs @@ -0,0 +1,113 @@ +using Microsoft.AspNetCore.Components; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Land.Components +{ + public partial class TaskExeList + { + #region Public Properties + + [Parameter] + public TaskListModel? CurrRecord { get; set; } = null; + + #endregion Public Properties + + #region Protected Fields + + protected bool isLoading = false; + + #endregion Protected Fields + + #region Protected Properties + + [Inject] + protected NavigationManager NavManager { get; set; } + + /// + /// Show error mode: 0 = tutti 1 = solo errori 2 = solo ok + /// + protected int ShowErrorMode + { + get => showErrorMode; + set + { + if (showErrorMode != value) + { + showErrorMode = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + protected int totalCount { get; set; } = 0; + + [Inject] + protected TaskService TService { get; set; } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task ForceReload(int newNum) + { + numRecord = newNum; + await ReloadData(); + } + + protected async Task ForceReloadPage(int newNum) + { + currPage = newNum; + await ReloadData(); + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + #endregion Protected Methods + + #region Private Fields + + private List ListRecords; + private List SearchRecords; + + #endregion Private Fields + + #region Private Properties + + private int currPage { get; set; } = 1; + private int numRecord { get; set; } = 10; + private int showErrorMode { get; set; } = 0; + + #endregion Private Properties + + #region Private Methods + + private async Task ReloadData() + { + SearchRecords = await TService.TaskExecGetFilt(CurrRecord.TaskId, 1000, ""); + // se non tutti filtro... + if (ShowErrorMode != 0) + { + if (ShowErrorMode == 1) + { + SearchRecords = SearchRecords.FindAll(x => x.IsError); + } + else if (ShowErrorMode == 2) + { + SearchRecords = SearchRecords.FindAll(x => !x.IsError); + } + } + totalCount = SearchRecords.Count; + ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 3efa1241..3879efba 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net6.0 MP.Land - 6.16.2410.2215 + 6.16.2410.2319 Debug;Release;Debug_LiManDebug @@ -62,6 +62,7 @@ + diff --git a/MP.Land/Pages/TaskScheduler.razor b/MP.Land/Pages/TaskScheduler.razor new file mode 100644 index 00000000..14f307a3 --- /dev/null +++ b/MP.Land/Pages/TaskScheduler.razor @@ -0,0 +1,166 @@ +@page "/TaskScheduler" + +
+
+
+
+
+
+ TaskList +
+
+
+ @if (currRecord == null) + { + + } + else + { + + } + +
+
+
+ +
+
+ @if (isLoading) + { + + + } + else if (ListRecords == null) + { + + } + else if (totalCount == 0) + { +
Nessun record trovato
+ } + else + { +
+
+ + + + + + + + + + @if (detRecord == null) + { + + + + + } + + + + @foreach (var record in ListRecords) + { + + + + + + + + @if (detRecord == null) + { + + + + + } + + } + +
+ + OrdTaskTipoCommandSched.LastNextResult + +
+ + @if (detRecord == null) + { + @if (currRecord == null) + { + + + } + else + { + + } + } + + @if (detRecord == null) + { + @if (record.Ordinal == minOrdinal) + { + + } + else + { + + } + } + @record.Ordinal + @if (detRecord == null) + { + @if (record.Ordinal == maxOrdinal) + { + + } + else + { + + } + } + +
@record.Name
+
@record.Descript
+
+ @record.TType + +
@record.Command
+
@record.Args
+
@record.Freq × @record.Cad +
@($"{record.DtLastExec:yyyy-MM-dd}")
+
@($"{record.DtLastExec:ddd HH:mm:ss}")
+
+
@($"{record.DtNextExec:yyyy-MM-dd}")
+
@($"{record.DtNextExec:ddd HH:mm:ss}")
+
+ + + +
+
+
+ } +
+ +
+
+ @if (detRecord != null && !isLoading) + { +
+ +
+ } +
\ No newline at end of file diff --git a/MP.Land/Pages/TaskScheduler.razor.cs b/MP.Land/Pages/TaskScheduler.razor.cs new file mode 100644 index 00000000..b4e9f61c --- /dev/null +++ b/MP.Land/Pages/TaskScheduler.razor.cs @@ -0,0 +1,355 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using MP.Data.DatabaseModels; +using MP.Land.Data; +using static MP.Data.Objects.Enums; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System; +using System.Linq; +using MP.Data.Services; + +namespace MP.Land.Pages +{ + public partial class TaskScheduler : ComponentBase, IDisposable + { + #region Public Methods + + public string checkSelect(int TaskId) + { + string answ = ""; + if (currRecord != null) + { + try + { + answ = (currRecord.TaskId == TaskId) ? "table-info" : ""; + } + catch + { } + } + else if (detRecord != null) + { + answ = (detRecord.TaskId == TaskId) ? "table-info" : ""; + } + return answ; + } + + public void Dispose() + { + MessageService.EA_SearchUpdated -= OnSeachUpdated; + } + + public async void OnSeachUpdated() + { + await InvokeAsync(() => + { + Task task = ReloadData(); + StateHasChanged(); + }); + } + + #endregion Public Methods + + #region Protected Fields + + protected string fileName = "TaskList.csv"; + + #endregion Protected Fields + + #region Protected Properties + + [Inject] + protected IJSRuntime JSRuntime { get; set; } + + protected string mainCss + { + get => detRecord == null ? "col-12" : "col-6"; + } + + protected int maxOrdinal { get; set; } = 999; + + [Inject] + protected Data.MessageService MessageService { get; set; } + + protected int minOrdinal { get; set; } = 0; + + [Inject] + protected NavigationManager NavManager { get; set; } + + protected int totalCount { get; set; } = 0; + + [Inject] + protected TaskService TService { get; set; } + + protected Task2ExeType TypeSel + { + get => typeSel; + set + { + if (typeSel != value) + { + typeSel = value; + var pUpd = Task.Run(async () => + { + await ReloadData(); + }); + pUpd.Wait(); + } + } + } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task addNew() + { + currRecord = new TaskListModel() { Name = "Nuovo Task", Descript = "Descrizione", DtLastExec = DateTime.Today, DtNextExec = DateTime.Today.AddDays(1) }; + await ReloadData(); + } + + /// + /// Gestione display avanzamento step + /// + /// + protected async Task advStep(int currStep) + { + currVal = currStep; + nextVal = currVal + 1; + await InvokeAsync(StateHasChanged); + } + + protected async Task doCancel() + { + currRecord = null; + detRecord = null; + await ReloadData(); + } + + protected async Task doClone(TaskListModel selRec) + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi di voler duplicare il record selezionato?")) + return; + currRecord = new TaskListModel() + { + Args = selRec.Args, + Name = $"Copia di {selRec.Name}", + Cad = selRec.Cad, + Command = selRec.Command, + Descript = $"Copia di {selRec.Descript}", + DtNextExec = DateTime.Today.AddDays(1), + DtLastExec = DateTime.MinValue, + Freq = selRec.Freq, + LastDuration = 0, + LastIsError = false, + LastResult = "", + TType = selRec.TType, + Ordinal = SearchRecords.Count + 1, + }; + await ReloadData(); + } + + protected async Task doEdit(TaskListModel selRec) + { + currRecord = selRec; + await ReloadData(); + } + + protected async Task doMove(TaskListModel currRec, bool goUp) + { + await TService.TaskListMove(currRec, goUp); + detRecord = null; + currRecord = null; + await ReloadData(); + } + + protected async Task doReset() + { + detRecord = null; + currRecord = null; + await TService.FlushCache(); + await ReloadData(); + } + + protected async Task doRun(TaskListModel selRec) + { + // SE non è ancora scaduto chiedo conferma + if (selRec.DtNextExec > DateTime.Now) + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi esecuzione forzata task non scaduto?{Environment.NewLine}[{selRec.TaskId}]: {selRec.Name} - {selRec.Descript}{Environment.NewLine}Prossima schedulazione: {selRec.DtNextExec:yyyy-MM-dd HH:mm:ss}")) + return; + } + + // imposto tempo atteso esecuzione da ultimo... + isLoading = true; + MaxVal = 4; + int currStep = 0; + await advStep(currStep); + expTimeMsec = (int)(1000 * selRec.LastDuration) / 4; + detRecord = null; + await advStep(currStep++); + await Task.Delay(100); + await advStep(currStep++); + // chiama esecuzione task + var result = await TService.ExecuteTask(selRec.TaskId, false); + await advStep(currStep++); + isLoading = false; + await Task.Delay(100); + await advStep(currStep++); + await ReloadData(); + } + + protected async Task doSelect(TaskListModel selRec) + { + detRecord = null; + currRecord = null; + isLoading = true; + detRecord = selRec; + await ReloadData(); + isLoading = false; + } + + protected async Task forceAll() + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi esecuzione forzata di tutti i task?")) + return; + + isLoading = true; + detRecord = null; + await Task.Delay(100); + foreach (var taskRec in SearchRecords) + { + var result = await TService.ExecuteTask(taskRec.TaskId, false); + } + isLoading = false; + await Task.Delay(100); + await ReloadData(); + } + + protected async Task ForceReload(int newNum) + { + numRecord = newNum; + await ReloadData(); + } + + protected async Task ForceReloadPage(int newNum) + { + currPage = newNum; + await ReloadData(); + } + + protected async Task forceUpdate(bool doForce) + { + currRecord = null; + await ReloadData(); + } + + protected override async Task OnInitializedAsync() + { + clearFile(); + numRecord = 10; + MessageService.ShowSearch = false; + MessageService.PageName = "Task Scheduler"; + MessageService.PageIcon = "oi oi-clock"; + MessageService.EA_SearchUpdated += OnSeachUpdated; + await ReloadData(); + } + + protected void ResetData() + { + clearFile(); + TService.rollBackEdit(currRecord); + currRecord = null; + } + + protected async Task ResetFilter(SelectData newFilter) + { + clearFile(); + detRecord = null; + currRecord = null; + SearchRecords = null; + ListRecords = null; + await ReloadData(); + } + + protected double righDiv(double num, double den) + { + if (den == 0) + { + den = 1; + } + double answ = num / den; + return answ; + } + + #endregion Protected Methods + + #region Private Fields + + private double currVal = 0; + private List ListRecords; + private int MaxVal = 10; + private double nextVal = 0; + private List SearchRecords; + + #endregion Private Fields + + #region Private Properties + + private int currPage { get; set; } = 1; + + private TaskListModel currRecord { get; set; } = null; + + private TaskListModel detRecord { get; set; } = null; + + private int expTimeMsec { get; set; } = 30000; + + private string fullPath + { + get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}"; + } + + private bool isLoading { get; set; } = false; + private int numRecord { get; set; } = 10; + + private Task2ExeType typeSel { get; set; } = Task2ExeType.ND; + + #endregion Private Properties + + #region Private Methods + + private string btnRunCss(DateTime dtNextExe) + { + DateTime adesso = DateTime.Now; + string answ = dtNextExe < adesso ? "btn-success" : "btn-warning"; + return answ; + } + + private async void clearFile() + { + await Task.Run(() => File.Delete(fullPath)); + } + + private async Task ExportCsv() + { + isLoading = true; + // salvo davvero! + await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';'); + isLoading = false; + } + + private async Task ReloadData() + { + SearchRecords = await TService.TaskListAll(TypeSel, ""); + totalCount = SearchRecords.Count; + var firstRec = SearchRecords.OrderBy(x => x.Ordinal).FirstOrDefault(); + minOrdinal = firstRec != null ? firstRec.Ordinal : 0; + var lastRec = SearchRecords.OrderByDescending(x => x.Ordinal).FirstOrDefault(); + maxOrdinal = lastRec != null ? lastRec.Ordinal : 9999; + ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 1755be06..89c96808 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

Versione: 6.16.2410.2215

+

Versione: 6.16.2410.2319


Note di rilascio:
    diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 892d8f51..90be5917 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2215 +6.16.2410.2319 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index cd262318..98bea03f 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2215 + 6.16.2410.2319 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.Land/Shared/NavMenu.razor b/MP.Land/Shared/NavMenu.razor index 547e2abb..58b2fa2d 100644 --- a/MP.Land/Shared/NavMenu.razor +++ b/MP.Land/Shared/NavMenu.razor @@ -53,6 +53,14 @@ System Info
+ @if (IsSuperAdmin) + { + + }