Got fix working for issues editing
@@ -103,8 +103,7 @@
|
|||||||
|
|
||||||
<MudGrid Justify="Justify.FlexEnd" Class="pt-6">
|
<MudGrid Justify="Justify.FlexEnd" Class="pt-6">
|
||||||
<MudItem>
|
<MudItem>
|
||||||
<MudCheckBox Label="Publicly Visible" T="bool"></MudCheckBox>
|
<MudCheckBox Label="Publicly Visible" T="bool" @bind-Value=Model.IsPublicallyVisible></MudCheckBox>
|
||||||
@*<MudCheckBox Label="Publicly Visible" T="bool" @bind-Value=Model.IsPublic></MudCheckBox>*@
|
|
||||||
</MudItem>
|
</MudItem>
|
||||||
|
|
||||||
@if (FormButtonsEnabled)
|
@if (FormButtonsEnabled)
|
||||||
|
|||||||
@@ -143,7 +143,7 @@
|
|||||||
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="pb-2">Input the text transcription of the words on the artifact if applicable to aid the search engine.</MudText>
|
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="pb-2">Input the text transcription of the words on the artifact if applicable to aid the search engine.</MudText>
|
||||||
<MudDivider DividerType="DividerType.Middle"></MudDivider>
|
<MudDivider DividerType="DividerType.Middle"></MudDivider>
|
||||||
<MudTextField T="string"
|
<MudTextField T="string"
|
||||||
Value=_artifactTextContent
|
Value=Model.FileTextContent
|
||||||
ValueChanged="OnArtifactTextContentChanged"
|
ValueChanged="OnArtifactTextContentChanged"
|
||||||
Lines="5"
|
Lines="5"
|
||||||
For="@(() => Model.FileTextContent)"></MudTextField>
|
For="@(() => Model.FileTextContent)"></MudTextField>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
Filterable=false
|
Filterable=false
|
||||||
SelectOnRowClick=true
|
SelectOnRowClick=true
|
||||||
ServerData="new Func<GridState<ArtifactGroupingRowElement>, Task<GridData<ArtifactGroupingRowElement>>>(ServerReload)"
|
ServerData="new Func<GridState<ArtifactGroupingRowElement>, Task<GridData<ArtifactGroupingRowElement>>>(ServerReload)"
|
||||||
|
@key=@ArtifactGroupingRows
|
||||||
@ref=@DataGrid>
|
@ref=@DataGrid>
|
||||||
|
|
||||||
<ToolBarContent>
|
<ToolBarContent>
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
@inject IArtifactGroupingProvider GroupingProvider;
|
@inject IArtifactGroupingProvider GroupingProvider;
|
||||||
@inject IDialogService DialogService;
|
@inject IDialogService DialogService;
|
||||||
@inject IArtifactGroupingProvider GroupingProvider;
|
@inject IArtifactGroupingProvider GroupingProvider;
|
||||||
|
@inject ArtifactEntrySharedHelpers Helpers;
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
@@ -114,7 +116,8 @@
|
|||||||
if (result is not null && !result.Canceled)
|
if (result is not null && !result.Canceled)
|
||||||
{
|
{
|
||||||
var validationModel = (ArtifactGroupingValidationModel)result.Data!;
|
var validationModel = (ArtifactGroupingValidationModel)result.Data!;
|
||||||
await GroupingProvider.UpdateGroupingAsync(validationModel.ToArtifactGrouping());
|
|
||||||
|
await Helpers.OnGroupingPublished(validationModel);
|
||||||
|
|
||||||
await DataGrid.ReloadServerData();
|
await DataGrid.ReloadServerData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ public class ArtifactEntrySharedHelpers
|
|||||||
|
|
||||||
IDbContextFactory<ApplicationDbContext> DbContextFactory { get; set; }
|
IDbContextFactory<ApplicationDbContext> DbContextFactory { get; set; }
|
||||||
|
|
||||||
|
IArtifactGroupingProvider GroupingProvider { get; set; }
|
||||||
|
|
||||||
public ArtifactEntrySharedHelpers(IArtifactDefectProvider defectsProvider, IArtifactStorageLocationProvider storageLocationProvider, IArchiveEntryTagProvider tagsProvider, IArtifactTypeProvider typesProvider, IListedNameProvider listedNamesProvider, IDbContextFactory<ApplicationDbContext> contextFactory)
|
|
||||||
|
public ArtifactEntrySharedHelpers(IArtifactDefectProvider defectsProvider, IArtifactStorageLocationProvider storageLocationProvider, IArchiveEntryTagProvider tagsProvider, IArtifactTypeProvider typesProvider, IListedNameProvider listedNamesProvider, IDbContextFactory<ApplicationDbContext> contextFactory, IArtifactGroupingProvider groupingProvider)
|
||||||
{
|
{
|
||||||
DefectsProvider = defectsProvider;
|
DefectsProvider = defectsProvider;
|
||||||
StorageLocationProvider = storageLocationProvider;
|
StorageLocationProvider = storageLocationProvider;
|
||||||
@@ -26,6 +28,7 @@ public class ArtifactEntrySharedHelpers
|
|||||||
TypesProvider = typesProvider;
|
TypesProvider = typesProvider;
|
||||||
ListedNameProvider = listedNamesProvider;
|
ListedNameProvider = listedNamesProvider;
|
||||||
DbContextFactory = contextFactory;
|
DbContextFactory = contextFactory;
|
||||||
|
GroupingProvider = groupingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<string>> SearchDefects(string value, CancellationToken cancellationToken)
|
public async Task<IEnumerable<string>> SearchDefects(string value, CancellationToken cancellationToken)
|
||||||
@@ -103,214 +106,155 @@ public class ArtifactEntrySharedHelpers
|
|||||||
return names.Select(p => p.Value);
|
return names.Select(p => p.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public async Task OnGroupingPublished(ArtifactGroupingValidationModel model)
|
public async Task OnGroupingPublished(ArtifactGroupingValidationModel model)
|
||||||
{
|
{
|
||||||
await using var context = await DbContextFactory.CreateDbContextAsync();
|
await using var context = await DbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var grouping = model.ToArtifactGrouping();
|
var grouping = model.ToArtifactGrouping();
|
||||||
|
|
||||||
// Caches to track entities processed within this transaction
|
// The old logic for attaching the category is still good.
|
||||||
var processedFilePaths = new Dictionary<string, FilePathListing>();
|
context.Attach(grouping.Category);
|
||||||
var processedLocations = new Dictionary<string, ArtifactStorageLocation>();
|
|
||||||
var processedTags = new Dictionary<string, ArtifactEntryTag>();
|
|
||||||
var processedDefects = new Dictionary<string, ArtifactDefect>();
|
|
||||||
var processedTypes = new Dictionary<string, ArtifactType>();
|
|
||||||
var processedNames = new Dictionary<string, ListedName>();
|
|
||||||
|
|
||||||
// Process File Paths for each entry first
|
// 1. Handle ArtifactType (no change, this was fine)
|
||||||
foreach (var entry in grouping.ChildArtifactEntries)
|
if (grouping.Type is not null)
|
||||||
{
|
{
|
||||||
if (entry.Files is { Count: > 0 })
|
var existingType = await context.ArtifactTypes
|
||||||
|
.FirstOrDefaultAsync(t => t.Name == grouping.Type.Name);
|
||||||
|
|
||||||
|
if (existingType is not null)
|
||||||
{
|
{
|
||||||
var correctedFileList = new List<FilePathListing>();
|
grouping.Type = existingType;
|
||||||
foreach (var fileListing in entry.Files)
|
|
||||||
{
|
|
||||||
var path = fileListing.Path;
|
|
||||||
if (string.IsNullOrWhiteSpace(path)) continue;
|
|
||||||
|
|
||||||
if (processedFilePaths.TryGetValue(path, out var trackedFile))
|
|
||||||
{
|
|
||||||
correctedFileList.Add(trackedFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingFile = await context.ArtifactFilePaths
|
|
||||||
.FirstOrDefaultAsync(f => f.Path == path);
|
|
||||||
|
|
||||||
if (existingFile != null)
|
|
||||||
{
|
|
||||||
correctedFileList.Add(existingFile);
|
|
||||||
processedFilePaths[path] = existingFile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
correctedFileList.Add(fileListing);
|
|
||||||
processedFilePaths[path] = fileListing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.Files = correctedFileList;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process all other related entities for each entry
|
// 2. Process ChildArtifactEntries
|
||||||
foreach (var entry in grouping.ChildArtifactEntries)
|
foreach (var entry in grouping.ChildArtifactEntries)
|
||||||
{
|
{
|
||||||
// Attach entry to its parent grouping
|
// Handle ArtifactStorageLocation (no change, this was fine)
|
||||||
|
var existingLocation = await context.ArtifactStorageLocations
|
||||||
|
.FirstOrDefaultAsync(l => l.Location == entry.StorageLocation.Location);
|
||||||
|
|
||||||
|
if (existingLocation is not null)
|
||||||
|
{
|
||||||
|
entry.StorageLocation = existingLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Defects
|
||||||
|
if (entry.Defects is not null && entry.Defects.Any())
|
||||||
|
{
|
||||||
|
var defectDescriptions = entry.Defects.Select(d => d.Description).ToList();
|
||||||
|
var existingDefects = await context.ArtifactDefects
|
||||||
|
.Where(d => defectDescriptions.Contains(d.Description))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Replace in-memory defects with existing ones
|
||||||
|
for (int i = 0; i < entry.Defects.Count; i++)
|
||||||
|
{
|
||||||
|
var existingDefect = existingDefects
|
||||||
|
.FirstOrDefault(ed => ed.Description == entry.Defects[i].Description);
|
||||||
|
|
||||||
|
if (existingDefect is not null)
|
||||||
|
{
|
||||||
|
entry.Defects[i] = existingDefect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle ListedNames
|
||||||
|
if (entry.ListedNames is not null && entry.ListedNames.Any())
|
||||||
|
{
|
||||||
|
var listedNamesValues = entry.ListedNames.Select(n => n.Value).ToList();
|
||||||
|
var existingNames = await context.ArtifactAssociatedNames
|
||||||
|
.Where(n => listedNamesValues.Contains(n.Value))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
for (int i = 0; i < entry.ListedNames.Count; i++)
|
||||||
|
{
|
||||||
|
var existingName = existingNames
|
||||||
|
.FirstOrDefault(en => en.Value == entry.ListedNames[i].Value);
|
||||||
|
|
||||||
|
if (existingName is not null)
|
||||||
|
{
|
||||||
|
entry.ListedNames[i] = existingName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Tags
|
||||||
|
if (entry.Tags is not null && entry.Tags.Any())
|
||||||
|
{
|
||||||
|
var tagNames = entry.Tags.Select(t => t.Name).ToList();
|
||||||
|
var existingTags = await context.ArtifactEntryTags
|
||||||
|
.Where(t => tagNames.Contains(t.Name))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
for (int i = 0; i < entry.Tags.Count; i++)
|
||||||
|
{
|
||||||
|
var existingTag = existingTags
|
||||||
|
.FirstOrDefault(et => et.Name == entry.Tags[i].Name);
|
||||||
|
|
||||||
|
if (existingTag is not null)
|
||||||
|
{
|
||||||
|
entry.Tags[i] = existingTag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 💡 NEW: Handle pre-existing FilePathListings
|
||||||
|
// This is the key change to resolve the exception
|
||||||
|
if (entry.Files is not null)
|
||||||
|
{
|
||||||
|
foreach (var filepath in entry.Files)
|
||||||
|
{
|
||||||
|
// The issue is trying to add a new entity that has an existing primary key.
|
||||||
|
// Since you stated that all files are pre-added, you must attach them.
|
||||||
|
// Attach() tells EF Core to track the entity, assuming it already exists.
|
||||||
|
context.Attach(filepath);
|
||||||
|
// Also ensure the parent-child relationship is set correctly, though it's likely set by ToArtifactGrouping
|
||||||
|
filepath.ParentArtifactEntry = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Tag each entry with the parent grouping so it is linked correctly in the database
|
||||||
entry.ArtifactGrouping = grouping;
|
entry.ArtifactGrouping = grouping;
|
||||||
|
|
||||||
// --- Process Storage Location ---
|
|
||||||
var locationName = entry.StorageLocation?.Location;
|
|
||||||
if (!string.IsNullOrWhiteSpace(locationName))
|
|
||||||
{
|
|
||||||
if (processedLocations.TryGetValue(locationName, out var trackedLocation))
|
|
||||||
{
|
|
||||||
entry.StorageLocation = trackedLocation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingLocation = await context.ArtifactStorageLocations
|
|
||||||
.FirstOrDefaultAsync(l => l.Location == locationName);
|
|
||||||
|
|
||||||
if (existingLocation != null)
|
|
||||||
{
|
|
||||||
entry.StorageLocation = existingLocation;
|
|
||||||
processedLocations[locationName] = existingLocation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
processedLocations[locationName] = entry.StorageLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Process Tags ---
|
|
||||||
if (entry.Tags is { Count: > 0 })
|
|
||||||
{
|
|
||||||
var correctedTagList = new List<ArtifactEntryTag>();
|
|
||||||
foreach (var tag in entry.Tags)
|
|
||||||
{
|
|
||||||
var tagName = tag.Name;
|
|
||||||
if (string.IsNullOrWhiteSpace(tagName)) continue;
|
|
||||||
|
|
||||||
if (processedTags.TryGetValue(tagName, out var trackedTag))
|
|
||||||
{
|
|
||||||
correctedTagList.Add(trackedTag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingTag = await context.ArtifactEntryTags.FirstOrDefaultAsync(t => t.Name == tagName);
|
|
||||||
if (existingTag != null)
|
|
||||||
{
|
|
||||||
correctedTagList.Add(existingTag);
|
|
||||||
processedTags[tagName] = existingTag;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
correctedTagList.Add(tag);
|
|
||||||
processedTags[tagName] = tag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.Tags = correctedTagList;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Process Defects ---
|
|
||||||
if (entry.Defects is { Count: > 0 })
|
|
||||||
{
|
|
||||||
var correctedDefectList = new List<ArtifactDefect>();
|
|
||||||
foreach (var defect in entry.Defects)
|
|
||||||
{
|
|
||||||
var defectDesc = defect.Description;
|
|
||||||
if (string.IsNullOrWhiteSpace(defectDesc)) continue;
|
|
||||||
|
|
||||||
if (processedDefects.TryGetValue(defectDesc, out var trackedDefect))
|
|
||||||
{
|
|
||||||
correctedDefectList.Add(trackedDefect);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingDefect = await context.ArtifactDefects.FirstOrDefaultAsync(d => d.Description == defectDesc);
|
|
||||||
if (existingDefect != null)
|
|
||||||
{
|
|
||||||
correctedDefectList.Add(existingDefect);
|
|
||||||
processedDefects[defectDesc] = existingDefect;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
correctedDefectList.Add(defect);
|
|
||||||
processedDefects[defectDesc] = defect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.Defects = correctedDefectList;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Process Types ---
|
|
||||||
if (entry.Type is not null)
|
|
||||||
{
|
|
||||||
var typeName = entry.Type.Name;
|
|
||||||
if (!string.IsNullOrWhiteSpace(typeName))
|
|
||||||
{
|
|
||||||
if (processedTypes.TryGetValue(typeName, out var trackedType))
|
|
||||||
{
|
|
||||||
entry.Type = trackedType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingType = await context.ArtifactTypes.FirstOrDefaultAsync(t => t.Name == typeName);
|
|
||||||
if (existingType != null)
|
|
||||||
{
|
|
||||||
entry.Type = existingType;
|
|
||||||
processedTypes[typeName] = existingType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
processedTypes[typeName] = entry.Type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Process Listed Names ---
|
|
||||||
if (entry.ListedNames is { Count: > 0 })
|
|
||||||
{
|
|
||||||
var correctedNameList = new List<ListedName>();
|
|
||||||
foreach (var name in entry.ListedNames)
|
|
||||||
{
|
|
||||||
var nameValue = name.Value;
|
|
||||||
if (string.IsNullOrWhiteSpace(nameValue)) continue;
|
|
||||||
|
|
||||||
if (processedNames.TryGetValue(nameValue, out var trackedName))
|
|
||||||
{
|
|
||||||
correctedNameList.Add(trackedName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var existingName = await context.ArtifactAssociatedNames
|
|
||||||
.FirstOrDefaultAsync(n => n.Value == nameValue);
|
|
||||||
|
|
||||||
if (existingName != null)
|
|
||||||
{
|
|
||||||
correctedNameList.Add(existingName);
|
|
||||||
processedNames[nameValue] = existingName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
correctedNameList.Add(name);
|
|
||||||
processedNames[nameValue] = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.ListedNames = correctedNameList;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grouping.Category != null && grouping.Category.Id > 0)
|
// 3. Add the main grouping object and let EF Core handle the graph
|
||||||
{
|
// The previous issues with the graph are resolved, so this line should now work.
|
||||||
context.Attach(grouping.Category);
|
|
||||||
}
|
|
||||||
// Add the entire graph. EF Core will correctly handle new vs. existing entities.
|
|
||||||
context.ArtifactGroupings.Add(grouping);
|
context.ArtifactGroupings.Add(grouping);
|
||||||
|
|
||||||
|
// 4. Save all changes in a single transaction
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public async Task OnGroupingPublished(ArtifactGroupingValidationModel model)
|
||||||
|
{
|
||||||
|
// The OnGroupingPublished method in this class should not contain DbContext logic.
|
||||||
|
// It should orchestrate the data flow by calling the appropriate provider methods.
|
||||||
|
var isNew = model.Id == 0 || model.Id is null;
|
||||||
|
|
||||||
|
// Convert the validation model to an entity
|
||||||
|
var grouping = model.ToArtifactGrouping();
|
||||||
|
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
// For a new grouping, use the CreateGroupingAsync method.
|
||||||
|
// The provider method will handle the file path logic.
|
||||||
|
await GroupingProvider.CreateGroupingAsync(grouping);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For an existing grouping, use the UpdateGroupingAsync method.
|
||||||
|
// The provider method will handle the change tracking.
|
||||||
|
await GroupingProvider.UpdateGroupingAsync(grouping);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class ArtifactEntryValidationModel
|
|||||||
List<ListedName> listedNames = new();
|
List<ListedName> listedNames = new();
|
||||||
foreach (var name in ListedNames)
|
foreach (var name in ListedNames)
|
||||||
{
|
{
|
||||||
listedNames.Add(new ListedName() { ParentArtifactEntry=entry, Value=name});
|
listedNames.Add(new ListedName() { Value=name });
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.ListedNames = listedNames;
|
entry.ListedNames = listedNames;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class ArtifactGroupingValidationModel : IValidatableObject
|
|||||||
IdentifierFields = identifierFields,
|
IdentifierFields = identifierFields,
|
||||||
IsPublicallyVisible = true,
|
IsPublicallyVisible = true,
|
||||||
ChildArtifactEntries = entries,
|
ChildArtifactEntries = entries,
|
||||||
Type = Type
|
Type = new ArtifactType() { Name = Type }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the parent link
|
// Create the parent link
|
||||||
@@ -113,7 +113,7 @@ public class ArtifactGroupingValidationModel : IValidatableObject
|
|||||||
Description = grouping.Description,
|
Description = grouping.Description,
|
||||||
IdentifierFieldValues = identifierFields,
|
IdentifierFieldValues = identifierFields,
|
||||||
IsPublicallyVisible = grouping.IsPublicallyVisible,
|
IsPublicallyVisible = grouping.IsPublicallyVisible,
|
||||||
Type = grouping.Type,
|
Type = grouping.Type.Name
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,14 @@ public class ArtifactGroupingRowElement
|
|||||||
|
|
||||||
public bool IsPublicallyVisible { get; set; }
|
public bool IsPublicallyVisible { get; set; }
|
||||||
|
|
||||||
public override bool Equals(object? o)
|
public bool Equals(ArtifactGroupingRowElement? other)
|
||||||
{
|
{
|
||||||
var other = o as ArtifactGroupingRowElement;
|
if (other is null) return false;
|
||||||
return other?.Id == Id;
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
return Id == other.Id; // Compare based on the unique Id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object? obj) => Equals(obj as ArtifactGroupingRowElement);
|
||||||
|
|
||||||
public override int GetHashCode() => Id.GetHashCode();
|
public override int GetHashCode() => Id.GetHashCode();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<h3>ArchiveEntryDisplay</h3>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
@page "/archive/{GroupingIdString}"
|
||||||
|
@using OpenArchival.DataAccess;
|
||||||
|
|
||||||
|
@inject IArtifactGroupingProvider GroupingProvider;
|
||||||
|
@inject NavigationManager NavigationManager;
|
||||||
|
|
||||||
|
@if (_artifactGrouping is not null)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h1">@_artifactGrouping.Title</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string GroupingIdString { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The converted grouping id from the URL
|
||||||
|
/// </summary>
|
||||||
|
private int _groupingId { get; set; }
|
||||||
|
|
||||||
|
private ArtifactGrouping _artifactGrouping { get; set; } = default!;
|
||||||
|
|
||||||
|
protected override async Task OnParametersSetAsync()
|
||||||
|
{
|
||||||
|
_groupingId = int.Parse(GroupingIdString);
|
||||||
|
var grouping = await GroupingProvider.GetGroupingAsync(_groupingId);
|
||||||
|
|
||||||
|
if (grouping is null)
|
||||||
|
{
|
||||||
|
NavigationManager.NavigateTo("/grouping-not-found");
|
||||||
|
}
|
||||||
|
|
||||||
|
_artifactGrouping = grouping!;
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
|
await base.OnParametersSetAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
@page "/grouping-not-found"
|
||||||
|
|
||||||
|
|
||||||
|
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
|
||||||
|
<MudText Typo="Typo.h1" Align="Align.Center">Artifact Not Found!</MudText>
|
||||||
|
</MudPaper>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<h3>FileDisplayBase</h3>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<h3>FileDisplayImage</h3>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
namespace OpenArchival.Blazor;
|
||||||
|
|
||||||
|
public interface IFileDisplayComponent
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ COPY . .
|
|||||||
WORKDIR "/src/OpenArchival.Blazor"
|
WORKDIR "/src/OpenArchival.Blazor"
|
||||||
RUN dotnet build "./OpenArchival.Blazor.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
RUN dotnet build "./OpenArchival.Blazor.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|
||||||
|
|
||||||
# This stage is used to publish the service project to be copied to the final stage
|
# This stage is used to publish the service project to be copied to the final stage
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
@@ -29,4 +30,8 @@ RUN dotnet publish "./OpenArchival.Blazor.csproj" -c $BUILD_CONFIGURATION -o /ap
|
|||||||
FROM base AS final
|
FROM base AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
|
|
||||||
|
# Create the folder that will be used to store uploads
|
||||||
|
RUN mkdir /app/OpenArchivalUploads
|
||||||
|
|
||||||
ENTRYPOINT ["dotnet", "OpenArchival.Blazor.dll"]
|
ENTRYPOINT ["dotnet", "OpenArchival.Blazor.dll"]
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ActiveDebugProfile>Container (Dockerfile)</ActiveDebugProfile>
|
<ActiveDebugProfile>https</ActiveDebugProfile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"FileUploadOptions": {
|
"FileUploadOptions": {
|
||||||
"MaxUploadSizeBytes": 2147483648,
|
"MaxUploadSizeBytes": 2147483648,
|
||||||
"UploadFolderPath": "/OpenArchivalUploads",
|
"UploadFolderPath": "/app/OpenArchivalUploads",
|
||||||
"MaxFileCount": 100
|
"MaxFileCount": 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"FileUploadOptions": {
|
"FileUploadOptions": {
|
||||||
"MaxUploadSizeBytes": 2147483648,
|
"MaxUploadSizeBytes": 2147483648,
|
||||||
"UploadFolderPath": "/OpenArchivalUploads",
|
"UploadFolderPath": "/app/OpenArchivalUploads",
|
||||||
"MaxFileCount": 100
|
"MaxFileCount": 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||