mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Add details page for uploaded reports with navigation and merging functionality
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Aaru.Server.Database.Models;
|
|||||||
|
|
||||||
public class UploadedReportDetails
|
public class UploadedReportDetails
|
||||||
{
|
{
|
||||||
public UploadedReport Report { get; set; }
|
public UploadedReport? Report { get; set; }
|
||||||
public List<int> SameAll { get; set; }
|
public List<int> SameAll { get; set; }
|
||||||
public List<int> SameButManufacturer { get; set; }
|
public List<int> SameButManufacturer { get; set; }
|
||||||
public List<int> ReportAll { get; set; }
|
public List<int> ReportAll { get; set; }
|
||||||
|
|||||||
345
Aaru.Server/Components/Admin/Pages/Reports/Details.razor
Normal file
345
Aaru.Server/Components/Admin/Pages/Reports/Details.razor
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
@page "/admin/reports/{id:int}"
|
||||||
|
@attribute [Authorize]
|
||||||
|
@layout AdminLayout
|
||||||
|
|
||||||
|
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<DbContext> DbContextFactory
|
||||||
|
|
||||||
|
<PageTitle>Uploaded report</PageTitle>
|
||||||
|
|
||||||
|
@if(!_initialized)
|
||||||
|
{
|
||||||
|
<div class="stats-section">
|
||||||
|
<h1 style="color: red; align-content: center; padding: 2rem">Loading...</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
<section class="stats-section">
|
||||||
|
<div>
|
||||||
|
<h4>Uploaded report</h4>
|
||||||
|
<hr />
|
||||||
|
<dl class="row">
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.UploadedWhen))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.UploadedWhen
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.Manufacturer))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.Manufacturer
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.Model))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.Model
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.Revision))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.Revision
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.CompactFlash))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.CompactFlash
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-2">
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(UploadedReport), nameof(UploadedReport.Type))
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-10">
|
||||||
|
@_model.Report?.Type
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="/admin/reports/edit/@_model.Report?.Id" class="btn btn-secondary btn-sm">
|
||||||
|
<i class="bi bi-pencil"></i> Edit
|
||||||
|
</a>
|
||||||
|
<a @onclick="Promote" class="btn btn-secondary btn-sm">
|
||||||
|
<i class="bi bi-arrow-up-circle"></i> Promote
|
||||||
|
</a>
|
||||||
|
<a href="/admin/reports" class="btn btn-secondary btn-sm">
|
||||||
|
<i class="bi bi-arrow-left-circle"></i> Back to List
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@if(_model.ReadCapabilitiesId != 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/tested-media/@_model.ReadCapabilitiesId" target="_blank">Read capabilities</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.ATA != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/ata/@_model.Report.ATA.Id" target="_blank">ATA report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.ATAPI != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/ata/@_model.Report.ATAPI.Id" target="_blank">ATAPI report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.SCSI != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/scsi/@_model.Report.SCSI.Id" target="_blank">SCSI report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.MultiMediaCard != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/mmc-sd/@_model.Report.MultiMediaCard.Id" target="_blank">MultiMediaCard report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.SecureDigital != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/mmc-sd/@_model.Report.SecureDigital.Id" target="_blank">SecureDigital report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.USB != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/usb/devices/@_model.Report.USB.Id" target="_blank">USB report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.GdRomSwapDiscCapabilitiesId != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<a href="/admin/gdrom/@_model.Report.GdRomSwapDiscCapabilitiesId" target="_blank">GD-ROM swap-trick
|
||||||
|
capabilities report</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.FireWire != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
Has a FireWire report.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.Report?.PCMCIA != null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
Has a PCMCIA report.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.SameAll.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Other uploaded reports with same manufacturer, model and revision:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Id
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(int item in _model.SameAll)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/reports/@item"
|
||||||
|
class="btn btn-primary"
|
||||||
|
target="_blank">Details</a>
|
||||||
|
<a @onclick="() => Merge(_model.Report?.Id, item)"
|
||||||
|
class="btn btn-secondary">Merge</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.SameButManufacturer.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Other uploaded reports with same model and revision:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Id
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(int item in _model.SameButManufacturer)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/reports/@item"
|
||||||
|
class="btn btn-primary"
|
||||||
|
target="_blank">Details</a>
|
||||||
|
<a @onclick="() => Merge(_model.Report?.Id, item)"
|
||||||
|
class="btn btn-secondary">Merge</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.ReportAll.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Device reports with same manufacturer, model and revision:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Id
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(int item in _model.ReportAll)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/devices/@item"
|
||||||
|
class="btn btn-primary"
|
||||||
|
target="_blank">Details</a>
|
||||||
|
<a @onclick="() => MergeReports(item, _model.Report?.Id)"
|
||||||
|
class="btn btn-secondary">Merge</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.ReportButManufacturer.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Device reports with same model and revision:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Id
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(int item in _model.ReportButManufacturer)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/devices/@item"
|
||||||
|
class="btn btn-primary"
|
||||||
|
target="_blank">Details</a>
|
||||||
|
<a @onclick="() => MergeReports(item, _model.Report?.Id)"
|
||||||
|
class="btn btn-secondary">Merge</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.TestedMedias.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Tested media:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedMedia), nameof(TestedMedia.Manufacturer))
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedMedia), nameof(TestedMedia.Model))
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedMedia), nameof(TestedMedia.MediumTypeName))
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(TestedMedia item in _model.TestedMedias)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item.Manufacturer
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@item.Model
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@item.MediumTypeName
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/admin/tested-media/@item.Id"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
target="_blank">Details</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(_model.TestedSequentialMedias.Count > 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<h4>Tested media:</h4>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedSequentialMedia), nameof(TestedSequentialMedia.Manufacturer))
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedSequentialMedia), nameof(TestedSequentialMedia.Model))
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@DisplayNameHelper.GetDisplayName(typeof(TestedSequentialMedia), nameof(TestedSequentialMedia.MediumTypeName))
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach(TestedSequentialMedia item in _model.TestedSequentialMedias)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@item.Manufacturer
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@item.Model
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@item.MediumTypeName
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</section>
|
||||||
356
Aaru.Server/Components/Admin/Pages/Reports/Details.razor.cs
Normal file
356
Aaru.Server/Components/Admin/Pages/Reports/Details.razor.cs
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
using Aaru.CommonTypes.Metadata;
|
||||||
|
using Aaru.Server.Database.Models;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
|
using DbContext = Aaru.Server.Database.DbContext;
|
||||||
|
|
||||||
|
namespace Aaru.Server.Components.Admin.Pages.Reports;
|
||||||
|
|
||||||
|
public partial class Details
|
||||||
|
{
|
||||||
|
bool _initialized;
|
||||||
|
UploadedReportDetails _model;
|
||||||
|
[Parameter]
|
||||||
|
public int Id { get; set; }
|
||||||
|
[Inject]
|
||||||
|
NavigationManager Navigator { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
|
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
_model = new UploadedReportDetails
|
||||||
|
{
|
||||||
|
Report = await ctx.Reports.Include(static deviceReport => deviceReport.ATAPI)
|
||||||
|
.Include(static deviceReport => deviceReport.ATA)
|
||||||
|
.ThenInclude(static ata => ata.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.MultiMediaDevice)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.SequentialDevice)
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == Id)
|
||||||
|
};
|
||||||
|
|
||||||
|
if(_model.Report is null) return;
|
||||||
|
|
||||||
|
_model.ReportAll = await ctx.Devices
|
||||||
|
.Where(d => d.Manufacturer == _model.Report.Manufacturer &&
|
||||||
|
d.Model == _model.Report.Model &&
|
||||||
|
d.Revision == _model.Report.Revision)
|
||||||
|
.Select(static d => d.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_model.ReportButManufacturer = await ctx.Devices
|
||||||
|
.Where(d => d.Model == _model.Report.Model &&
|
||||||
|
d.Revision == _model.Report.Revision)
|
||||||
|
.Select(static d => d.Id)
|
||||||
|
.Where(d => _model.ReportAll.All(r => r != d))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_model.SameAll = await ctx.Reports
|
||||||
|
.Where(d => d.Manufacturer == _model.Report.Manufacturer &&
|
||||||
|
d.Model == _model.Report.Model &&
|
||||||
|
d.Revision == _model.Report.Revision &&
|
||||||
|
d.Id != Id)
|
||||||
|
.Select(static d => d.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_model.SameButManufacturer = await ctx.Reports
|
||||||
|
.Where(d => d.Model == _model.Report.Model &&
|
||||||
|
d.Revision == _model.Report.Revision &&
|
||||||
|
d.Id != Id)
|
||||||
|
.Select(static d => d.Id)
|
||||||
|
.Where(d => _model.SameAll.All(r => r != d))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_model.ReadCapabilitiesId =
|
||||||
|
_model.Report.ATA?.ReadCapabilities?.Id ?? _model.Report.SCSI?.ReadCapabilities?.Id ?? 0;
|
||||||
|
|
||||||
|
// So we can check, as we know IDs with 0 will never exist, and EFCore does not allow null propagation in the LINQ
|
||||||
|
int ataId = _model.Report.ATA?.Id ?? 0;
|
||||||
|
int atapiId = _model.Report.ATAPI?.Id ?? 0;
|
||||||
|
int scsiId = _model.Report.SCSI?.Id ?? 0;
|
||||||
|
int mmcId = _model.Report.SCSI?.MultiMediaDevice?.Id ?? 0;
|
||||||
|
int sscId = _model.Report.SCSI?.SequentialDevice?.Id ?? 0;
|
||||||
|
|
||||||
|
_model.TestedMedias = await ctx.TestedMedia
|
||||||
|
.Where(t => t.AtaId == ataId ||
|
||||||
|
t.AtaId == atapiId ||
|
||||||
|
t.ScsiId == scsiId ||
|
||||||
|
t.MmcId == mmcId)
|
||||||
|
.OrderBy(static t => t.Manufacturer)
|
||||||
|
.ThenBy(static t => t.Model)
|
||||||
|
.ThenBy(static t => t.MediumTypeName)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_model.TestedSequentialMedias = await ctx.TestedSequentialMedia.Where(t => t.SscId == sscId)
|
||||||
|
.OrderBy(static t => t.Manufacturer)
|
||||||
|
.ThenBy(static t => t.Model)
|
||||||
|
.ThenBy(static t => t.MediumTypeName)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async Task Promote()
|
||||||
|
{
|
||||||
|
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
UploadedReport? uploadedReport = await ctx.Reports.FirstOrDefaultAsync(m => m.Id == Id);
|
||||||
|
|
||||||
|
if(uploadedReport == null) return;
|
||||||
|
|
||||||
|
var device = new Device(uploadedReport.ATAId,
|
||||||
|
uploadedReport.ATAPIId,
|
||||||
|
uploadedReport.FireWireId,
|
||||||
|
uploadedReport.MultiMediaCardId,
|
||||||
|
uploadedReport.PCMCIAId,
|
||||||
|
uploadedReport.SecureDigitalId,
|
||||||
|
uploadedReport.SCSIId,
|
||||||
|
uploadedReport.USBId,
|
||||||
|
uploadedReport.UploadedWhen,
|
||||||
|
uploadedReport.Manufacturer,
|
||||||
|
uploadedReport.Model,
|
||||||
|
uploadedReport.Revision,
|
||||||
|
uploadedReport.CompactFlash,
|
||||||
|
uploadedReport.Type,
|
||||||
|
uploadedReport.GdRomSwapDiscCapabilitiesId);
|
||||||
|
|
||||||
|
EntityEntry<Device> res = ctx.Devices.Add(device);
|
||||||
|
ctx.Reports.Remove(uploadedReport);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
Navigator.NavigateTo($"/admin/devices/{res.Entity.Id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task Merge(int? master, int? slave)
|
||||||
|
{
|
||||||
|
if(master is null || slave is null) return;
|
||||||
|
|
||||||
|
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
UploadedReport? masterReport = await ctx.Reports.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == master);
|
||||||
|
|
||||||
|
UploadedReport? slaveReport = await ctx.Reports.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == slave);
|
||||||
|
|
||||||
|
if(masterReport is null || slaveReport is null) return;
|
||||||
|
|
||||||
|
if(masterReport.ATAId != null && masterReport.ATAId != slaveReport.ATAId)
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in
|
||||||
|
ctx.TestedMedia.Where(d => d.AtaId == slaveReport.ATAId))
|
||||||
|
{
|
||||||
|
testedMedia.AtaId = masterReport.ATAId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(masterReport.ATAId == null && slaveReport.ATAId != null)
|
||||||
|
{
|
||||||
|
masterReport.ATAId = slaveReport.ATAId;
|
||||||
|
ctx.Update(masterReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(masterReport.ATAPIId != null && masterReport.ATAPIId != slaveReport.ATAPIId)
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in
|
||||||
|
ctx.TestedMedia.Where(d => d.AtaId == slaveReport.ATAPIId))
|
||||||
|
{
|
||||||
|
testedMedia.AtaId = masterReport.ATAPIId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(masterReport.ATAPIId == null && slaveReport.ATAPIId != null)
|
||||||
|
{
|
||||||
|
masterReport.ATAPIId = slaveReport.ATAPIId;
|
||||||
|
ctx.Update(masterReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(masterReport.SCSIId != null && masterReport.SCSIId != slaveReport.SCSIId)
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in
|
||||||
|
ctx.TestedMedia.Where(d => d.ScsiId == slaveReport.SCSIId))
|
||||||
|
{
|
||||||
|
testedMedia.ScsiId = masterReport.SCSIId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(masterReport.SCSIId == null && slaveReport.SCSIId != null)
|
||||||
|
{
|
||||||
|
masterReport.SCSIId = slaveReport.SCSIId;
|
||||||
|
ctx.Update(masterReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(masterReport.SCSI?.SequentialDeviceId != null &&
|
||||||
|
masterReport.SCSI?.SequentialDeviceId != slaveReport.SCSI?.SequentialDeviceId)
|
||||||
|
{
|
||||||
|
foreach(TestedSequentialMedia testedMedia in
|
||||||
|
ctx.TestedSequentialMedia.Where(d => slaveReport.SCSI != null &&
|
||||||
|
d.SscId == slaveReport.SCSI.SequentialDeviceId))
|
||||||
|
{
|
||||||
|
if(masterReport.SCSI != null) testedMedia.SscId = masterReport.SCSI.SequentialDeviceId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(masterReport.SCSI is { SequentialDeviceId: null } && slaveReport.SCSI?.SequentialDeviceId != null)
|
||||||
|
{
|
||||||
|
if(masterReport.SCSI != null) masterReport.SCSI.SequentialDeviceId = slaveReport.SCSI.SequentialDeviceId;
|
||||||
|
ctx.Update(masterReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(masterReport.GdRomSwapDiscCapabilitiesId == null && slaveReport.GdRomSwapDiscCapabilitiesId != null ||
|
||||||
|
masterReport.GdRomSwapDiscCapabilitiesId != null && slaveReport.GdRomSwapDiscCapabilitiesId != null)
|
||||||
|
{
|
||||||
|
masterReport.GdRomSwapDiscCapabilitiesId = slaveReport.GdRomSwapDiscCapabilitiesId;
|
||||||
|
ctx.Update(masterReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Remove(slaveReport);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
Navigator.Refresh(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task MergeReports(int? deviceId, int? reportId)
|
||||||
|
{
|
||||||
|
if(deviceId is null || reportId is null) return;
|
||||||
|
|
||||||
|
await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
Device? device = await ctx.Devices.Include(static deviceReport => deviceReport.ATA)
|
||||||
|
.ThenInclude(static ata => ata.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.MultiMediaDevice)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.SequentialDevice)
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == deviceId);
|
||||||
|
|
||||||
|
UploadedReport? report = await ctx.Reports.Include(static deviceReport => deviceReport.ATA)
|
||||||
|
.ThenInclude(static ata => ata.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.ReadCapabilities)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.MultiMediaDevice)
|
||||||
|
.Include(static deviceReport => deviceReport.SCSI)
|
||||||
|
.ThenInclude(static scsi => scsi.SequentialDevice)
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == reportId);
|
||||||
|
|
||||||
|
if(device?.ATAId != null && device.ATAId != report?.ATAId)
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in
|
||||||
|
ctx.TestedMedia.Where(d => report != null && d.AtaId == report.ATAId))
|
||||||
|
{
|
||||||
|
testedMedia.AtaId = device.ATAId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.ATA is { ReadCapabilities: null } && report?.ATA?.ReadCapabilities != null)
|
||||||
|
{
|
||||||
|
device.ATA.ReadCapabilities = report.ATA.ReadCapabilities;
|
||||||
|
ctx.Update(device.ATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(device?.ATAId == null && report?.ATAId != null)
|
||||||
|
{
|
||||||
|
if(device != null)
|
||||||
|
{
|
||||||
|
device.ATAId = report.ATAId;
|
||||||
|
ctx.Update(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(device)
|
||||||
|
{
|
||||||
|
case { ATAPIId: not null } when device.ATAPIId != report?.ATAPIId:
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in
|
||||||
|
ctx.TestedMedia.Where(d => report != null && d.AtaId == report.ATAPIId))
|
||||||
|
{
|
||||||
|
testedMedia.AtaId = device.ATAPIId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case { ATAPIId: null } when report?.ATAPIId != null:
|
||||||
|
device.ATAPIId = report.ATAPIId;
|
||||||
|
ctx.Update(device);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(device)
|
||||||
|
{
|
||||||
|
case { SCSIId: not null } when device.SCSIId != report?.SCSIId:
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in ctx.TestedMedia.Where(d => report != null &&
|
||||||
|
d.ScsiId == report.SCSIId))
|
||||||
|
{
|
||||||
|
testedMedia.ScsiId = device.SCSIId;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.SCSI is { ReadCapabilities: null } && report?.SCSI?.ReadCapabilities != null)
|
||||||
|
{
|
||||||
|
device.SCSI.ReadCapabilities = report.SCSI.ReadCapabilities;
|
||||||
|
ctx.Update(device.SCSI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.SCSI is { MultiMediaDevice: null } && report?.SCSI?.MultiMediaDevice != null)
|
||||||
|
{
|
||||||
|
device.SCSI.MultiMediaDevice = report.SCSI.MultiMediaDevice;
|
||||||
|
ctx.Update(device.SCSI);
|
||||||
|
}
|
||||||
|
else if(device.SCSI?.MultiMediaDevice != null && report?.SCSI?.MultiMediaDevice != null)
|
||||||
|
{
|
||||||
|
foreach(CommonTypes.Metadata.TestedMedia testedMedia in ctx.TestedMedia.Where(d => d.MmcId ==
|
||||||
|
report.SCSI.MultiMediaDevice.Id))
|
||||||
|
{
|
||||||
|
testedMedia.MmcId = device.SCSI.MultiMediaDevice.Id;
|
||||||
|
ctx.Update(testedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.SCSI is { SequentialDevice: null } && report?.SCSI?.SequentialDevice != null)
|
||||||
|
{
|
||||||
|
device.SCSI.SequentialDevice = report.SCSI.SequentialDevice;
|
||||||
|
ctx.Update(device.SCSI);
|
||||||
|
}
|
||||||
|
else if(device.SCSI?.SequentialDevice != null && report?.SCSI?.SequentialDevice != null)
|
||||||
|
{
|
||||||
|
foreach(TestedSequentialMedia testedSequentialMedia in
|
||||||
|
ctx.TestedSequentialMedia.Where(d => d.SscId == report.SCSI.SequentialDevice.Id))
|
||||||
|
{
|
||||||
|
testedSequentialMedia.SscId = device.SCSI.SequentialDevice.Id;
|
||||||
|
ctx.Update(testedSequentialMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case { SCSIId: null } when report?.SCSIId != null:
|
||||||
|
device.SCSIId = report.SCSIId;
|
||||||
|
ctx.Update(device);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Remove(report);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
Navigator.Refresh(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user