Merge branch 'feature/GestUpdateMod' into develop

This commit is contained in:
Samuele Locatelli
2021-09-07 19:17:41 +02:00
26 changed files with 1326 additions and 290 deletions
+413 -205
View File
@@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MP.FileData.DatabaseModels;
namespace MP.FileData.Controllers
{
@@ -31,6 +32,418 @@ namespace MP.FileData.Controllers
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Elenco tabella Articoli (FILTRATO!!!)
/// </summary>
/// <param name="searchVal"></param>
/// <param name="maxNum"></param>
/// <returns></returns>
public List<DatabaseModels.ArticoloModel> ArtGetFilt(string searchVal, int maxNum = 100)
{
maxNum = maxNum <= 0 ? 100 : maxNum;
List<DatabaseModels.ArticoloModel> dbResult = new List<DatabaseModels.ArticoloModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
int totRecord = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.Count();
if (totRecord > maxNum)
{
dbResult = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.OrderBy(x => x.DescArticolo)
.Take(maxNum)
.ToList();
dbResult.Add(new DatabaseModels.ArticoloModel() { CodArticolo = "#####", DescArticolo = $"... +{totRecord - maxNum} rec ..." });
}
else
{
dbResult = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.OrderBy(x => x.DescArticolo)
.ToList();
}
}
return dbResult;
}
/// <summary>
/// Effettua la comparazione tra i file in archivio ed i file attuali e segna info LastCheck e Changed (se cambiati)
/// </summary>
/// <returns></returns>
public bool CheckFileArchived(string idxMacchina, string path, string searchPattern)
{
bool answ = false;
DirectoryInfo dirInfo = new DirectoryInfo(path);
FileInfo[] fileList = dirInfo.GetFiles(searchPattern);
List<FileInfo> fileNew = new List<FileInfo>();
List<FileModel> fileChecked = new List<FileModel>();
List<FileModel> fileMod = new List<FileModel>();
DateTime adesso = DateTime.Now;
// recupera elenco file nel DB
var archivedFile = FileGetByPath(path, true);
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
// verifica i file
foreach (var file in fileList)
{
// cerca nel DB...
FileModel currRecord = archivedFile
.Where(x => x.Active && x.Path == file.FullName)
.OrderByDescending(y => y.Rev)
.FirstOrDefault();
// se NON trova lo crea
if (currRecord == null)
{
fileNew.Add(file);
}
else
{
// verifico se data modifica sia cambiata...
if (currRecord.LastMod != file.LastWriteTime)
{
// calcolo e verifico MD5
var fileContent = File.ReadAllBytes(file.FullName);
var hash = md5.ComputeHash(fileContent);
var newMD5 = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
if (newMD5 != currRecord.MD5)
{
fileMod.Add(currRecord);
}
else
{
fileChecked.Add(currRecord);
}
}
else
{
fileChecked.Add(currRecord);
}
}
}
}
// salvo i NUOVI file
if (fileNew != null && fileNew.Count > 0)
{
FileInsert(idxMacchina, fileNew, 0);
}
// aggiorno i file modificati
if (fileMod != null && fileMod.Count > 0)
{
FileSetUpdated(fileMod);
}
// segno data-ora ultimo controllo x file invariati
if (fileChecked != null && fileChecked.Count > 0)
{
FileSetChecked(fileChecked);
}
return answ;
}
public void Dispose()
{
// Clear database context
dbCtx.Dispose();
}
/// <summary>
/// ELiminazione file da tabella
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
public bool FileDelete(FileModel currItem)
{
bool done = false;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// eliminazione di uno specifico file + rev da tabella
var file2del = localDbCtx
.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.Articolo == currItem.Articolo && x.IdxMacchina == currItem.IdxMacchina)
.OrderByDescending(y => y.Rev)
.FirstOrDefault();
if (file2open != null)
{
file2open.Active = true;
}
// salvo!
localDbCtx.SaveChanges();
done = true;
}
return done;
}
public bool FileDiskStatusChange(List<FileModel> updFiles, FileState newStatus)
{
bool done = false;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
foreach (var item in updFiles)
{
item.DiskStatus = newStatus;
localDbCtx.Entry(item).State = EntityState.Modified;
}
localDbCtx.SaveChanges();
done = true;
}
return done;
}
public FileModel FileGetByKey(int FileId)
{
FileModel thisFile = null;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
thisFile = localDbCtx
.DbSetProgFile
.Where(x => x.FileId == FileId)
.FirstOrDefault();
}
return thisFile;
}
public List<DatabaseModels.FileModel> FileGetByPath(string path, bool onlyActive)
{
List<DatabaseModels.FileModel> dbResult = new List<DatabaseModels.FileModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
dbResult = localDbCtx
.DbSetProgFile
.Where(x => x.Path.StartsWith(path) && ((onlyActive == x.Active) || !onlyActive))
.OrderBy(x => x.Name)
.ToList();
}
return dbResult;
}
public List<DatabaseModels.FileModel> FileGetFilt(string IdxMacchina, string CodArticolo, bool OnlyActive, bool OnlyMod, string SearchVal = "")
{
List<DatabaseModels.FileModel> dbResult = new List<DatabaseModels.FileModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
dbResult = localDbCtx
.DbSetProgFile
.Include(m => m.Macchina)
.Include(a => a.Articolo)
.Where(x => (x.IdxMacchina == IdxMacchina || IdxMacchina == "0") && (x.Active == OnlyActive || !OnlyActive) && (!OnlyMod || x.DiskStatus != FileState.Ok) && (x.Name.Contains(SearchVal) || string.IsNullOrEmpty(SearchVal)))
.OrderByDescending(x => x.LastMod)
.ToList();
}
return dbResult;
}
/// <summary>
/// Effettua inserimento di un elenco di record in archivio come NUOVO documento tracciato
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="newFiles"></param>
/// <param name="rev"></param>
/// <returns></returns>
public bool FileInsert(string idxMacchina, List<FileInfo> newFiles, int rev)
{
bool answ = false;
DateTime adesso = DateTime.Now;
// MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// converto
List<DatabaseModels.FileModel> newRec = newFiles.Select(o => new DatabaseModels.FileModel()
{
Active = true,
CodArticolo = "ND",
DiskStatus = FileState.Ok,
IdxMacchina = idxMacchina,
LastCheck = adesso,
LastMod = o.LastWriteTime,
MimeType = o.Extension,
Name = o.Name,
Path = o.FullName,
Rev = rev,
Size = o.Length,
FileContent = File.ReadAllBytes(o.FullName)
}).ToList();
// calcolo MD5
foreach (var item in newRec)
{
var hash = md5.ComputeHash(item.FileContent);
item.MD5 = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
// aggiungo in blocco
localDbCtx
.DbSetProgFile
.AddRange(newRec);
// salvo
localDbCtx.SaveChanges();
answ = true;
}
}
return answ;
}
public bool FileModApprove(FileModel currFile)
{
bool done = false;
List<FileInfo> listUpdate = new List<FileInfo>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// rileggo dati file...
var newFileInfo = new FileInfo(currFile.Path);
listUpdate.Add(newFileInfo);
// inserisco come REVISIONE
FileInsert(currFile.IdxMacchina, listUpdate, currFile.Rev + 1);
// archivio vecchio file
currFile.Active = false;
currFile.DiskStatus = FileState.Ok;
localDbCtx.Entry(currFile).State = EntityState.Modified;
// salvo DB
localDbCtx.SaveChanges();
done = true;
}
return done;
}
public bool FileModReject(FileModel currFile)
{
bool done = false;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// sovrascrivo il file su disco
File.WriteAllBytes(currFile.Path, currFile.FileContent);
// rileggo file...
var newFileInfo = new FileInfo(currFile.Path);
// aggiorno stato del file a unchanged e data mod ad ora...
currFile.DiskStatus = FileState.Ok;
currFile.LastMod = newFileInfo.LastWriteTime;
localDbCtx.Entry(currFile).State = EntityState.Modified;
// salvo DB
localDbCtx.SaveChanges();
done = true;
}
return done;
}
/// <summary>
/// Effettua update di un record in archivio da lista (SOLO STATUS)
/// </summary>
/// <param name="updFiles"></param>
/// <returns></returns>
public bool FileSetChecked(List<FileModel> updFiles)
{
bool answ = false;
DateTime adesso = DateTime.Now;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
foreach (var item in updFiles)
{
item.LastCheck = adesso;
localDbCtx.Entry(item).State = EntityState.Modified;
}
// salvo
localDbCtx.SaveChanges();
answ = true;
}
return answ;
}
/// <summary>
/// Effettua update di un record in archivio da lista (SOLO STATUS)
/// </summary>
/// <param name="updFiles"></param>
/// <returns></returns>
public bool FileSetUpdated(List<FileModel> updFiles)
{
bool answ = false;
DateTime adesso = DateTime.Now;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
foreach (var item in updFiles)
{
item.DiskStatus = FileState.Changed;
item.LastCheck = adesso;
localDbCtx.Entry(item).State = EntityState.Modified;
}
// salvo
localDbCtx.SaveChanges();
answ = true;
}
return answ;
}
/// <summary>
/// Aggiorna un Ordine
/// </summary>
/// <param name="updItem"></param>
/// <returns></returns>
public bool FileUpdate(FileModel updItem)
{
bool done = false;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
try
{
FileModel currData = null;
currData = dbCtx
.DbSetProgFile
.Where(x => x.FileId == updItem.FileId)
.FirstOrDefault();
if (currData != null)
{
updItem.DiskStatus = FileState.Changed;
localDbCtx.Entry(updItem).State = EntityState.Modified;
localDbCtx.SaveChanges();
}
else
{
dbCtx
.DbSetProgFile
.Add(updItem);
dbCtx.SaveChanges();
}
done = true;
}
catch (Exception exc)
{
Log.Error(exc, "Eccezione durante FileUpdate");
}
}
return done;
}
#if false
/// <summary>
/// Elenco Azioni (decodifica)
@@ -88,211 +501,6 @@ namespace MP.FileData.Controllers
}
#endif
#region Public Methods
/// <summary>
/// Elenco tabella Articoli (FILTRATO!!!)
/// </summary>
/// <param name="searchVal"></param>
/// <param name="maxNum"></param>
/// <returns></returns>
public List<DatabaseModels.ArticoloModel> ArtGetFilt(string searchVal, int maxNum = 100)
{
maxNum = maxNum <= 0 ? 100 : maxNum;
List<DatabaseModels.ArticoloModel> dbResult = new List<DatabaseModels.ArticoloModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
int totRecord = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.Count();
if (totRecord > maxNum)
{
dbResult = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.OrderBy(x => x.DescArticolo)
.Take(maxNum)
.ToList();
dbResult.Add(new DatabaseModels.ArticoloModel() { CodArticolo = "#####", DescArticolo = $"... +{totRecord - maxNum} rec ..." });
}
else
{
dbResult = localDbCtx
.DbSetArticoli
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))
.OrderBy(x => x.DescArticolo)
.ToList();
}
}
return dbResult;
}
/// <summary>
/// Effettua la comparazione tra i file in archivio ed i file attuali e segna info LastCheck e Changed (se cambiati)
/// </summary>
/// <returns></returns>
public bool CheckFileArchived(string idxMacchina, string path, string searchPattern)
{
bool answ = false;
DirectoryInfo dirInfo = new DirectoryInfo(path);
FileInfo[] fileList = dirInfo.GetFiles("*.*");
List<FileInfo> fileNew = new List<FileInfo>();
List<FileInfo> fileMod = new List<FileInfo>();
// recupera elenco file nel DB
var archivedFile = FileGetByPath(path, true);
// verifica i file
foreach (var file in fileList)
{
// cerca nel DB...
var currRecord = archivedFile
.Where(x => x.Path == file.FullName)
.FirstOrDefault();
// se NON trova lo crea
if (currRecord == null)
{
fileNew.Add(file);
}
else
{
fileMod.Add(file);
}
}
// salvo i NUOVI file
if (fileNew != null && fileNew.Count > 0)
{
FileInsert(idxMacchina, fileNew);
}
// aggiorno i file modificati
if (fileMod != null && fileMod.Count > 0)
{
FileUpdate(idxMacchina, fileMod);
}
return answ;
}
public void Dispose()
{
// Clear database context
dbCtx.Dispose();
}
public List<DatabaseModels.FileModel> FileGetByPath(string path, bool onlyActive)
{
List<DatabaseModels.FileModel> dbResult = new List<DatabaseModels.FileModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
dbResult = localDbCtx
.DbSetProgFile
.Where(x => x.Path.StartsWith(path) && ((onlyActive && x.Active) || !onlyActive))
.OrderBy(x => x.Name)
.ToList();
}
return dbResult;
}
public List<DatabaseModels.FileModel> FileGetFilt(string IdxMacchina, string CodArticolo, string SearchVal = "")
{
List<DatabaseModels.FileModel> dbResult = new List<DatabaseModels.FileModel>();
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
dbResult = localDbCtx
.DbSetProgFile
.Include(m => m.Macchina)
.Include(a => a.Articolo)
.Where(x => ((x.IdxMacchina == IdxMacchina || IdxMacchina == "0") || (x.CodArticolo == CodArticolo || CodArticolo == "ND" || CodArticolo == "")) && (x.Name.Contains(SearchVal) || string.IsNullOrEmpty(SearchVal)))
.OrderBy(x => x.Name)
.ToList();
}
return dbResult;
}
/// <summary>
/// effettua inserimento di un record in archivio come NUOVO documento tracciato
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="newFiles"></param>
/// <returns></returns>
public bool FileInsert(string idxMacchina, List<FileInfo> newFiles)
{
bool answ = false;
DateTime adesso = DateTime.Now;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// converto
List<DatabaseModels.FileModel> newRec = newFiles.Select(o => new DatabaseModels.FileModel()
{
Active = true,
CodArticolo = "ND",
Changed = false,
IdxMacchina = idxMacchina,
LastCheck = adesso,
LastMod = o.LastWriteTime,
MimeType = o.Extension,
Name = o.Name,
Path = o.FullName,
Rev = 0,
Size = o.Length,
FileContent = File.ReadAllBytes(o.FullName)
}).ToList();
// aggiungo in blocco
localDbCtx
.DbSetProgFile
.AddRange(newRec);
// salvo
localDbCtx.SaveChanges();
answ = true;
}
return answ;
}
/// <summary>
/// effettua inserimento di un record in archivio come NUOVO documento tracciato
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="updFiles"></param>
/// <returns></returns>
public bool FileUpdate(string idxMacchina, List<FileInfo> updFiles)
{
bool answ = false;
DateTime adesso = DateTime.Now;
using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration))
{
// converto
List<DatabaseModels.FileModel> newRec = updFiles.Select(o => new DatabaseModels.FileModel()
{
Active = true,
CodArticolo = "ND",
Changed = false,
IdxMacchina = idxMacchina,
LastCheck = adesso,
LastMod = o.LastWriteTime,
MimeType = o.Extension,
Name = o.Name,
Path = o.FullName,
Rev = 0,
Size = o.Length,
FileContent = File.ReadAllBytes(o.FullName)
}).ToList();
// aggiungo in blocco
localDbCtx
.DbSetProgFile
.UpdateRange(newRec);
// salvo
localDbCtx.SaveChanges();
answ = true;
}
return answ;
}
/// <summary>
/// Elenco tabella Macchine
/// </summary>
+18 -1
View File
@@ -30,10 +30,27 @@ namespace MP.FileData.DatabaseModels
public long Size { get; set; } = 0;
public string Path { get; set; } = "";
public string MimeType { get; set; } = "";
public bool Changed { get; set; } = false;
public string MD5 { get; set; } = "";
public FileState DiskStatus { get; set; } = FileState.Ok;
public DateTime LastCheck { get; set; } = DateTime.Now.AddYears(-1);
public byte[] FileContent { get; set; }
public ICollection<TagModel> Tags { get; set; }
[NotMapped]
public string FileStringContent
{
get
{
return Encoding.UTF8.GetString(FileContent);
}
set
{
// serializzo a byte
FileContent = Encoding.ASCII.GetBytes(value);
}
}
[ForeignKey("CodArticolo")]
public virtual ArticoloModel Articolo { get; set; }
[ForeignKey("IdxMacchina")]
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.FileData.DatabaseModels
{
[Table("Tags")]
public partial class TagModel
{
[Key]
public string TagId { get; set; }
public ICollection<FileModel> Files { get; set; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.FileData
{
/// <summary>
/// Stato File
/// </summary>
public enum FileState
{
ND = 0,
Changed,
Deleted,
Ok
}
}
@@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace MP.FileData.Migrations
{
[DbContext(typeof(MoonPro_ProgContext))]
[Migration("20210903153915_InitDb")]
[Migration("20210907103215_InitDb")]
partial class InitDb
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -22,6 +22,21 @@ namespace MP.FileData.Migrations
.HasAnnotation("ProductVersion", "5.0.9")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("FileModelTagModel", b =>
{
b.Property<int>("FilesFileId")
.HasColumnType("int");
b.Property<string>("TagsTagId")
.HasColumnType("nvarchar(450)");
b.HasKey("FilesFileId", "TagsTagId");
b.HasIndex("TagsTagId");
b.ToTable("FileModelTagModel");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.ArticoloModel", b =>
{
b.Property<string>("CodArticolo")
@@ -60,12 +75,12 @@ namespace MP.FileData.Migrations
b.Property<bool>("Active")
.HasColumnType("bit");
b.Property<bool>("Changed")
.HasColumnType("bit");
b.Property<string>("CodArticolo")
.HasColumnType("nvarchar(450)");
b.Property<int>("DiskStatus")
.HasColumnType("int");
b.Property<byte[]>("FileContent")
.HasColumnType("varbinary(max)");
@@ -78,6 +93,9 @@ namespace MP.FileData.Migrations
b.Property<DateTime>("LastMod")
.HasColumnType("datetime2");
b.Property<string>("MD5")
.HasColumnType("nvarchar(max)");
b.Property<string>("MimeType")
.HasColumnType("nvarchar(max)");
@@ -146,6 +164,31 @@ namespace MP.FileData.Migrations
});
});
modelBuilder.Entity("MP.FileData.DatabaseModels.TagModel", b =>
{
b.Property<string>("TagId")
.HasColumnType("nvarchar(450)");
b.HasKey("TagId");
b.ToTable("Tags");
});
modelBuilder.Entity("FileModelTagModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.FileModel", null)
.WithMany()
.HasForeignKey("FilesFileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MP.FileData.DatabaseModels.TagModel", null)
.WithMany()
.HasForeignKey("TagsTagId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.ArticoloModel", "Articolo")
@@ -39,6 +39,17 @@ namespace MP.FileData.Migrations
table.PrimaryKey("PK_Macchine", x => x.IdxMacchina);
});
migrationBuilder.CreateTable(
name: "Tags",
columns: table => new
{
TagId = table.Column<string>(type: "nvarchar(450)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tags", x => x.TagId);
});
migrationBuilder.CreateTable(
name: "Files",
columns: table => new
@@ -54,7 +65,8 @@ namespace MP.FileData.Migrations
Size = table.Column<long>(type: "bigint", nullable: false),
Path = table.Column<string>(type: "nvarchar(max)", nullable: true),
MimeType = table.Column<string>(type: "nvarchar(max)", nullable: true),
Changed = table.Column<bool>(type: "bit", nullable: false),
MD5 = table.Column<string>(type: "nvarchar(max)", nullable: true),
DiskStatus = table.Column<int>(type: "int", nullable: false),
LastCheck = table.Column<DateTime>(type: "datetime2", nullable: false),
FileContent = table.Column<byte[]>(type: "varbinary(max)", nullable: true)
},
@@ -75,6 +87,30 @@ namespace MP.FileData.Migrations
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "FileModelTagModel",
columns: table => new
{
FilesFileId = table.Column<int>(type: "int", nullable: false),
TagsTagId = table.Column<string>(type: "nvarchar(450)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FileModelTagModel", x => new { x.FilesFileId, x.TagsTagId });
table.ForeignKey(
name: "FK_FileModelTagModel_Files_FilesFileId",
column: x => x.FilesFileId,
principalTable: "Files",
principalColumn: "FileId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_FileModelTagModel_Tags_TagsTagId",
column: x => x.TagsTagId,
principalTable: "Tags",
principalColumn: "TagId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Articoli",
columns: new[] { "CodArticolo", "DescArticolo", "Disegno", "Tipo" },
@@ -85,6 +121,11 @@ namespace MP.FileData.Migrations
columns: new[] { "IdxMacchina", "BasePath", "CodMacchina", "Descrizione", "ImgUrl", "Nome", "Note", "ShowOrder" },
values: new object[] { "0", "", "0", "--- Tutte ---", "", "--- Tutte ---", "", 0 });
migrationBuilder.CreateIndex(
name: "IX_FileModelTagModel_TagsTagId",
table: "FileModelTagModel",
column: "TagsTagId");
migrationBuilder.CreateIndex(
name: "IX_Files_CodArticolo",
table: "Files",
@@ -98,9 +139,15 @@ namespace MP.FileData.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FileModelTagModel");
migrationBuilder.DropTable(
name: "Files");
migrationBuilder.DropTable(
name: "Tags");
migrationBuilder.DropTable(
name: "Articoli");
@@ -20,6 +20,21 @@ namespace MP.FileData.Migrations
.HasAnnotation("ProductVersion", "5.0.9")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("FileModelTagModel", b =>
{
b.Property<int>("FilesFileId")
.HasColumnType("int");
b.Property<string>("TagsTagId")
.HasColumnType("nvarchar(450)");
b.HasKey("FilesFileId", "TagsTagId");
b.HasIndex("TagsTagId");
b.ToTable("FileModelTagModel");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.ArticoloModel", b =>
{
b.Property<string>("CodArticolo")
@@ -58,12 +73,12 @@ namespace MP.FileData.Migrations
b.Property<bool>("Active")
.HasColumnType("bit");
b.Property<bool>("Changed")
.HasColumnType("bit");
b.Property<string>("CodArticolo")
.HasColumnType("nvarchar(450)");
b.Property<int>("DiskStatus")
.HasColumnType("int");
b.Property<byte[]>("FileContent")
.HasColumnType("varbinary(max)");
@@ -76,6 +91,9 @@ namespace MP.FileData.Migrations
b.Property<DateTime>("LastMod")
.HasColumnType("datetime2");
b.Property<string>("MD5")
.HasColumnType("nvarchar(max)");
b.Property<string>("MimeType")
.HasColumnType("nvarchar(max)");
@@ -144,6 +162,31 @@ namespace MP.FileData.Migrations
});
});
modelBuilder.Entity("MP.FileData.DatabaseModels.TagModel", b =>
{
b.Property<string>("TagId")
.HasColumnType("nvarchar(450)");
b.HasKey("TagId");
b.ToTable("Tags");
});
modelBuilder.Entity("FileModelTagModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.FileModel", null)
.WithMany()
.HasForeignKey("FilesFileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MP.FileData.DatabaseModels.TagModel", null)
.WithMany()
.HasForeignKey("TagsTagId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.ArticoloModel", "Articolo")
+110
View File
@@ -0,0 +1,110 @@
@using MP.FileData.DatabaseModels
@using MP.Prog.Data
@inject FileArchDataService DataService
@inject MessageService AppMService
@if (ArtList == null)
{
<LoadingData></LoadingData>
}
else
{
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<span class="fas fa-search" aria-hidden="true"></span>
</span>
</div>
<input type="text" class="form-control form-control-sm" placeholder="Ricerca Articolo" @bind-value="@SearchArt" />
<select @bind="@SelCodArt" class="form-control form-control-sm">
@if (ArtList != null)
{
foreach (var item in ArtList)
{
<option value="@item.CodArticolo">@item.Disegno | @item.DescArticolo [@item.CodArticolo]</option>
}
}
</select>
<div class="input-group-append">
<button id="searchReset" class="btn btn-sm btn-secondary" @onclick="() => ResetSearchArt()" title="Reset ricerca articolo"><i class="fas fa-ban"></i></button>
</div>
</div>
}
@code {
[Parameter]
public EventCallback<string> searchUpdated { get; set; }
[Parameter]
public string SelCodArt
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.CodArticolo;
}
return answ;
}
set
{
if (!AppMService.File_Filter.CodArticolo.Equals(value))
{
AppMService.File_Filter.CodArticolo = value;
}
reportChange();
}
}
private void reportChange()
{
searchUpdated.InvokeAsync(SelCodArt);
}
protected string _SearchArt;
protected string defCodArt = "";
protected List<ArticoloModel> ArtList;
protected string SearchArt
{
get
{
return _SearchArt;
}
set
{
_SearchArt = value;
// se son > 3 char... debounce...
if (string.IsNullOrEmpty(value))
{
_SearchArt = defCodArt;
}
if (value.Length >= defCodArt.Length)
{
var pUpd = Task.Run(async () =>
{
ArtList = await DataService.ArticoliGetFilt(SearchArt);
});
pUpd.Wait();
}
}
}
protected override async Task OnInitializedAsync()
{
await ReloadAllData();
_SearchArt = defCodArt;
}
protected async Task ReloadAllData()
{
SelCodArt = defCodArt;
ArtList = await DataService.ArticoliGetFilt(SearchArt);
}
protected void ResetSearchArt()
{
SearchArt = defCodArt;
}
}
+154
View File
@@ -0,0 +1,154 @@
@using MP.Prog.Data
@using System.Text
@using DiffMatchPatch
<div class="row">
<div class="col-6 table-success">
<div class="row">
<div class="col-4 text-success">
<h4>Archivio</h4>
</div>
<div class="col-4">
</div>
<div class="col-4 text-right">
<input @bind="@pHeight" class="text-right" width="20" inputmode="numeric" /> <i class="fas fa-arrows-alt-v"></i>
</div>
</div>
</div>
@if (numChanges > 0)
{
<div class="col-6 table-danger">
<div class="row">
<div class="col-4 text-danger">
<h4>Attuale</h4>
</div>
<div class="col-4">
</div>
<div class="col-4 text-right">
<span class="border border-danger table-danger px-2"><b>@numChanges</b> modifiche</span>
</div>
</div>
</div>
}
</div>
<div class="row" style="height: @(pHeight)em; overflow-y: scroll;">
<div class="col-6 table-success">
<div class="border border-success p-2 bg-light">
<p>@((MarkupString)oldResult)</p>
</div>
</div>
@if (numChanges > 0)
{
<div class="col-6 table-danger">
<div class="border border-danger p-2 bg-light">
<p>@((MarkupString)newResult)</p>
</div>
</div>
}
</div>
@code {
string sepDest = "<br />";
protected int pHeight = 25;
protected string oldResult = "";
protected string newResult = "";
protected string _oldText = "";
protected string _newText = "";
[Parameter]
public EventCallback<int> diffDone { get; set; }
protected int numChanges { get; set; } = 0;
[Parameter]
public string oldText
{
get
{
return _oldText;
}
set
{
_oldText = value;
}
}
protected string oldTextFix
{
get
{
return _oldText.Replace(Environment.NewLine, sepDest).Replace("\n", sepDest).Replace("\r", sepDest);
}
}
protected string newTextFix
{
get
{
return _newText.Replace(Environment.NewLine, sepDest).Replace("\n", sepDest).Replace("\r", sepDest);
}
}
[Parameter]
public string newText
{
get
{
return _newText;
}
set
{
_newText = value;
ReloadData();
}
}
protected void ReloadData()
{
numChanges = 0;
// calcolo diff
diff_match_patch dmp = new diff_match_patch();
List<Diff> diff = dmp.diff_main(oldTextFix, newTextFix);
dmp.diff_cleanupSemantic(diff);
// predispongo la stringa secondo l'elenco dei diff....
StringBuilder sbNew = new StringBuilder();
StringBuilder sbOld = new StringBuilder();
foreach (var item in diff)
{
switch (item.operation)
{
case Operation.DELETE:
sbOld.Append($"<span class=\"border border-success table-success\">{item.text}</span>");
break;
case Operation.INSERT:
sbNew.Append($"<span class=\"border border-danger table-danger\">{item.text}</span>");
numChanges++;
break;
case Operation.EQUAL:
sbNew.Append($"<span class=\"text-dark\">{item.text}</span>");
sbOld.Append($"<span class=\"text-dark\">{item.text}</span>");
break;
default:
break;
}
}
newResult = sbNew.ToString().Trim();
oldResult = sbOld.ToString().Trim();
var pUpd = Task.Run(async () =>
{
await diffDone.InvokeAsync(numChanges);
});
pUpd.Wait();
}
protected override Task OnInitializedAsync()
{
ReloadData();
return base.OnInitializedAsync();
}
}
+31
View File
@@ -0,0 +1,31 @@
<div class="card">
<div class="card-header bg-secondary text-light">
<div class="row">
<div class="col-4">
<h5>Dettaglio modifiche</h5>
</div>
<div class="col-4">
@if (_currItem.DiskStatus != FileData.FileState.Ok)
{
<div class="row">
<div class="col-6">
<button type="button" class="btn btn-success btn-block" value="Cancel" @onclick="RejectChange">Mantieni Archivio <i class="fas fa-file-download"></i></button>
</div>
<div class="col-6">
<button type="button" class="btn btn-danger btn-block" value="Cancel" @onclick="ApproveChange">Accetta Attuale <i class="fas fa-file-upload"></i></button>
</div>
</div>
}
</div>
<div class="col-2">
@numDiff
</div>
<div class="col-2 text-right">
<button type="button" class="btn btn-primary btn-block" value="Cancel" @onclick="cancelUpdate" title="Chiudi">Chiudi <i class="fas fa-window-close"></i></button>
</div>
</div>
</div>
<div class="card-body small py-1">
<MP.Prog.Components.DiffView oldText="@_currItem.FileStringContent" newText="@(CurrFileContent(_currItem.Path))"></MP.Prog.Components.DiffView>
</div>
</div>
+161
View File
@@ -0,0 +1,161 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.FileData.DatabaseModels;
using MP.Prog.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Components
{
public partial class FileEditor : ComponentBase
{
#region Protected Fields
protected int numDiff = 0;
#endregion Protected Fields
#region Public Fields
public FileModel _currItem = new FileModel();
#endregion Public Fields
#region Protected Properties
[Inject]
protected FileArchDataService DataService { get; set; }
[Inject]
protected IJSRuntime JSRuntime { get; set; }
#endregion Protected Properties
#region Public Properties
[Parameter]
public List<ArticoloModel> ArtList { get; set; }
[Parameter]
public FileModel currItem
{
get
{
return _currItem = null;
}
set
{
_currItem = value;
}
}
[Parameter]
public EventCallback<int> DataReset { get; set; }
[Parameter]
public EventCallback<int> DataUpdated { get; set; }
[Parameter]
public List<MacchinaModel> MacList { get; set; }
#endregion Public Properties
#region Private Methods
private async Task ApproveChange()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler asccettare la modifica del file selezionato generando una nuova revisione?"))
return;
if (_currItem != null)
{
await DataService.FileApprove(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task cancelUpdate()
{
await DataReset.InvokeAsync(0);
}
private async Task deleteRecord()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il file selezionato??"))
return;
if (_currItem != null)
{
await DataService.FileDelete(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task RejectChange()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare la modifica del file selezionato e sovrascrivere la versione in rete?"))
return;
if (_currItem != null)
{
await DataService.FileReject(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task saveUpdate()
{
if (_currItem != null)
{
await DataService.FileUpdate(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
#endregion Private Methods
#region Protected Methods
protected void diffDoneHandler(int numChanges)
{
#if false
numDiff = numChanges;
#endif
}
#endregion Protected Methods
#region Public Methods
public string CurrFileContent(string fullPath)
{
string answ = "";
if (File.Exists(fullPath))
{
answ = File.ReadAllText(fullPath);
}
return answ;
}
#endregion Public Methods
}
}
+2 -2
View File
@@ -28,9 +28,9 @@
}
}
private void reportChange()
private async Task reportChange()
{
searchUpdated.InvokeAsync(searchVal);
await searchUpdated.InvokeAsync(searchVal);
}
private void reset()
+29 -3
View File
@@ -102,6 +102,26 @@ namespace MP.Prog.Data
#region Internal Methods
internal Task FileApprove(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileModApprove(currItem));
}
internal Task FileDelete(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileDelete(currItem));
}
internal Task FileReject(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileModReject(currItem));
}
internal Task FileUpdate(FileData.DatabaseModels.FileModel updItem)
{
return Task.FromResult(dbController.FileUpdate(updItem));
}
internal void ResetController()
{
dbController.ResetController();
@@ -187,7 +207,8 @@ namespace MP.Prog.Data
public Task<List<MP.FileData.DatabaseModels.ArticoloModel>> ArticoliGetFilt(string SearchVal)
{
return Task.FromResult(dbController.ArtGetFilt(SearchVal, 20).ToList());
return Task.FromResult(dbController.ArtGetFilt(SearchVal, 200).ToList());
//return Task.FromResult(dbController.ArtGetFilt(SearchVal, 20).ToList());
}
public void Dispose()
@@ -196,9 +217,14 @@ namespace MP.Prog.Data
dbController.Dispose();
}
public Task<List<MP.FileData.DatabaseModels.FileModel>> FileGetFilt(string IdxMacchina, string CodArticolo, string SearchVal)
public Task<MP.FileData.DatabaseModels.FileModel> FileGetByKey(int FileId)
{
return Task.FromResult(dbController.FileGetFilt(IdxMacchina, CodArticolo, SearchVal).ToList());
return Task.FromResult(dbController.FileGetByKey(FileId));
}
public Task<List<MP.FileData.DatabaseModels.FileModel>> FileGetFilt(string IdxMacchina, string CodArticolo, bool OnlyActive, bool OnlyMod, string SearchVal)
{
return Task.FromResult(dbController.FileGetFilt(IdxMacchina, CodArticolo, OnlyActive, OnlyMod, SearchVal).ToList());
}
public Task<List<MP.FileData.DatabaseModels.MacchinaModel>> MacchineGetAll()
+6 -1
View File
@@ -13,6 +13,8 @@ namespace MP.Prog.Data
public DateTime DateEnd { get; set; } = DateTime.Now.AddMinutes(1);
public DateTime DateStart { get; set; } = DateTime.Now.AddDays(-7);
public string IdxMacchina { get; set; } = "";
public bool OnlyActive { get; set; } = true;
public bool OnlyMod { get; set; } = false;
#endregion Public Properties
@@ -41,7 +43,10 @@ namespace MP.Prog.Data
{
if (!(obj is SelectData item))
return false;
if (OnlyActive != item.OnlyActive)
return false;
if (OnlyMod != item.OnlyMod)
return false;
if (CodArticolo != item.CodArticolo)
return false;
if (IdxMacchina != item.IdxMacchina)
+1
View File
@@ -13,6 +13,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DiffMatchPatch" Version="1.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+55 -55
View File
@@ -15,7 +15,27 @@
</button>
</div>
</div>
<div class="col-4">
<div class="col-2">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="togAttivi" title="Solo Attivi / Mostra tutti" @bind-value="@OnlyActive" checked="@OnlyActive" />
<label class="custom-control-label small" for="togAttivi"><sub>Attivi</sub></label>
</div>
</div>
</div>
<div class="col-2">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="togModificati" title="Solo Aperti / Mostra tutti" @bind-value="@OnlyMod" checked="@OnlyMod" />
<label class="custom-control-label small" for="togModificati"><sub>Modifiche</sub></label>
</div>
</div>
</div>
<div class="col-6">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
@@ -33,28 +53,6 @@
</select>
</div>
</div>
<div class="col-6">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<span class="fas fa-search" aria-hidden="true"></span>
</span>
</div>
<input type="text" class="form-control form-control-sm" placeholder="Ricerca Articolo" @bind-value="@SearchArt" width="4em" />
<select @bind="@SelCodArt" class="form-control form-control-sm">
@if (ArtList != null)
{
foreach (var item in ArtList)
{
<option value="@item.CodArticolo">@item.Disegno | @item.DescArticolo</option>
}
}
</select>
<div class="input-group-append">
<button id="searchReset" class="btn btn-sm btn-secondary" @onclick="() => ResetSearchArt()" title="Reset ricerca articolo"><i class="fas fa-ban"></i></button>
</div>
</div>
</div>
<div class="col-1">
<div class="form-group mb-0">
<button id="btnReset" class="btn btn-info btn-sm btn-block" @onclick="() => ResetFilter()" title="Reset Filter"><span class="oi oi-loop-circular"></span></button>
@@ -67,12 +65,12 @@
<div class="card-body p-1">
@if (currRecord != null)
{
<p> mostrare dettaglio: diff? comando accetta/annulla?</p>
@*<OrderAdminEditor currItem="@currRecord" DataReset="ResetData" DataUpdated="UpdateData" SupplierId="@currRecord.SupplierId"></OrderAdminEditor>*@
<MP.Prog.Components.FileEditor currItem="@currRecord" DataReset="ResetData" DataUpdated="UpdateData" ArtList="@ArtList" MacList="@MacList"></MP.Prog.Components.FileEditor>
}
@if (ListRecords == null)
{
<LoadingData></LoadingData>
<MP.Prog.Components.LoadingData></MP.Prog.Components.LoadingData>
<d2>RELOADING</d2>
}
else if (totalCount == 0)
{
@@ -86,18 +84,14 @@
<thead>
<tr>
<th></th>
<th>Macchina</th>
<th>Articolo</th>
<th>File</th>
<th>Rev</th>
<th>Size</th>
<th>Modifica</th>
<th>Controllo</th>
<th>OK</th>
@*<th class="text-right">Fornitore</th>
<th class="text-right">Richiesta</th>
<th class="text-right">Carico</th>
<th class="text-right">Effettivo</th>*@
<th class="text-center">State</th>
<th>Macchina</th>
<th>Articolo</th>
<th class="text-right">Modificato</th>
@*<th>Controllo</th>*@
</tr>
</thead>
<tbody>
@@ -105,10 +99,9 @@
{
<tr class="@checkSelect(record.FileId)">
<td class="text-nowrap">
@if (currRecord == null)
@if (currRecord == null && record.Active)
{
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)">
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)" title="Edit record #@record.FileId">
<i class="oi oi-pencil"></i>
</button>
}
@@ -118,7 +111,25 @@
<i class="oi oi-pencil"></i>
</button>
}
<div class="small">[@record.FileId]</div>
</td>
<td>
<div class="@(cssActive(record.Active))">
<div>@record.Name</div>
<div class="small">@record.Path</div>
</div>
</td>
<td>
<div>@record.Rev</div>
</td>
<td>
<div>@((((double)record.Size)/1024).ToString("N2")) k</div>
</td>
<td class="text-center">
<span title="@record.DiskStatus | Ultimo controllo: @record.LastCheck.ToString("yyyy.MM.dd HH:mm:ss")">
<span class="@(cssStatusByCod(record.DiskStatus))">
@record.DiskStatus
</span>
</span>
</td>
<td>
<div>@record.Macchina.CodMacchina</div>
@@ -128,25 +139,14 @@
<div>@record.Articolo.Disegno</div>
<div class="small">@record.Articolo.DescArticolo</div>
</td>
<td>
<div>@record.Name</div>
<div class="small">@record.Path</div>
</td>
<td>
<div>@record.Rev</div>
</td>
<td>
<div>@((double)record.Size)/1024</div>
</td>
<td>
<td class="text-right">
<div>@record.LastMod.ToString("yyyy.MM.dd")</div>
<div class="small">@record.LastMod.ToString("ddd HH:mm.ss")</div>
</td>
<td>
<div>@record.LastCheck.ToString("yyyy.MM.dd")</div>
<div class="small">@record.LastCheck.ToString("ddd HH:mm.ss")</div>
</td>
<td>@record.Changed</td>
@*<td>
<div>@record.LastCheck.ToString("yyyy.MM.dd")</div>
<div class="small">@record.LastCheck.ToString("ddd HH:mm.ss")</div>
</td>*@
</tr>
}
</tbody>
+94 -10
View File
@@ -14,6 +14,7 @@ namespace MP.Prog.Pages
#region Private Fields
private List<ArticoloModel> ArtList;
private FileModel currRecord = null;
private List<FileModel> ListRecords;
private List<MacchinaModel> MacList;
@@ -23,7 +24,9 @@ namespace MP.Prog.Pages
#region Protected Fields
protected string _SearchArt = "###";
protected string _SearchArt;
protected string defCodArt = "";
#endregion Protected Fields
@@ -63,6 +66,50 @@ namespace MP.Prog.Pages
}
}
private bool OnlyActive
{
get
{
bool answ = false;
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.OnlyActive;
}
return answ;
}
set
{
if (!AppMService.File_Filter.OnlyActive.Equals(value))
{
AppMService.File_Filter.OnlyActive = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private bool OnlyMod
{
get
{
bool answ = false;
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.OnlyMod;
}
return answ;
}
set
{
if (!AppMService.File_Filter.OnlyMod.Equals(value))
{
AppMService.File_Filter.OnlyMod = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private string SelCodArt
{
get
@@ -136,9 +183,9 @@ namespace MP.Prog.Pages
// se son > 3 char... debounce...
if (string.IsNullOrEmpty(value))
{
_SearchArt = "###";
_SearchArt = defCodArt;
}
if (value.Length >= 3)
if (value.Length >= defCodArt.Length)
{
var pUpd = Task.Run(async () =>
{
@@ -167,10 +214,41 @@ namespace MP.Prog.Pages
#region Private Methods
private string cssActive(bool active)
{
string answ = active ? "text-dark" : "text-secondary textStriked";
return answ;
}
private string cssStatusByCod(FileData.FileState currStatus)
{
string answ = "badge";
switch (currStatus)
{
case FileData.FileState.Changed:
answ += " badge-warning";
break;
case FileData.FileState.Deleted:
answ += " badge-danger";
break;
case FileData.FileState.Ok:
answ += " badge-success";
break;
case FileData.FileState.ND:
default:
answ += " badge-light";
break;
}
return answ;
}
private async Task ReloadData()
{
isLoading = true;
SearchRecords = await DataService.FileGetFilt(AppMService.File_Filter.IdxMacchina, AppMService.File_Filter.CodArticolo, AppMService.SearchVal);
SearchRecords = await DataService.FileGetFilt(AppMService.File_Filter.IdxMacchina, AppMService.File_Filter.CodArticolo, AppMService.File_Filter.OnlyActive, AppMService.File_Filter.OnlyMod, AppMService.SearchVal);
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
@@ -181,11 +259,9 @@ namespace MP.Prog.Pages
protected void Edit(FileModel selRecord)
{
#if false
// rileggo dal DB il record corrente...
var pUpd = Task.Run(async () => currRecord = await DataService.OrderGetByCode(selRecord.OrderCode));
var pUpd = Task.Run(async () => currRecord = await DataService.FileGetByKey(selRecord.FileId));
pUpd.Wait();
#endif
}
protected async Task ForceCheck()
@@ -213,6 +289,7 @@ namespace MP.Prog.Pages
protected override async Task OnInitializedAsync()
{
DataService.ResetController();
SearchArt = defCodArt;
AppMService.ShowSearch = false;
AppMService.PageName = "Archivio File Programmi";
AppMService.PageIcon = "fas fa-folder pr-2";
@@ -225,8 +302,10 @@ namespace MP.Prog.Pages
isLoading = true;
MacList = await DataService.MacchineGetAll();
SelIdxMacc = "0";
SearchArt = defCodArt;
ArtList = await DataService.ArticoliGetFilt(SearchArt);
SelCodArt = "###";
isLoading = false;
await ReloadData();
}
@@ -243,13 +322,18 @@ namespace MP.Prog.Pages
SearchRecords = null;
ListRecords = null;
AppMService.File_Filter = SelectData.Init(5, 10);
SearchArt = "###";
SearchArt = defCodArt;
await ReloadAllData();
}
protected void ResetSearchArt()
{
SearchArt = "###";
SearchArt = defCodArt;
}
protected void searchArtUpd(string newCod)
{
SelCodArt = newCod;
}
protected void Select(FileModel selRecord)
+52
View File
@@ -0,0 +1,52 @@
@page "/Setup"
@using MP.Prog.Data
@using System.Text
@using DiffMatchPatch
@inject MessageService AppMService
<h3>Setup</h3>
<div class="row">
<div class="col-6">
<textarea @bind="@oldText" cols="50" rows="30" />
</div>
<div class="col-6">
<textarea @bind="@newText" cols="50" rows="30" />
</div>
<div class="col-12">
<MP.Prog.Components.DiffView oldText="@oldText" newText="@newText"></MP.Prog.Components.DiffView>
</div>
</div>
@code {
protected string _oldText = "Prova primo testo";
protected string _newText = "Prova secondo testo";
protected string oldText
{
get
{
return _oldText;
}
set
{
_oldText = value;
}
}
protected string newText
{
get
{
return _newText;
}
set
{
_newText = value;
}
}
}
+5
View File
@@ -17,6 +17,11 @@
<span class="far fa-folder fa-2x pr-2" aria-hidden="true"></span> Archivio File
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Setup">
<span class="fas fa-wrench fa-2x pr-2" aria-hidden="true"></span> Setup
</NavLink>
</li>
</ul>
</div>
+3
View File
@@ -40,6 +40,9 @@ a,
.validation-message {
color: red;
}
.textStriked {
text-decoration: line-through;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
+4
View File
@@ -36,6 +36,10 @@ a, .btn-link {
color: red;
}
.textStriked {
text-decoration: line-through;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
+1 -1
View File
@@ -1 +1 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');@import url('fonts.min.css');h1,h2,h3,h4,h5,h6,b,display-1,display-2,display-3,display-4{font-family:'Lato',sans-serif;}html,body,.textCondensed{font-family:'Roboto Condensed',sans-serif;}a,.btn-link{color:#0366d6;}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac;}.content{padding-top:1.1rem;}.valid.modified:not([type=checkbox]){outline:1px solid #26b050;}.invalid{outline:1px solid #f00;}.validation-message{color:#f00;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.footer{line-height:1.8em;}.shortcuts{text-align:center;}.shortcuts .shortcut-icon{font-size:2rem;}.shortcuts .shortcut{min-width:9rem;min-height:5rem;display:inline-block;padding:.66666667rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut-sm{min-width:4.5rem;min-height:3rem;display:inline-block;padding:.25rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut-sm .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut-sm:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut-sm:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut:hover .shortcut-icon{color:#c93;}.shortcuts .shortcut-sm:hover .shortcut-icon{color:#666;}.shortcuts .shortcut-label{display:block;margin-top:.75em;font-weight:400;color:#666;}@media(max-width:640px){.shortcuts .shortcut{min-width:8rem;min-height:4rem;}body{font-size:.8em;}}
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');@import url('fonts.min.css');h1,h2,h3,h4,h5,h6,b,display-1,display-2,display-3,display-4{font-family:'Lato',sans-serif}html,body,.textCondensed{font-family:'Roboto Condensed',sans-serif}a,.btn-link{color:#0366d6}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac}.content{padding-top:1.1rem}.valid.modified:not([type=checkbox]){outline:1px solid #26b050}.invalid{outline:1px solid #f00}.validation-message{color:#f00}.textStriked{text-decoration:line-through}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem}.footer{line-height:1.8em}.shortcuts{text-align:center}.shortcuts .shortcut-icon{font-size:2rem}.shortcuts .shortcut{min-width:9rem;min-height:5rem;display:inline-block;padding:.66666667rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem}.shortcuts .shortcut-sm{min-width:4.5rem;min-height:3rem;display:inline-block;padding:.25rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem}.shortcuts .shortcut .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333}.shortcuts .shortcut-sm .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333}.shortcuts .shortcut:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0)}.shortcuts .shortcut-sm:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0)}.shortcuts .shortcut:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.shortcuts .shortcut-sm:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.shortcuts .shortcut:hover .shortcut-icon{color:#c93}.shortcuts .shortcut-sm:hover .shortcut-icon{color:#666}.shortcuts .shortcut-label{display:block;margin-top:.75em;font-weight:400;color:#666}@media(max-width:640px){.shortcuts .shortcut{min-width:8rem;min-height:4rem}body{font-size:.8em}}
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>MP.Stats</RootNamespace>
<UserSecretsId>826e877c-ba70-4253-84cb-d0b1cafd4440</UserSecretsId>
<Version>1.0.2109.0316</Version>
<Version>1.0.2109.0318</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo statistiche MAPO</i>
<h4>Versione: 1.0.2109.0316</h4>
<h4>Versione: 1.0.2109.0318</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
1.0.2109.0316
1.0.2109.0318
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.0.2109.0316</version>
<version>1.0.2109.0318</version>
<url>http://nexus.steamware.net/repository/SWS/MP-STATS/stable/0/MP.Stats.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP-STATS/stable/0/ChangeLog.html</changelog>
<mandatory>false</mandatory>