Inizio modifiche TaskMan:
- migration x nuovo campo da gestire - inizio divisione controllo TaskList x avere gestione gruppi
This commit is contained in:
@@ -39,7 +39,6 @@
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
@* <i>selezione ITEM da mostrare, tra quelli POSSIBILI dato periodo...</i> *@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>MP.Stats</RootNamespace>
|
||||
<UserSecretsId>826e877c-ba70-4253-84cb-d0b1cafd4440</UserSecretsId>
|
||||
<Version>6.16.2507.0217</Version>
|
||||
<Version>6.16.2507.0217</Version>
|
||||
<Version>6.16.2507.0312</Version>
|
||||
<Version>6.16.2507.0312</Version>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo statistiche MAPO</i>
|
||||
<h4>Versione: 6.16.2507.0217</h4>
|
||||
<h4>Versione: 6.16.2507.0312</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2507.0217
|
||||
6.16.2507.0312
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2507.0217</version>
|
||||
<version>6.16.2507.0312</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using MP.TaskMan;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MP.TaskMan.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaskContext))]
|
||||
[Migration("20250703101600_AddTaskGroup")]
|
||||
partial class AddTaskGroup
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.UseCollation("SQL_Latin1_General_CP1_CI_AS")
|
||||
.HasAnnotation("ProductVersion", "6.0.36")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskExecModel", b =>
|
||||
{
|
||||
b.Property<int>("TaskExecId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("TaskExecId"), 1L, 1);
|
||||
|
||||
b.Property<DateTime>("DtEnd")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("DtStart")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("IsError")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Result")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("TaskId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("TaskExecId");
|
||||
|
||||
b.HasIndex("TaskId");
|
||||
|
||||
b.ToTable("TaskExec");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskListModel", b =>
|
||||
{
|
||||
b.Property<int>("TaskId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("TaskId"), 1L, 1);
|
||||
|
||||
b.Property<string>("Args")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Cad")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Command")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Descript")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("DtLastExec")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("DtNextExec")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("Freq")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Group")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<double>("LastDuration")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.Property<bool>("LastIsError")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("LastResult")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Ordinal")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("TaskId");
|
||||
|
||||
b.ToTable("TaskList");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskResultModel", b =>
|
||||
{
|
||||
b.Property<string>("Task")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("ExecResult")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TextResult")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Task");
|
||||
|
||||
b.ToTable("DbSetTaskResult");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskExecModel", b =>
|
||||
{
|
||||
b.HasOne("MP.TaskMan.Models.TaskListModel", "TaskListNav")
|
||||
.WithMany()
|
||||
.HasForeignKey("TaskId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("TaskListNav");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MP.TaskMan.Migrations
|
||||
{
|
||||
public partial class AddTaskGroup : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Group",
|
||||
table: "TaskList",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 1);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DbSetTaskResult",
|
||||
columns: table => new
|
||||
{
|
||||
Task = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
||||
ExecResult = table.Column<int>(type: "int", nullable: false),
|
||||
TextResult = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DbSetTaskResult", x => x.Task);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "DbSetTaskResult");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Group",
|
||||
table: "TaskList");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace MP.TaskMan.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.UseCollation("SQL_Latin1_General_CP1_CI_AS")
|
||||
.HasAnnotation("ProductVersion", "6.0.33")
|
||||
.HasAnnotation("ProductVersion", "6.0.36")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
|
||||
@@ -85,6 +85,9 @@ namespace MP.TaskMan.Migrations
|
||||
b.Property<int>("Freq")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Group")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<double>("LastDuration")
|
||||
.HasColumnType("float");
|
||||
|
||||
@@ -108,6 +111,22 @@ namespace MP.TaskMan.Migrations
|
||||
b.ToTable("TaskList");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskResultModel", b =>
|
||||
{
|
||||
b.Property<string>("Task")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("ExecResult")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TextResult")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Task");
|
||||
|
||||
b.ToTable("DbSetTaskResult");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MP.TaskMan.Models.TaskExecModel", b =>
|
||||
{
|
||||
b.HasOne("MP.TaskMan.Models.TaskListModel", "TaskListNav")
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace MP.TaskMan.Models
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int TaskId { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gruppo task (per gestione precedenze e semaforo exec)
|
||||
/// </summary>
|
||||
public int Group { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Ordinale x esecuzione
|
||||
/// </summary>
|
||||
|
||||
+3
-132
@@ -42,149 +42,20 @@
|
||||
<ProgressDisplay DisplaySize="ProgressDisplay.ModalSize.Medium" ExpTimeMSec="@expTimeMsec" CurrVal="@currVal" NextVal="@nextVal" MaxVal="@MaxVal" Title="Task Processing" RefreshInterval="200"></ProgressDisplay>
|
||||
<LoadingData Title="Elaborazione..." DisplayMode="LoadingData.SpinMode.BounceLine" DisplaySize="LoadingData.CtrlSize.Large"></LoadingData>
|
||||
}
|
||||
else if (ListRecords == null)
|
||||
else if (SearchRecords == null)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-sm btn-info" @onclick="DoReset" title="Reset"><i class="fas fa-sync"></i></button>
|
||||
</th>
|
||||
<th>Ord</th>
|
||||
<th>Task</th>
|
||||
<th>Tipo</th>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<th>Command</th>
|
||||
}
|
||||
<th>Sched.</th>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<th class="text-end">Last</th>
|
||||
<th class="text-end">Next</th>
|
||||
<th class="text-end">Result</th>
|
||||
<th>
|
||||
<button class="btn btn-sm btn-danger me-1" @onclick="ForceAll" title="Force All"><i class="fas fa-play"></i></button>
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record)">
|
||||
<td class="text-nowrap">
|
||||
<button class="btn btn-sm btn-info" @onclick="()=>DoSelect(record)" title="Select"><i class="fas fa-search"></i></button>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (currRecord == null)
|
||||
{
|
||||
<button class="btn btn-sm btn-primary ms-1" @onclick="()=>DoEdit(record)" title="Edit"><i class="fas fa-pencil-alt"></i></button>
|
||||
<button class="btn btn-sm btn-success" @onclick="()=>DoClone(record)" title="Clona"><i class="fas fa-magic"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary ms-1" @onclick="()=>DoCancel()" title="Cancel"><i class="fas fa-undo"></i></button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="text-nowrap">
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (record.Ordinal == minOrdinal)
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-secondary mx-1" disabled title="Cannot Move"><i class="fas fa-caret-up"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-primary mx-1" @onclick="()=>DoMove(record, true)" title="Move Up"><i class="fas fa-caret-up"></i></button>
|
||||
}
|
||||
}
|
||||
<b>@record.Ordinal</b>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (record.Ordinal == maxOrdinal)
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-secondary mx-1" disabled title="Cannot Move"><i class="fas fa-caret-down"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-primary mx-1" @onclick="()=>DoMove(record, false)" title="Move Down"><i class="fas fa-caret-down"></i></button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="text-nowrap @checkDis(@record)">
|
||||
<div>@record.Name</div>
|
||||
<div class="small text-truncate">@record.Descript</div>
|
||||
</td>
|
||||
<td class="@checkDis(@record)">
|
||||
@record.TType
|
||||
</td>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<td class="small text-truncate text-break @checkDis(@record)">
|
||||
<div class="font-monospace fw-bold" title="@record.Command">@TextReduce(record.Command, 32)</div>
|
||||
<div class="small text-break" title="@record.Args">@TextReduce(record.Args, 40)</div>
|
||||
</td>
|
||||
}
|
||||
<td>@record.Freq × @record.Cad</td>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<td class="text-end text-nowrap @checkDis(@record)">
|
||||
<div>@($"{record.DtLastExec:yyyy-MM-dd}")</div>
|
||||
<div class="small">@($"{record.DtLastExec:ddd HH:mm:ss}")</div>
|
||||
</td>
|
||||
<td class="text-end text-nowrap @checkDis(@record)">
|
||||
<div>@($"{record.DtNextExec:yyyy-MM-dd}")</div>
|
||||
<div class="small">@($"{record.DtNextExec:ddd HH:mm:ss}")</div>
|
||||
</td>
|
||||
<td class="text-end @checkDis(@record)">
|
||||
<b>@($"{record.LastDuration:N3}")</b> <sub>sec</sub> <button class="btn btn-sm @btnCss(record)" @onclick="() => ToggleDetail(record)" title="Ultima esecuzione"><i class="far @iconCss(record)"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
@if(record.Enabled)
|
||||
{
|
||||
<button class="btn btn-sm @btnRunCss(record.DtNextExec) me-1" @onclick="()=>DoRun(record)" title="Run Now"><i class="fas fa-play"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary me-1" title="Disabled / Cannot run!" disabled><i class="fas fa-play"></i></button>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
@if (DetailTaskId != null && DetailTaskId.TaskId == record.TaskId)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="10 @checkDis(@record)">
|
||||
<div class="d-flex justify-content-end">
|
||||
<div class="p-1 small alert @alCss(record)">
|
||||
<div class="text-trim">@record.LastResult</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<TaskListTable AllRecords="SearchRecords" EC_DoReset="DoReset" EC_ForceAll="ForceAll" EC_Cancel="DoCancel" EC_Clone="DoClone" EC_Select="DoSelect" EC_Edit="DoEdit" EC_Run="DoRun"></TaskListTable>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer py-1">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" exportEnabled="false" exportRequested="ExportCsv" fileName="@fileName" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (detRecord != null && !isLoading)
|
||||
|
||||
@@ -10,27 +10,23 @@ namespace MP.TaskMan
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
#if false
|
||||
protected string checkSelect(TaskListModel selRec)
|
||||
{
|
||||
string answ = "";
|
||||
if (currRecord != null)
|
||||
{
|
||||
answ = (currRecord.Equals(selRec)) ? "table-info" : "";
|
||||
answ = (currRecord.Equals(selRec)) ? "table-info" : "";
|
||||
}
|
||||
else if (detRecord != null)
|
||||
{
|
||||
answ = detRecord.Equals(selRec) ? "table-info" : "";
|
||||
}
|
||||
#if false
|
||||
// verifico se sia disabilitato...
|
||||
if (!selRec.Enabled)
|
||||
{
|
||||
answ += " text-secondary text-opacity-50 textStriked";
|
||||
}
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
protected string checkDis(TaskListModel selRec)
|
||||
{
|
||||
string answ = "";
|
||||
@@ -40,13 +36,16 @@ namespace MP.TaskMan
|
||||
answ += " text-secondary text-opacity-75 textStriked";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected string fileName = "TaskList.csv";
|
||||
#if false
|
||||
protected string fileName = "TaskList.csv";
|
||||
#endif
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
@@ -112,17 +111,21 @@ namespace MP.TaskMan
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
#if false
|
||||
protected string alCss(TaskListModel TaskRec)
|
||||
{
|
||||
return TaskRec.LastIsError ? "alert-danger" : "alert-success";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
protected string btnCss(TaskListModel TaskRec)
|
||||
{
|
||||
string answ = DetailTaskId != null && DetailTaskId.TaskId == TaskRec.TaskId ? "btn-" : "btn-outline-";
|
||||
answ += TaskRec.LastIsError ? "danger" : "success";
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected async Task DoCancel()
|
||||
{
|
||||
@@ -168,7 +171,7 @@ namespace MP.TaskMan
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task DoReset()
|
||||
protected async Task DoReset(bool force)
|
||||
{
|
||||
detRecord = null;
|
||||
currRecord = null;
|
||||
@@ -208,14 +211,16 @@ namespace MP.TaskMan
|
||||
{
|
||||
detRecord = null;
|
||||
currRecord = null;
|
||||
DetailTaskId = null;
|
||||
#if false
|
||||
DetailTaskId = null;
|
||||
#endif
|
||||
isLoading = true;
|
||||
detRecord = selRec;
|
||||
await ReloadData();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
protected async Task ForceAll()
|
||||
protected async Task ForceAll(bool force)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Confermi esecuzione forzata di tutti i task?"))
|
||||
return;
|
||||
@@ -232,6 +237,7 @@ namespace MP.TaskMan
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
#if false
|
||||
protected async Task ForceReload(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
@@ -242,7 +248,8 @@ namespace MP.TaskMan
|
||||
{
|
||||
currPage = newNum;
|
||||
await ReloadData();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected async Task ForceUpdate(bool doForce)
|
||||
{
|
||||
@@ -250,18 +257,24 @@ namespace MP.TaskMan
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
#if false
|
||||
protected string iconCss(TaskListModel TaskRec)
|
||||
{
|
||||
return TaskRec.LastIsError ? "fa-thumbs-down" : "fa-thumbs-up";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
isLoading = true;
|
||||
MaxVal = 2;
|
||||
CleanupDir();
|
||||
#if false
|
||||
CleanupDir();
|
||||
#endif
|
||||
await advStep(1);
|
||||
numRecord = 10;
|
||||
#if false
|
||||
numRecord = 10;
|
||||
#endif
|
||||
await ReloadData();
|
||||
await advStep(2);
|
||||
isLoading = false;
|
||||
@@ -269,7 +282,9 @@ namespace MP.TaskMan
|
||||
|
||||
protected void ResetData()
|
||||
{
|
||||
CleanupDir();
|
||||
#if false
|
||||
CleanupDir();
|
||||
#endif
|
||||
TService.rollBackEdit(currRecord);
|
||||
currRecord = null;
|
||||
}
|
||||
@@ -284,6 +299,7 @@ namespace MP.TaskMan
|
||||
return answ;
|
||||
}
|
||||
|
||||
#if false
|
||||
protected string TextReduce(string textOriginal, int maxChar)
|
||||
{
|
||||
string answ = textOriginal;
|
||||
@@ -292,8 +308,10 @@ namespace MP.TaskMan
|
||||
answ = $"{textOriginal.Substring(0, maxChar / 2)} ... {textOriginal.Substring(answ.Length - maxChar / 2)}";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
protected void ToggleDetail(TaskListModel TaskRec)
|
||||
{
|
||||
if (DetailTaskId == null)
|
||||
@@ -304,14 +322,17 @@ namespace MP.TaskMan
|
||||
{
|
||||
DetailTaskId = (DetailTaskId.TaskId == TaskRec.TaskId) ? null : TaskRec;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private double currVal = 0;
|
||||
private TaskListModel? DetailTaskId = null;
|
||||
#if false
|
||||
private TaskListModel? DetailTaskId = null;
|
||||
#endif
|
||||
private List<TaskListModel> ListRecords = new List<TaskListModel>();
|
||||
private int MaxVal = 10;
|
||||
private double nextVal = 0;
|
||||
@@ -321,18 +342,22 @@ namespace MP.TaskMan
|
||||
|
||||
#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;
|
||||
|
||||
#if false
|
||||
private string fullPath
|
||||
{
|
||||
get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
private int numRecord { get; set; } = 10;
|
||||
#if false
|
||||
private int currPage { get; set; } = 1;
|
||||
private int numRecord { get; set; } = 10;
|
||||
#endif
|
||||
private string SearchVal { get; set; } = "";
|
||||
private Task2ExeType typeSel { get; set; } = Task2ExeType.ND;
|
||||
|
||||
@@ -340,13 +365,16 @@ namespace MP.TaskMan
|
||||
|
||||
#region Private Methods
|
||||
|
||||
#if false
|
||||
private string btnRunCss(DateTime dtNextExe)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
string answ = dtNextExe < adesso ? "btn-success" : "btn-warning";
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
private async void CleanupDir()
|
||||
{
|
||||
var parentDir = Directory.GetParent(fullPath).FullName;
|
||||
@@ -355,25 +383,31 @@ namespace MP.TaskMan
|
||||
Directory.CreateDirectory(parentDir);
|
||||
}
|
||||
await Task.Run(() => File.Delete(fullPath));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
private async Task ExportCsv()
|
||||
{
|
||||
isLoading = true;
|
||||
// salvo davvero!
|
||||
await Egw.Core.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
SearchRecords = await TService.TaskListAll(TypeSel, SearchVal);
|
||||
// suddivido per gruppo e genero relativo display
|
||||
#if false
|
||||
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();
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-sm btn-info" @onclick="DoReset" title="Reset"><i class="fas fa-sync"></i></button>
|
||||
</th>
|
||||
<th>Ord</th>
|
||||
<th>Task</th>
|
||||
<th>Tipo</th>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<th>Command</th>
|
||||
}
|
||||
<th>Sched.</th>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<th class="text-end">Last</th>
|
||||
<th class="text-end">Next</th>
|
||||
<th class="text-end">Result</th>
|
||||
<th>
|
||||
<button class="btn btn-sm btn-danger me-1" @onclick="ForceAll" title="Force All"><i class="fas fa-play"></i></button>
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record)">
|
||||
<td class="text-nowrap">
|
||||
<button class="btn btn-sm btn-info" @onclick="() => DoSelect(record)" title="Select"><i class="fas fa-search"></i></button>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (currRecord == null)
|
||||
{
|
||||
<button class="btn btn-sm btn-primary ms-1" @onclick="() => DoEdit(record)" title="Edit"><i class="fas fa-pencil-alt"></i></button>
|
||||
<button class="btn btn-sm btn-success" @onclick="() => DoClone(record)" title="Clona"><i class="fas fa-magic"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary ms-1" @onclick="() => DoCancel()" title="Cancel"><i class="fas fa-undo"></i></button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="text-nowrap">
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (record.Ordinal == minOrdinal)
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-secondary mx-1" disabled title="Cannot Move"><i class="fas fa-caret-up"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-primary mx-1" @onclick="() => DoMove(record, true)" title="Move Up"><i class="fas fa-caret-up"></i></button>
|
||||
}
|
||||
}
|
||||
<b>@record.Ordinal</b>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
@if (record.Ordinal == maxOrdinal)
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-secondary mx-1" disabled title="Cannot Move"><i class="fas fa-caret-down"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-outline-primary mx-1" @onclick="() => DoMove(record, false)" title="Move Down"><i class="fas fa-caret-down"></i></button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="text-nowrap @checkDis(@record)">
|
||||
<div>@record.Name</div>
|
||||
<div class="small text-truncate">@record.Descript</div>
|
||||
</td>
|
||||
<td class="@checkDis(@record)">
|
||||
@record.TType
|
||||
</td>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<td class="small text-truncate text-break @checkDis(@record)">
|
||||
<div class="font-monospace fw-bold" title="@record.Command">@TextReduce(record.Command, 32)</div>
|
||||
<div class="small text-break" title="@record.Args">@TextReduce(record.Args, 40)</div>
|
||||
</td>
|
||||
}
|
||||
<td>@record.Freq × @record.Cad</td>
|
||||
@if (detRecord == null)
|
||||
{
|
||||
<td class="text-end text-nowrap @checkDis(@record)">
|
||||
<div>@($"{record.DtLastExec:yyyy-MM-dd}")</div>
|
||||
<div class="small">@($"{record.DtLastExec:ddd HH:mm:ss}")</div>
|
||||
</td>
|
||||
<td class="text-end text-nowrap @checkDis(@record)">
|
||||
<div>@($"{record.DtNextExec:yyyy-MM-dd}")</div>
|
||||
<div class="small">@($"{record.DtNextExec:ddd HH:mm:ss}")</div>
|
||||
</td>
|
||||
<td class="text-end @checkDis(@record)">
|
||||
<b>@($"{record.LastDuration:N3}")</b> <sub>sec</sub> <button class="btn btn-sm @btnCss(record)" @onclick="() => ToggleDetail(record)" title="Ultima esecuzione"><i class="far @iconCss(record)"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
@if (record.Enabled)
|
||||
{
|
||||
<button class="btn btn-sm @btnRunCss(record.DtNextExec) me-1" @onclick="() => DoRun(record)" title="Run Now"><i class="fas fa-play"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary me-1" title="Disabled / Cannot run!" disabled><i class="fas fa-play"></i></button>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
@if (DetailTaskId != null && DetailTaskId.TaskId == record.TaskId)
|
||||
{
|
||||
<tr>
|
||||
<td colspan="10 @checkDis(@record)">
|
||||
<div class="d-flex justify-content-end">
|
||||
<div class="p-1 small alert @alCss(record)">
|
||||
<div class="text-trim">@record.LastResult</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="10">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="totalCount" />
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MP.TaskMan.Models;
|
||||
using MP.TaskMan.Services;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.TaskMan
|
||||
{
|
||||
public partial class TaskListTable
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public List<TaskListModel> AllRecords { get; set; } = new List<TaskListModel>();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> EC_Cancel { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<TaskListModel> EC_Clone { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> EC_DoReset { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<TaskListModel> EC_Edit { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> EC_ForceAll { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<ActionParam> EC_Move { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<TaskListModel> EC_Run { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<TaskListModel> EC_Select { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Classes
|
||||
|
||||
public class ActionParam
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public TaskListModel? CurrRec { get; set; } = null;
|
||||
public bool GoUp { get; set; } = true;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
#endregion Public Classes
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected bool isLoading = false;
|
||||
protected List<TaskListModel> ListRecords = new List<TaskListModel>();
|
||||
protected int maxOrdinal = 999;
|
||||
protected int minOrdinal = 0;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected TaskService TService { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
protected string checkSelect(TaskListModel selRec)
|
||||
{
|
||||
string answ = "";
|
||||
if (currRecord != null)
|
||||
{
|
||||
answ = (currRecord.Equals(selRec)) ? "table-info" : "";
|
||||
}
|
||||
else if (detRecord != null)
|
||||
{
|
||||
answ = detRecord.Equals(selRec) ? "table-info" : "";
|
||||
}
|
||||
#if false
|
||||
// verifico se sia disabilitato...
|
||||
if (!selRec.Enabled)
|
||||
{
|
||||
answ += " text-secondary text-opacity-50 textStriked";
|
||||
}
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
#region Protected Methods
|
||||
|
||||
protected string alCss(TaskListModel TaskRec)
|
||||
{
|
||||
return TaskRec.LastIsError ? "alert-danger" : "alert-success";
|
||||
}
|
||||
|
||||
protected string btnCss(TaskListModel TaskRec)
|
||||
{
|
||||
string answ = DetailTaskId != null && DetailTaskId.TaskId == TaskRec.TaskId ? "btn-" : "btn-outline-";
|
||||
answ += TaskRec.LastIsError ? "danger" : "success";
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected string checkDis(TaskListModel selRec)
|
||||
{
|
||||
string answ = "";
|
||||
// verifico se sia disabilitato...
|
||||
if (!selRec.Enabled)
|
||||
{
|
||||
answ += " text-secondary text-opacity-75 textStriked";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected async Task DoCancel()
|
||||
{
|
||||
await EC_Cancel.InvokeAsync(true);
|
||||
}
|
||||
|
||||
protected async Task DoClone(TaskListModel currRec)
|
||||
{
|
||||
await EC_Clone.InvokeAsync(currRec);
|
||||
}
|
||||
|
||||
protected async Task DoEdit(TaskListModel currRec)
|
||||
{
|
||||
await EC_Edit.InvokeAsync(currRec);
|
||||
}
|
||||
|
||||
protected async Task DoMove(TaskListModel currRec, bool goUp)
|
||||
{
|
||||
ActionParam retVal = new ActionParam()
|
||||
{
|
||||
CurrRec = currRec,
|
||||
GoUp = goUp
|
||||
};
|
||||
await EC_Move.InvokeAsync(retVal);
|
||||
}
|
||||
|
||||
protected async Task DoReset()
|
||||
{
|
||||
await EC_DoReset.InvokeAsync(true);
|
||||
}
|
||||
|
||||
protected async Task DoRun(TaskListModel currRec)
|
||||
{
|
||||
await EC_Run.InvokeAsync(currRec);
|
||||
}
|
||||
|
||||
protected async Task DoSelect(TaskListModel currRec)
|
||||
{
|
||||
DetailTaskId = null;
|
||||
await EC_Select.InvokeAsync(currRec);
|
||||
}
|
||||
|
||||
protected async Task ForceAll()
|
||||
{
|
||||
await EC_ForceAll.InvokeAsync(true);
|
||||
}
|
||||
|
||||
protected string iconCss(TaskListModel TaskRec)
|
||||
{
|
||||
return TaskRec.LastIsError ? "fa-thumbs-down" : "fa-thumbs-up";
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
protected void SetNumRec(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
protected void SetPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
ReloadData();
|
||||
}
|
||||
|
||||
protected string TextReduce(string textOriginal, int maxChar)
|
||||
{
|
||||
string answ = textOriginal;
|
||||
if (answ.Length > maxChar)
|
||||
{
|
||||
answ = $"{textOriginal.Substring(0, maxChar / 2)} ... {textOriginal.Substring(answ.Length - maxChar / 2)}";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected async Task ToggleDetail(TaskListModel TaskRec)
|
||||
{
|
||||
if (DetailTaskId == null)
|
||||
{
|
||||
DetailTaskId = TaskRec;
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailTaskId = (DetailTaskId.TaskId == TaskRec.TaskId) ? null : TaskRec;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private int currPage = 1;
|
||||
private TaskListModel? DetailTaskId = null;
|
||||
private int numRecord = 10;
|
||||
|
||||
private int totalCount = 10;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private TaskListModel? currRecord { get; set; } = null;
|
||||
|
||||
private TaskListModel? detRecord { get; set; } = null;
|
||||
|
||||
#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 void ReloadData()
|
||||
{
|
||||
totalCount = AllRecords.Count;
|
||||
var firstRec = AllRecords.OrderBy(x => x.Ordinal).FirstOrDefault();
|
||||
minOrdinal = firstRec != null ? firstRec.Ordinal : 0;
|
||||
var lastRec = AllRecords.OrderByDescending(x => x.Ordinal).FirstOrDefault();
|
||||
maxOrdinal = lastRec != null ? lastRec.Ordinal : 9999;
|
||||
ListRecords = AllRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user