diff --git a/Aaru.Server/Components/Admin/AdminNavMenu.razor b/Aaru.Server/Components/Admin/AdminNavMenu.razor index da0e9d29..a2c282a1 100644 --- a/Aaru.Server/Components/Admin/AdminNavMenu.razor +++ b/Aaru.Server/Components/Admin/AdminNavMenu.razor @@ -53,6 +53,9 @@ SCSI MODE SENSE responses + + SCSI SSC + Supported densities diff --git a/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor b/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor new file mode 100644 index 00000000..70bbc691 --- /dev/null +++ b/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor @@ -0,0 +1,106 @@ +@page "/admin/scsi/ssc" +@attribute [Authorize] +@layout AdminLayout + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +SCSI SSC + +@if(!_initialized) +{ +
+

Loading...

+
+ + return; +} + +
+

SCSI SSC

+ + + + + + + + + + + @foreach(Ssc item in _items) + { + + + + + + + } + +
+ @DisplayNameHelper.GetDisplayName(typeof(Ssc), nameof(Ssc.MinBlockLength)) + + @DisplayNameHelper.GetDisplayName(typeof(Ssc), nameof(Ssc.MaxBlockLength)) + + @DisplayNameHelper.GetDisplayName(typeof(Ssc), nameof(Ssc.BlockSizeGranularity)) + + Actions +
+ @item.MinBlockLength + + @item.MaxBlockLength + + @item.BlockSizeGranularity + + +
+ + @if(_duplicates.Count > 0) + { +
+ The following SSC have duplicates. + + + @foreach(SscModel item in _duplicates) + { + + + + + + } + +
+ @item.MinBlockLength + + @item.MaxBlockLength + + @item.BlockSizeGranularity +
+
+ + + } +
+ + + +
Are you sure you want to delete the duplicates?
+
+ + + + +
+ + + +
Are you sure you want to delete this SSC?
+
+ + + + +
\ No newline at end of file diff --git a/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor.cs b/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor.cs new file mode 100644 index 00000000..74795435 --- /dev/null +++ b/Aaru.Server/Components/Admin/Pages/Scsi/Ssc/View.razor.cs @@ -0,0 +1,127 @@ +using Aaru.CommonTypes.Metadata; +using Aaru.Server.Database.Models; +using BlazorBootstrap; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.Components.Admin.Pages.Scsi.Ssc; + +public partial class View +{ + private Modal? _consolidateModal; + private int _deleteId; + private Modal? _deleteModal; + List _duplicates; + bool _initialized; + List _items; + + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + StateHasChanged(); + + await RefreshItemsAsync(); + + _initialized = true; + + StateHasChanged(); + } + + async Task RefreshItemsAsync() + { + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + _items = await ctx.Ssc.OrderBy(static s => s.MinBlockLength) + .ThenBy(static s => s.MaxBlockLength) + .ThenBy(static s => s.BlockSizeGranularity) + .ToListAsync(); + + _duplicates = await ctx.Ssc.GroupBy(static x => new + { + x.BlockSizeGranularity, + x.MaxBlockLength, + x.MinBlockLength + }) + .Where(static x => x.Count() > 1) + .Select(static x => new SscModel + { + BlockSizeGranularity = x.Key.BlockSizeGranularity, + MaxBlockLength = x.Key.MaxBlockLength, + MinBlockLength = x.Key.MinBlockLength + }) + .ToListAsync(); + } + + Task ConsolidateDuplicatesAsync() => _consolidateModal?.ShowAsync(); + + Task HideConsolidateModalAsync() => _consolidateModal?.HideAsync(); + + async Task ConfirmConsolidateAsync() + { + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + foreach(SscModel duplicate in _duplicates) + { + CommonTypes.Metadata.Ssc? master = + ctx.Ssc.FirstOrDefault(m => m.BlockSizeGranularity == duplicate.BlockSizeGranularity && + m.MaxBlockLength == duplicate.MaxBlockLength && + m.MinBlockLength == duplicate.MinBlockLength); + + if(master is null) continue; + + foreach(CommonTypes.Metadata.Ssc ssc in await ctx.Ssc + .Where(m => m.BlockSizeGranularity == + duplicate.BlockSizeGranularity && + m.MaxBlockLength == duplicate.MaxBlockLength && + m.MinBlockLength == duplicate.MinBlockLength) + .Skip(1) + .ToArrayAsync()) + { + foreach(TestedSequentialMedia media in ctx.TestedSequentialMedia.Where(d => d.SscId == ssc.Id)) + media.SscId = master.Id; + + ctx.Ssc.Update(ssc); + ctx.Ssc.Remove(ssc); + } + } + + await ctx.SaveChangesAsync(); + + await RefreshItemsAsync(); + + StateHasChanged(); + } + + private async Task ShowDeleteModal(int id) + { + _deleteId = id; + if(_deleteModal != null) await _deleteModal.ShowAsync(); + } + + private async Task HideDeleteModal() + { + if(_deleteModal != null) await _deleteModal.HideAsync(); + } + + private async Task ConfirmDelete() + { + await DeleteAsync(_deleteId); + await HideDeleteModal(); + await RefreshItemsAsync(); + } + + private async Task DeleteAsync(int id) + { + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + CommonTypes.Metadata.Ssc? ssc = await ctx.Ssc.FindAsync(id); + + if(ssc is not null) + { + ctx.Ssc.Remove(ssc); + await ctx.SaveChangesAsync(); + } + } +} \ No newline at end of file