Got the new ui flow working and the models updated. Need to get changes written to the database.

This commit is contained in:
Vincent Allen
2025-08-11 10:02:45 -04:00
parent a28663441e
commit dd3968f6ef
456 changed files with 17237 additions and 3851 deletions

View File

@@ -0,0 +1,82 @@
@* ChipContainer.razor *@
@typeparam T
<div class="d-flex flex-wrap ga-2 align-center">
@* Loop through and display each item as a chip *@
@foreach (var item in Items)
{
<MudChip Color="Color.Primary" OnClose="() => RemoveItem(item)" T="T">
@DisplayFunc(item)
</MudChip>
}
@* Render the input control provided by the consumer *@
<div style="min-width: 150px;">
@if (InputContent is not null)
{
@InputContent(this)
}
</div>
@SubmitButton
</div>
@code {
/// <summary>
/// The list of items to display and manage.
/// </summary>
[Parameter]
public required List<T> Items { get; set; } = new();
/// <summary>
/// Required for two-way binding (@bind-Items).
/// </summary>
[Parameter]
public EventCallback<List<T>> ItemsChanged { get; set; }
/// <summary>
/// The RenderFragment that defines the custom input control.
/// The 'context' is a reference to this component instance.
/// </summary>
[Parameter]
public RenderFragment<ChipContainer<T>>? InputContent { get; set; }
[Parameter]
public RenderFragment SubmitButton { get; set; }
/// <summary>
/// A function to convert an item of type T to a string for display in the chip.
/// Defaults to item.ToString().
/// </summary>
[Parameter]
public Func<T, string> DisplayFunc { get; set; } = item => item?.ToString() ?? string.Empty;
/// <summary>
/// A public method that the consumer's input control can call to add a new item.
/// </summary>
public async Task AddItem(T item)
{
if (item is null || (item is string str && string.IsNullOrWhiteSpace(str)))
{
return;
}
// Add the item if it doesn't already exist
if (!Items.Contains(item))
{
Items.Add(item);
await ItemsChanged.InvokeAsync(Items);
}
}
/// <summary>
/// Removes an item from the list when the chip's close icon is clicked.
/// </summary>
private async Task RemoveItem(T item)
{
Items.Remove(item);
await ItemsChanged.InvokeAsync(Items);
}
}

View File

@@ -1,122 +0,0 @@
@using MudBlazor
<div class="d-flex flex-wrap ga-2 align-center">
@* Loop through and display each tag as a chip *@
@foreach (var tag in Items)
{
<MudChip Color="Color.Primary" OnClose="() => RemoveTag(tag)" T="string">@tag</MudChip>
}
@* Text field for adding new tags *@
<div style="min-width: 150px;">
@switch (InputType)
{
case ChipTagInputType.TextBox:
{
<MudTextField T="string"
@bind-Value="_newTag"
Variant="Variant.Text"
@bind-Placeholder="Placeholder"
OnKeyDown="HandleKeyDownTextBox"
Immediate="true"
Style="padding-top: 0;"
@ref=_mudTextField
/>
break;
}
case ChipTagInputType.AutoComplete:
{
@if (AutocompleteSearchFunc is not null)
{
<MudAutocomplete
@bind-Text="_newTag"
@bind-Placeholder="Placeholder"
SearchFunc="AutocompleteSearchFunc"
CoerceText=false
CoerceValue=false
OnKeyDown="HandleKeyDownTextBox"
>
</MudAutocomplete>
}
break;
}
}
</div>
</div>
@code {
public enum ChipTagInputType
{
None,
TextBox,
AutoComplete,
Date
}
private string _newTag = "";
/// <summary>
/// The list of tags to display and manage.
/// </summary>
[Parameter]
public List<string> Items { get; set; } = new();
/// <summary>
/// Required for two-way binding (@bind-Items).
/// </summary>
[Parameter]
public EventCallback<List<string>> ItemsChanged { get; set; }
[Parameter]
public EventCallback OnChanged { get; set; }
[Parameter]
public string Placeholder { get; set; } = "Add tag...";
[Parameter]
public ChipTagInputType InputType { get; set; } = ChipTagInputType.TextBox;
[Parameter]
public Func<string, CancellationToken, Task<IEnumerable<string>>>? AutocompleteSearchFunc { get; set; } = null;
private MudTextField<string>? _mudTextField;
private MudAutocomplete<string>? _mudAutoComplete;
/// <summary>
/// Handles the key press event in the text field.
/// </summary>
private async Task HandleKeyDownTextBox(KeyboardEventArgs e)
{
if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(_newTag))
{
// Add the tag if it doesn't already exist
if (!Items.Contains(_newTag, StringComparer.OrdinalIgnoreCase))
{
Items.Add(_newTag);
await ItemsChanged.InvokeAsync(Items);
await OnChanged.InvokeAsync();
}
// Clear the input field
_newTag = "";
if (_mudTextField is not null)
_mudTextField.Clear();
if (_mudAutoComplete is not null)
await _mudAutoComplete.ClearAsync();
}
}
/// <summary>
/// Removes a tag from the list when the close icon is clicked.
/// </summary>
private async Task RemoveTag(string tag)
{
Items.Remove(tag);
await ItemsChanged.InvokeAsync(Items);
await OnChanged.InvokeAsync();
}
}

View File

@@ -0,0 +1,10 @@
namespace OpenArchival.Blazor.Components;
public class FileUploadOptions
{
public static string Key = "FileUploadOptions";
public required long MaxUploadSizeBytes { get; set; }
public required string UploadFolderPath { get; set; }
public required int MaxFileCount { get; set; }
}

View File

@@ -1,4 +1,5 @@
@inject ISnackbar Snackbar
@using Microsoft.Extensions.Options
TODO: Handle the case in which there are duplicate file names
<style>
.file-upload-input {
@@ -15,7 +16,8 @@
<MudFileUpload T="IReadOnlyList<IBrowserFile>"
@ref="@_fileUpload"
OnFilesChanged="OnInputFileChanged"
AppendMultipleFiles
AppendMultipleFiles=true
MaximumFileCount="_options.Value.MaxFileCount"
Hidden="@false"
InputClass="file-upload-input"
tabindex="-1"
@@ -24,22 +26,33 @@
@ondragleave="@ClearDragClass"
@ondragend="@ClearDragClass">
<ActivatorContent>
<MudPaper Height="300px"
Outlined="true"
Class="@_dragClass">
<MudText Typo="Typo.h6">
Drag and drop files here or click
</MudText>
@foreach (var file in _fileNames)
{
<MudChip T="string"
Color="Color.Dark"
Text="@file"
tabindex="-1" />
}
</MudPaper>
<MudPaper Outlined="true"
Class="@_dragClass"
Style="height: 150px; display: flex; flex-direction: column; position: relative;">
<div class="d-flex align-center justify-center pa-4" style="flex-shrink: 0;">
<MudText Typo="Typo.h6">
Drag and drop files here or click
</MudText>
</div>
</MudPaper>
</ActivatorContent>
</MudFileUpload>
@if (_files.Any())
{
<MudPaper Style="max-height: 150px; overflow-y: auto;" Outlined="true" Class="pa-4">
@foreach (var file in _files)
{
var color = _fileToDiskFileName.Keys.Contains(file) ? Color.Success : Color.Warning;
<MudChip T="string"
Color="@color"
Text="@file.Name"
tabindex="-1" />
}
</MudPaper>
}
<MudToolBar Gutters="@false"
Class="relative d-flex justify-end gap-4">
<MudButton Color="Color.Primary"
@@ -48,32 +61,78 @@
Open file picker
</MudButton>
<MudButton Color="Color.Primary"
Disabled="@(!_fileNames.Any())"
Disabled="@(!_files.Any())"
OnClick="@Upload"
Variant="Variant.Filled">
Upload
</MudButton>
<MudButton Color="Color.Error"
Disabled="@(!_fileNames.Any())"
Disabled="@(!_files.Any())"
OnClick="@ClearAsync"
Variant="Variant.Filled">
Clear
</MudButton>
</MudToolBar>
@if (_files.Count != _fileToDiskFileName.Count)
{
<MudText Color="Color.Error" Align="Align.Right">*Files must be uploaded</MudText>
}
</MudStack>
@inject IOptions<FileUploadOptions> _options;
@inject IFilePathListingProvider PathProvider;
@inject ISnackbar Snackbar;
@inject ILogger<UploadDropBox> _logger;
@code {
#nullable enable
private const string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full";
private string _dragClass = DefaultDragClass;
private readonly List<string> _fileNames = new();
private readonly List<IBrowserFile> _files = new();
private readonly Dictionary<IBrowserFile, string> _fileToDiskFileName = new();
private MudFileUpload<IReadOnlyList<IBrowserFile>>? _fileUpload;
public int SelectedFileCount { get => _files.Count; }
public bool UploadsComplete { get; set; } = true;
[Parameter]
public EventCallback<List<FilePathListing>> FilesUploaded {get; set; }
[Parameter]
public EventCallback ClearClicked { get; set; }
private async Task ClearAsync()
{
foreach (var pair in _fileToDiskFileName)
{
try
{
FileInfo targetFile = new(pair.Value);
if (targetFile.Exists)
{
targetFile.Delete();
}
await PathProvider.DeleteFilePathListingAsync(pair.Key.Name, pair.Value);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting file {FileName}", pair.Key.Name);
Snackbar.Add($"Error cleaning up file: {pair.Key.Name}", Severity.Warning);
}
}
_fileToDiskFileName.Clear();
_files.Clear();
await (_fileUpload?.ClearAsync() ?? Task.CompletedTask);
_fileNames.Clear();
ClearDragClass();
UploadsComplete = true;
await ClearClicked.InvokeAsync();
}
private Task OpenFilePickerAsync()
@@ -82,18 +141,54 @@
private void OnInputFileChanged(InputFileChangeEventArgs e)
{
ClearDragClass();
var files = e.GetMultipleFiles();
foreach (var file in files)
{
_fileNames.Add(file.Name);
}
var files = e.GetMultipleFiles(maximumFileCount: _options.Value.MaxFileCount);
_files.AddRange(files);
UploadsComplete = false;
StateHasChanged();
}
private void Upload()
private async Task Upload()
{
// Upload the files here
if (!_files.Any())
{
Snackbar.Add("No files to upload.", Severity.Warning);
return;
}
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
Snackbar.Add("TODO: Upload your files!");
List<FilePathListing> fileListings = [];
foreach (var file in _files)
{
if (_fileToDiskFileName.ContainsKey(file)) continue;
try
{
var diskFileName = $"{Guid.NewGuid()}{Path.GetExtension(file.Name)}";
var destinationPath = Path.Combine(_options.Value.UploadFolderPath, diskFileName);
await using var browserUploadStream = file.OpenReadStream(maxAllowedSize: _options.Value.MaxUploadSizeBytes);
await using var outFileStream = new FileStream(destinationPath, FileMode.Create);
await browserUploadStream.CopyToAsync(outFileStream);
_fileToDiskFileName.Add(file, destinationPath);
var fileListing = new FilePathListing() { Path = destinationPath, OriginalName = Path.GetFileName(file.Name) };
fileListings.Add(fileListing);
await PathProvider.CreateFilePathListingAsync(fileListing);
Snackbar.Add($"Uploaded {file.Name}", Severity.Success);
UploadsComplete = true;
}
catch (Exception ex)
{
Snackbar.Add($"Error uploading file {file.Name}: {ex.Message}", Severity.Error);
}
}
await FilesUploaded.InvokeAsync(fileListings);
}
private void SetDragClass()

View File

@@ -0,0 +1,216 @@
@page "/add"
@using OpenArchival.Blazor.Components.CustomComponents;
@using OpenArchival.Blazor.Components.Pages.Administration.Categories
@using OpenArchival.DataAccess;
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<MudText Typo="Typo.h5" Color="Color.Primary">Add an Archive Item</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
@if (!IsValid && _isFormDivVisible)
{
<MudAlert Severity="Severity.Error" Class="mt-4">
All identifier fields must be filled in.
</MudAlert>
}
<MudGrid Justify="Justify.Center" Class="pt-4">
<MudItem>
<MudAutocomplete T="string" Label="Category" @bind-Value="Model.Category" @bind-Value:after=OnCategoryChanged SearchFunc="SearchCategory" CoerceValue=false CoerceText=false/>
</MudItem>
<MudItem>
<MudFab Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add" OnClick="OnAddCategoryClicked"/>
</MudItem>
</MudGrid>
</MudPaper>
<div @ref="_formDiv" style="@_formDivStyle">
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Archive Item Identifier</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<IdentifierTextBox @ref="_identifierTextBox" IdentifierFields="@Model.IdentifierFields"></IdentifierTextBox>
</MudPaper>
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<UploadDropBox FilesUploaded="OnFilesUploaded" ClearClicked="OnClearFilesClicked"></UploadDropBox>
</MudPaper>
@foreach (FilePathListing listing in _filePathListings)
{
<ArchiveEntryCreatorCard FilePath="listing" OnValueChanged="OnChanged"></ArchiveEntryCreatorCard>
}
</div>
<MudGrid Justify="Justify.FlexEnd" Class="pt-6">
<MudItem>
<MudCheckBox Label="Publicly Visible" T="bool"></MudCheckBox>
@*<MudCheckBox Label="Publicly Visible" T="bool" @bind-Value=Model.IsPublic></MudCheckBox>*@
</MudItem>
<MudItem Style="pr-0">
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="ml-4" OnClick="CancelClicked">Cancel</MudButton>
</MudItem>
<MudItem Style="pl-2">
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="ml-4" OnClick="PublishClicked">Publish</MudButton>
</MudItem>
</MudGrid>
@using System.ComponentModel.DataAnnotations
@inject IDialogService DialogService
@inject NavigationManager NavigationManager;
@inject IArchiveCategoryProvider CategoryProvider;
@code {
private IdentifierTextBox _identifierTextBox = default!;
private ElementReference _formDiv = default!;
private bool _isFormDivVisible = false;
private string _formDivStyle => _isFormDivVisible ? "" : "display: none;";
public List<string> DatesData { get; set; } = [];
public List<ArchiveCategory> Categories { get; set; } = new();
private List<FilePathListing> _filePathListings = new();
private bool _categorySelected = false;
//public List<IdentifierFieldValidationModel> IdentifierFields { get; set; } = [new IdentifierFieldValidationModel() { Name = "Field One", Value = "" }, new IdentifierFieldValidationModel() { Name = "Field Two", Value = "" }, new IdentifierFieldValidationModel() { Name = "Field Three", Value = "" }];
public ArchiveItemValidationModel Model { get; set; } = new();
public bool IsValid { get; set; } = false;
/// <summary>
/// The URI to navigate to if cancel is pressed
/// </summary>
public string? BackLink { get; set; } = "/";
public string? ForwardLink { get; set; } = "/";
private void CancelClicked(MouseEventArgs args)
{
if (BackLink is not null) {
NavigationManager.NavigateTo(BackLink);
}
else
{
throw new ArgumentNullException("No back link provided for the add archive item page.");
}
}
private async Task OnFilesUploaded(List<FilePathListing> args)
{
_filePathListings = args;
StateHasChanged();
await OnChanged();
}
private async Task OnClearFilesClicked()
{
_filePathListings = [];
StateHasChanged();
await OnChanged();
}
private void PublishClicked(MouseEventArgs args)
{
var validationContext = new ValidationContext(Model);
var validationResult = new List<ValidationResult>();
IsValid = Validator.TryValidateObject(Model, validationContext, validationResult);
/*
if (ForwardLink is not null)
{
if (IsValid)
{
NavigationManager.NavigateTo(ForwardLink);
}
else
{
StateHasChanged();
}
}
else
{
throw new ArgumentNullException("No forward link provided for the add archive item page.");
}
// TODO: assign parents to all file path listings
throw new NotImplementedException();
*/
}
async Task OnChanged()
{
var validationContext = new ValidationContext(Model);
var validationResult = new List<ValidationResult>();
IsValid = Validator.TryValidateObject(Model, validationContext, validationResult);
}
async Task OnCategoryChanged()
{
List<ArchiveCategory>? newCategory = await CategoryProvider.GetArchiveCategory(Model.Category);
if (newCategory.Count != 1)
{
throw new ArgumentException(nameof(Model.Category), $"Got {newCategory.Count} rows for category name={Model.Category}");
}
if (newCategory is not null)
{
_identifierTextBox.VerifyFormatCategory = newCategory[0];
_isFormDivVisible = true;
StateHasChanged();
}
if (!_categorySelected)
{
_categorySelected = true;
StateHasChanged();
}
await OnChanged();
}
public async Task OnAddCategoryClicked()
{
var options = new DialogOptions { CloseOnEscapeKey = true, BackdropClick = false };
var dialog = await DialogService.ShowAsync<CategoryCreatorDialog>("Create a Category", options);
var result = await dialog.Result;
if (result is not null && !result.Canceled)
{
await CategoryProvider.CreateCategoryAsync(CategoryValidationModel.ToArchiveCategory((CategoryValidationModel)result.Data));
StateHasChanged();
await OnChanged();
}
}
private async Task<IEnumerable<string>> SearchCategory(string value, CancellationToken cancellationToken)
{
List<ArchiveCategory> categories;
if (string.IsNullOrEmpty(value))
{
categories = new(await CategoryProvider.Top(25) ?? []);
}
else
{
categories = new((await CategoryProvider.Search(value) ?? []));
}
List<string> categoryStrings = [];
foreach (var category in categories)
{
categoryStrings.Add(category.Name);
}
return categoryStrings;
}
}

View File

@@ -1,308 +0,0 @@
@page "/add"
@using OpenArchival.Blazor.Components.CustomComponents;
@using OpenArchival.Blazor.Components.Pages.Administration.Categories
@using OpenArchival.Core
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<MudText Typo="Typo.h5" Color="Color.Primary">Add an Archive Item</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
@if (!IsValid && _isFormDivVisible)
{
<MudAlert Severity="Severity.Error" Class="mt-4">
All identifier fields must be filled in.
</MudAlert>
}
@* Archive item category *@
<MudGrid Justify="Justify.Center" Class="pt-4">
<MudItem>
<MudAutocomplete T="string" Label="Category" @bind-Value="Model.Category" @bind-Value:after=OnCategoryChanged SearchFunc="SearchCategory" CoerceValue=false CoerceText=false/>
</MudItem>
<MudItem>
<MudFab Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add" OnClick="OnAddCategoryClicked"/>
</MudItem>
</MudGrid>
<div @ref="_formDiv" style="@_formDivStyle">
@* ID Creation *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Archive Item Identifier</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<IdentifierTextBox @ref="_identifierTextBox" IdentifierFields="@Model.IdentifierFields"></IdentifierTextBox>
@* Title *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Archive Item Title</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudTextField Required=true Placeholder="Archive Item Title" T="string" Class="pl-4 pr-4" @bind-Value=Model.Title @bind-Value:after=OnChanged></MudTextField>
@* Description *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Item Description</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudTextField Lines=8 Placeholder="Description" T="string" Class="pl-4 pr-4" @bind-Value=Model.Description @bind-Value:after=OnChanged></MudTextField>
@* Storage Location *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Storage Location</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudAutocomplete T="string" Label="Storage Location" Class="pt-0 mt-0 pl-2 pr-2" @bind-Value=Model.StorageLocation @bind-Value:after=OnChanged CoerceText=false CoerceValue=false></MudAutocomplete>
@* Artifact Type *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Artifact Type</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudAutocomplete T="string" Label="Artifact Type" Class="pt-0 mt-0 pl-2 pr-2" @bind-Value=Model.ArtifactType @bind-Value:after=OnChanged SearchFunc="SearchItemTypes"></MudAutocomplete>
@* Tags *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Tags</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipTagInput @bind-Items=Model.Tags OnChanged="OnChanged" AutocompleteSearchFunc="SearchTags" InputType="ChipTagInput.ChipTagInputType.AutoComplete" Placeholder="Add tags..."></ChipTagInput>
@* Names *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Listed Names</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipTagInput @bind-Items=Model.AssociatedNames OnChanged="OnChanged" AutocompleteSearchFunc="SearchListedNames" InputType="ChipTagInput.ChipTagInputType.AutoComplete" Placeholder="Add names..."></ChipTagInput>
@* Associated Dates *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Associated Dates</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipTagInput @bind-Items=DatesData OnChanged="OnChanged"></ChipTagInput>
@* Defects *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Defects</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipTagInput @bind-Items=Model.Defects OnChanged="OnChanged" AutocompleteSearchFunc="SearchDefects" InputType="ChipTagInput.ChipTagInputType.AutoComplete" Placeholder="Add defects..."></ChipTagInput>
@* Related Artifacts *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Related Artifacts</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipTagInput @bind-Items=Model.RelatedArtifacts OnChanged="OnChanged"></ChipTagInput>
@* Files *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Artifact Documents</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<UploadDropBox></UploadDropBox>
@* Submit Buttons *@
<MudGrid Justify="Justify.FlexEnd" Class="pt-6">
<MudItem>
<MudCheckBox Label="Publicly Visible" T="bool" @bind-Value=Model.IsPublic></MudCheckBox>
</MudItem>
<MudItem>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="ml-4" OnClick="CancelClicked">Cancel</MudButton>
</MudItem>
<MudItem>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="ml-4" OnClick="PublishClicked">Publish</MudButton>
</MudItem>
</MudGrid>
</div>
</MudPaper>
@using OpenArchival.Database
@using System.ComponentModel.DataAnnotations
@inject IDialogService DialogService
@inject ICategoryProvider CategoryProvider
@inject IArchiveStorageLocationProvider StorageLocationProvider
@inject IArtifactTypesProvider ArtifactTypesProvider
@inject ITagsProvider TagsProvider;
@inject IArtifactAssociatedNamesProvider AssociatedNamesProvider;
@inject IDefectsProvider DefectsProvider;
@inject NavigationManager NavigationManager;
@code {
private IdentifierTextBox _identifierTextBox = default!;
private ElementReference _formDiv = default!;
private bool _isFormDivVisible = false;
private string _formDivStyle => _isFormDivVisible ? "" : "display: none;";
public List<string> DatesData { get; set; } = [];
public List<Category> Categories { get; set; } = new();
private bool _categorySelected = false;
//public List<IdentifierFieldValidationModel> IdentifierFields { get; set; } = [new IdentifierFieldValidationModel() { Name = "Field One", Value = "" }, new IdentifierFieldValidationModel() { Name = "Field Two", Value = "" }, new IdentifierFieldValidationModel() { Name = "Field Three", Value = "" }];
public ArchiveItemValidationModel Model { get; set; } = new();
public bool IsValid { get; set; } = false;
/// <summary>
/// The URI to navigate to if cancel is pressed
/// </summary>
public string? BackLink { get; set; } = "/";
public string? ForwardLink { get; set; } = "/";
private void CancelClicked(MouseEventArgs args)
{
if (BackLink is not null) {
NavigationManager.NavigateTo(BackLink);
}
else
{
throw new ArgumentNullException("No back link provided for the add archive item page.");
}
}
private void PublishClicked(MouseEventArgs args)
{
var validationContext = new ValidationContext(Model);
var validationResult = new List<ValidationResult>();
IsValid = Validator.TryValidateObject(Model, validationContext, validationResult);
if (ForwardLink is not null)
{
if (IsValid)
{
NavigationManager.NavigateTo(ForwardLink);
}
else
{
StateHasChanged();
}
}
else
{
throw new ArgumentNullException("No forward link provided for the add archive item page.");
}
throw new NotImplementedException();
}
void OnChanged()
{
var validationContext = new ValidationContext(Model);
var validationResult = new List<ValidationResult>();
IsValid = Validator.TryValidateObject(Model, validationContext, validationResult);
}
async Task OnCategoryChanged()
{
Category? newCategory = await CategoryProvider.GetCategoryAsync(Model.Category);
if (newCategory is not null)
{
_identifierTextBox.VerifyFormatCategory = newCategory;
_isFormDivVisible = true;
}
if (!_categorySelected)
{
_categorySelected = true;
StateHasChanged();
}
OnChanged();
}
public async Task OnAddCategoryClicked()
{
var options = new DialogOptions { CloseOnEscapeKey = true, BackdropClick = false };
var dialog = await DialogService.ShowAsync<CategoryCreatorDialog>("Create a Category", options);
var result = await dialog.Result;
if (result is not null && !result.Canceled)
{
StateHasChanged();
}
}
private async Task<IEnumerable<string>> SearchDefects(string value, CancellationToken cancellationToken)
{
List<string> defects;
if (string.IsNullOrEmpty(value))
{
defects = new(await DefectsProvider.TopDefects(25));
}
else
{
defects = new(await DefectsProvider.SearchDefects(value));
}
return defects;
}
private async Task<IEnumerable<string>> SearchListedNames(string value, CancellationToken cancellationToken)
{
List<string> names;
if (string.IsNullOrEmpty(value))
{
names = new(await AssociatedNamesProvider.TopNames(25));
}
else
{
names = new(await AssociatedNamesProvider.SearchNames(value));
}
return names;
}
private async Task<IEnumerable<string>> SearchTags(string value, CancellationToken cancellationToken)
{
List<string> tags;
if (string.IsNullOrEmpty(value))
{
tags = new(await TagsProvider.TopTags(25));
}
else
{
tags = new(await TagsProvider.SearchTags(value));
}
return tags;
}
private async Task<IEnumerable<string>> SearchItemTypes(string value, CancellationToken cancellationToken)
{
List<string> itemTypes;
if (string.IsNullOrEmpty(value))
{
itemTypes = new(await ArtifactTypesProvider.TopTypes(25));
}
else
{
itemTypes = new(await ArtifactTypesProvider.SearchTypes(value));
}
return itemTypes;
}
private async Task<IEnumerable<string>> SearchStorageLocation(string value, CancellationToken cancellationToken)
{
List<string> storageLocations;
if (string.IsNullOrEmpty(value))
{
storageLocations = new(await StorageLocationProvider.TopLocations(25));
}
else
{
storageLocations = new(await StorageLocationProvider.SearchLocations(value));
}
return storageLocations;
}
private async Task<IEnumerable<string>> SearchCategory(string value, CancellationToken cancellationToken)
{
List<Category> categories;
if (string.IsNullOrEmpty(value))
{
categories = new(await CategoryProvider.TopCategories(25));
}
else
{
categories = new(await CategoryProvider.SearchCategories(value));
}
List<string> categoryStrings = [];
foreach (var category in categories)
{
categoryStrings.Add(category.CategoryName);
}
return categoryStrings;
}
}

View File

@@ -0,0 +1,289 @@
@using OpenArchival.Blazor.Components.CustomComponents;
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<h3>@FilePath.OriginalName</h3>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Archive Item Title</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudTextField Required=true Placeholder="Archive Item Title" T="string" Class="pl-4 pr-4" @bind-Value=Model.Title @bind-Value:after=OnInputsChanged></MudTextField>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Item Description</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudTextField Lines=8 Placeholder="Description" T="string" Class="pl-4 pr-4" @bind-Value=Model.Description @bind-Value:after=OnInputsChanged></MudTextField>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Storage Location</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudAutocomplete T="string" Label="Storage Location" Class="pt-0 mt-0 pl-2 pr-2" @bind-Value=Model.StorageLocation @bind-Value:after=OnInputsChanged SearchFunc="SearchStorageLocation" CoerceValue=true></MudAutocomplete>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Artifact Type</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<MudAutocomplete T="string" Label="Artifact Type" Class="pt-0 mt-0 pl-2 pr-2" @bind-Value=Model.ArtifactType @bind-Value:after=OnInputsChanged SearchFunc="SearchItemTypes" CoerceValue=true></MudAutocomplete>
@* Tags entry *@
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Tags</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipContainer T="string" @ref="@_tagsChipContainer" @bind-Items="Model.Tags">
<InputContent>
<MudAutocomplete
T="string"
OnInternalInputChanged="OnInputsChanged"
SearchFunc="SearchTags"
Value="_tagsInputValue"
ValueChanged="OnTagsInputTextChanged"
OnKeyDown="@(ev => HandleChipContainerEnter<string>(ev, _tagsChipContainer, _tagsInputValue, () => _tagsInputValue = string.Empty))"
CoerceValue=true
Placeholder="Add Tags..."
ShowProgressIndicator="true">
</MudAutocomplete>
</InputContent>
</ChipContainer>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Listed Names</MudText>
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="pb-2">Enter any names of the people associated with this entry.</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipContainer T="string" @ref=_listedNamesChipContainer>
<InputContent>
<MudAutocomplete
T="string"
SearchFunc="SearchListedNames"
OnInternalInputChanged="OnInputsChanged"
Value="_listedNamesInputValue"
ValueChanged="OnListedNamesTextChanged"
OnKeyDown="@(ev=>HandleChipContainerEnter<string>(ev, _listedNamesChipContainer, _listedNamesInputValue, () => _listedNamesInputValue = string.Empty))"
CoerceValue=true
Placeholder="Add Listed Names..."
ShowProgressIndicator=true>
</MudAutocomplete>
</InputContent>
</ChipContainer>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Associated Dates</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipContainer T="DateTime" @ref="_assocaitedDatesChipContainer" DisplayFunc="date=>date.ToShortDateString()">
<InputContent>
<MudDatePicker @bind-Date=_associatedDateInputValue>
</MudDatePicker>
</InputContent>
<SubmitButton>
<MudButton
Color="Color.Primary"
OnClick="HandleAssociatedDateChipContainerAdd">+</MudButton>
</SubmitButton>
</ChipContainer>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Defects</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipContainer T="string" @ref=_defectsChipContainer>
<InputContent>
<MudAutocomplete
T="string"
SearchFunc="SearchDefects"
OnInternalInputChanged="OnInputsChanged"
Value="_defectsInputValue"
ValueChanged="OnDefectsValueChanged"
OnKeyDown="@(ev=>HandleChipContainerEnter<string>(ev, _defectsChipContainer, _defectsInputValue, () => _defectsInputValue = string.Empty))"
CoerceValue=true
Placeholder="Add Defects..."
ShowProgressIndicator=true>
</MudAutocomplete>
</InputContent>
</ChipContainer>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Related Artifacts</MudText>
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="pb-2">Tag this entry with the identifier of any other entry to link them.</MudText>
<MudDivider DividerType="DividerType.Middle"></MudDivider>
<ChipContainer T="ArtifactGrouping" @ref="_assocaitedArtifactsChipContainer" DisplayFunc="artifact => artifact.ArtifactGroupingIdentifier">
<InputContent>
<MudAutocomplete
T="ArtifactGrouping"
OnInternalInputChanged="OnInputsChanged"
Value="_associatedArtifactValue"
ValueChanged="OnAssociatedArtifactChanged"
OnKeyDown="@(EventArgs=>HandleChipContainerEnter<ArtifactGrouping>(EventArgs, _assocaitedArtifactsChipContainer, _associatedArtifactValue, () => _associatedArtifactValue = null))"
CoerceValue="false"
Placeholder="Link artifact groupings..."
ShowProgressIndicator=true>
</MudAutocomplete>
</InputContent>
</ChipContainer>
<MudText Typo="Typo.h6" Color="Color.Primary" Class="pt-4 pb-0">Artifact Text Contents</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>
<MudTextField T="string" Value=_artifactTextContent ValueChanged="OnArtifactTextContentChanged"></MudTextField>
</MudPaper>
@inject IArtifactDefectProvider DefectsProvider;
@inject IArtifactStorageLocationProvider StorageLocationProvider;
@inject IArchiveEntryTagProvider TagsProvider;
@inject IArtifactTypeProvider TypesProvider;
@inject IListedNameProvider ListedNameProvider;
@code {
[Parameter]
public required FilePathListing FilePath { get; set; }
[Parameter]
public EventCallback OnValueChanged { get; set; }
[Parameter]
public required ArtifactEntryValidationModel Model { get; set; } = new(){StorageLocation="hello", Title="Hello"};
private ChipContainer<string> _tagsChipContainer;
private string _tagsInputValue { get; set; } = "";
private ChipContainer<DateTime> _assocaitedDatesChipContainer;
private DateTime? _associatedDateInputValue { get; set; } = default;
private ChipContainer<string> _listedNamesChipContainer;
private string _listedNamesInputValue { get; set; } = "";
private ChipContainer<string> _defectsChipContainer;
private string _defectsInputValue = "";
private ChipContainer<ArtifactGrouping> _assocaitedArtifactsChipContainer;
private ArtifactGrouping? _associatedArtifactValue = null;
private string _artifactTextContent = "";
public Task OnInputsChanged()
{
return OnValueChanged.InvokeAsync();
}
private Task OnDefectsValueChanged(string text)
{
_defectsInputValue = text;
return OnValueChanged.InvokeAsync();
}
private Task OnTagsInputTextChanged(string text)
{
_tagsInputValue = text;
return OnValueChanged.InvokeAsync();
}
private Task OnListedNamesTextChanged(string text)
{
_listedNamesInputValue = text;
return OnValueChanged.InvokeAsync();
}
private Task OnAssociatedArtifactChanged(ArtifactGrouping grouping)
{
if (grouping is not null)
{
_associatedArtifactValue = grouping;
return OnValueChanged.InvokeAsync();
}
return OnValueChanged.InvokeAsync();
}
private Task OnArtifactTextContentChanged(string value)
{
return OnValueChanged.InvokeAsync();
}
public async Task HandleChipContainerEnter<Type>(KeyboardEventArgs args, ChipContainer<Type> container, Type value, Action resetInputAction)
{
if (args.Key == "Enter")
{
await container.AddItem(value);
resetInputAction?.Invoke();
StateHasChanged();
await OnValueChanged.InvokeAsync();
}
}
public async Task HandleAssociatedDateChipContainerAdd(MouseEventArgs args)
{
if (_associatedDateInputValue is not null)
{
await _assocaitedDatesChipContainer.AddItem((DateTime)_associatedDateInputValue);
_associatedDateInputValue = default;
}
}
private async Task<IEnumerable<string>> SearchDefects(string value, CancellationToken cancellationToken)
{
List<string> defects;
if (string.IsNullOrEmpty(value))
{
defects = new((await DefectsProvider.Top(25) ?? []).Select(prop => prop.Description));
}
else
{
defects = new((await DefectsProvider.Search(value) ?? []).Select(prop => prop.Description));
}
return defects;
}
private async Task<IEnumerable<string>> SearchStorageLocation(string value, CancellationToken cancellationToken)
{
List<string> storageLocations;
if (string.IsNullOrEmpty(value))
{
storageLocations = new((await StorageLocationProvider.Top(25) ?? []).Select(prop => prop.Location));
}
else
{
storageLocations = new((await StorageLocationProvider.Search(value) ?? []).Select(prop => prop.Location));
}
return storageLocations;
}
private async Task<IEnumerable<string>> SearchTags(string value, CancellationToken cancellationToken)
{
List<string> tags;
if (string.IsNullOrEmpty(value))
{
tags = new((await TagsProvider.Top(25) ?? []).Select(prop => prop.Name));
}
else
{
tags = new((await TagsProvider.Search(value) ?? []).Select(prop => prop.Name));
}
return tags;
}
private async Task<IEnumerable<string>> SearchItemTypes(string value, CancellationToken cancellationToken)
{
List<string> itemTypes;
if (string.IsNullOrEmpty(value))
{
itemTypes = new((await TypesProvider.Top(25) ?? []).Select(prop => prop.Name));
}
else
{
itemTypes = new((await TypesProvider.Search(value) ?? []).Select(prop => prop.Name));
}
return itemTypes;
}
private async Task<IEnumerable<string>> SearchListedNames(string value, CancellationToken cancellationToken)
{
List<string> names;
if (string.IsNullOrEmpty(value))
{
names = new((await ListedNameProvider.Top(25) ?? []).Select(prop=>$"{prop.FirstName} {prop.LastName}"));
}
else
{
names = new((await ListedNameProvider.Search(value) ?? []).Select(prop=>$"{prop.FirstName} {prop.LastName}"));
}
return names;
}
}

View File

@@ -17,7 +17,7 @@
<MudItem Class="pt-6">
<MudTextField Label="@field.Name"
@bind-Value="field.Value"
@bind-Value="@field.Value"
@bind-Value:after="OnInputChanged"
DebounceInterval="100"
Required=true/>
@@ -32,8 +32,8 @@
}
</MudGrid>
@using OpenArchival.Database;
@inject ICategoryProvider CategoryProvider;
@using OpenArchival.DataAccess;
@inject IArchiveCategoryProvider CategoryProvider;
@code {
[Parameter]
@@ -50,8 +50,8 @@
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
private Category _verifyFormatCategory;
public Category? VerifyFormatCategory
private ArchiveCategory _verifyFormatCategory;
public ArchiveCategory? VerifyFormatCategory
{
get
{
@@ -63,9 +63,9 @@
{
_identifierFields.Clear();
_verifyFormatCategory = value;
foreach (var field in value.FieldsIterator)
foreach (var field in value.FieldNames)
{
_identifierFields.Add(new IdentifierFieldValidationModel() {Name=field.Key, Value=""});
_identifierFields.Add(new IdentifierFieldValidationModel() {Name=field, Value=""});
}
}
}

View File

@@ -1,5 +1,5 @@
using OpenArchival.Core;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using OpenArchival.DataAccess;
namespace OpenArchival.Blazor;
@@ -34,19 +34,4 @@ public class ArchiveItemValidationModel
public bool IsPublic { get; set; } = true;
public ArchiveItem ToArchiveItem(Category category)
{
return new ArchiveItem() {
ArtifactType = ArtifactType,
Category = category,
Defects = Defects,
Description = Description,
AssociatedDates = AssociatedDates,
ItemTitle = Title,
ListedNames = AssociatedNames,
StorageLocation = StorageLocation,
Tags = Tags,
IsPublic = IsPublic
};
}
}

View File

@@ -0,0 +1,49 @@
namespace OpenArchival.Blazor;
using Microsoft.IdentityModel.Tokens;
using OpenArchival.DataAccess;
using System.ComponentModel.DataAnnotations;
public class ArtifactEntryValidationModel : IValidatableObject
{
[Required(AllowEmptyStrings = false, ErrorMessage = "An artifact numbering must be supplied")]
public string? ArtifactNumber { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "A title must be provided")]
public required string Title { get; set; }
public string? Description { get; set; }
public string? Type { get; set; }
public required string? StorageLocation { get; set; }
public List<string>? Tags { get; set; } = [];
public List<string>? ListedNames { get; set; } = [];
public List<DateTime>? AssociatedDates { get; set; } = [];
public List<string>? Defects { get; set; } = [];
public List<string>? Links { get; set; } = [];
public string? ArtifactType { get; set; }
public List<FilePathListing>? Files { get; set; } = [];
public Dictionary<string, string>? FileTextContent { get; set; } = [];
public IEnumerable<ValidationResult> Validate(ValidationContext context)
{
if (Links.IsNullOrEmpty() && Files.IsNullOrEmpty())
{
yield return new ValidationResult(
"Either uploaded files or add content links",
new[] {nameof(Links), nameof(Files)}
);
}
}
public bool IsPublicallyVisible { get; set; }
}

View File

@@ -0,0 +1,14 @@
using OpenArchival.DataAccess;
namespace OpenArchival.Blazor;
public class ArtifactGroupingValidationModel
{
public required ArchiveCategory Category { get; set; }
public List<string>? IdentifierFieldValues { get; set; }
public List<ArtifactEntryValidationModel>? ArtifactEntries { get; set; }
public bool IsPublicallyVisible { get; set; }
}

View File

@@ -1,44 +1,61 @@
@using OpenArchival.Database
@using Microsoft.EntityFrameworkCore;
@inject ICategoryProvider CategoryProvider;
@page "/categorieslist"
<MudPaper Class="pa-4 ma-2 rounded" Elevation="3">
<MudText Typo="Typo.h6">Categories</MudText>
<MudDivider></MudDivider>
<MudList T="string">
@foreach (Category category in _categories)
@foreach (ArchiveCategory category in _categories)
{
<MudListItem Text=@category.CategoryName OnClick="@(() => OnCategoryItemClicked(category.CategoryName))"></MudListItem>
<MudListItem Text=@category.Name OnClick="@(() => OnCategoryItemClicked(category))"></MudListItem>
}
</MudList>
@ChildContent
</MudPaper>
@inject IArchiveCategoryProvider CategoryProvider;
@inject ILogger<CategoriesListComponent> Logger;
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
public List<Category> _categories = new();
private List<ArchiveCategory> _categories = new();
[Parameter]
public EventCallback<string> ListItemClickedCallback { get; set; }
public EventCallback<ArchiveCategory> ListItemClickedCallback { get; set; }
protected override async Task OnInitializedAsync()
{
var categories = await CategoryProvider.AllCategories();
var categories = await CategoryProvider.GetAllArchiveCategories();
if (categories is null)
{
Logger.LogError("There were no categories in the database when attempting to load the list of categories.");
return;
}
_categories.AddRange(categories);
}
public async Task RefreshData()
{
_categories.Clear();
var categories = await CategoryProvider.AllCategories();
var categories = await CategoryProvider.GetAllArchiveCategories();
if (categories is null)
{
Logger.LogError("There were no categories in the database when attempting to load the list of categories.");
return;
}
_categories.AddRange(categories);
StateHasChanged();
}
protected async Task OnCategoryItemClicked(string categoryName)
protected async Task OnCategoryItemClicked(ArchiveCategory category)
{
await ListItemClickedCallback.InvokeAsync(categoryName);
await ListItemClickedCallback.InvokeAsync(category);
}
}

View File

@@ -1,6 +1,5 @@
@using System.ComponentModel.DataAnnotations;
@using OpenArchival.Core;
@using OpenArchival.Database;
@using OpenArchival.DataAccess;
<MudDialog>
<TitleContent>
@@ -8,8 +7,8 @@
</TitleContent>
<DialogContent>
<MudForm @ref="_form">
<MudTextField @bind-Value="Model.Name"
For="@(() => Model.Name)"
<MudTextField @bind-Value="ValidationModel.Name"
For="@(() => ValidationModel.Name)"
Label="Category Name"
Variant="Variant.Filled" />
@@ -23,9 +22,9 @@
<MudText Type="Typo.body2" Color="Color.Primary">@FormatPreview</MudText>
</MudStack>
<MudTextField @bind-Value="Model.FieldSeparator"
<MudTextField @bind-Value="ValidationModel.FieldSeparator"
@bind-Value:after="UpdateFormatPreview"
For="@(() => Model.FieldSeparator)"
For="@(() => ValidationModel.FieldSeparator)"
Label="Field Separator"
Variant="Variant.Filled"
MaxLength="1" />
@@ -33,7 +32,7 @@
<MudDivider Class="pt-4" />
<MudNumericField
Value="Model.NumFields"
Value="ValidationModel.NumFields"
ValueChanged="@((int newCount) => OnNumFieldsChanged(newCount))"
Label="Number of fields in the item identifiers"
Variant="Variant.Filled"
@@ -42,14 +41,14 @@
<MudDivider Class="pt-4" />
<MudGrid Class="pr-2 pt-2 pb-2 pl-8" Justify="Justify.FlexStart" Spacing="3">
@for (int index = 0; index < Model.FieldNames.Count; ++index)
@for (int index = 0; index < ValidationModel.FieldNames.Count; ++index)
{
var localIndex = index;
<MudItem xs="12" sm="6" md="6">
<CategoryFieldCardComponent Index="localIndex"
FieldName="@Model.FieldNames[localIndex]"
FieldDescription="@Model.FieldDescriptions[localIndex]"
FieldName="@ValidationModel.FieldNames[localIndex]"
FieldDescription="@ValidationModel.FieldDescriptions[localIndex]"
OnNameUpdate="HandleNameUpdate"
OnDescriptionUpdate="HandleDescriptionUpdate"/>
</MudItem>
@@ -63,14 +62,14 @@
</DialogActions>
</MudDialog>
@inject ICategoryProvider CategoryProvider;
@inject IArchiveCategoryProvider CategoryProvider;
@code {
[CascadingParameter]
private IMudDialogInstance MudDialog { get; set; } = default!;
[Parameter]
public CategoryValidationModel Model { get; set; } = default!;
public CategoryValidationModel ValidationModel { get; set; } = default!;
[Parameter]
public bool IsUpdate { get; set; }
@@ -83,38 +82,43 @@
protected override void OnParametersSet()
{
Model ??= new CategoryValidationModel { NumFields = 1 };
UpdateStateFromModel();
if (ValidationModel is null)
{
ValidationModel = new CategoryValidationModel { NumFields = 1 };
} else
{
ValidationModel.NumFields = ValidationModel.FieldNames.Count;
}
}
private void OnNumFieldsChanged(int newCount)
{
if (newCount < 1) return; // Prevent invalid counts
Model.NumFields = newCount;
if (newCount < 1) return;
ValidationModel.NumFields = newCount;
UpdateStateFromModel();
}
private void UpdateStateFromModel()
{
Model.FieldNames ??= new List<string>();
Model.FieldDescriptions ??= new List<string>();
ValidationModel.FieldNames ??= new List<string>();
ValidationModel.FieldDescriptions ??= new List<string>();
while (Model.FieldNames.Count < Model.NumFields)
while (ValidationModel.FieldNames.Count < ValidationModel.NumFields)
{
Model.FieldNames.Add($"Field {Model.FieldNames.Count + 1}");
ValidationModel.FieldNames.Add($"Field {ValidationModel.FieldNames.Count + 1}");
}
while (Model.FieldNames.Count > Model.NumFields)
while (ValidationModel.FieldNames.Count > ValidationModel.NumFields)
{
Model.FieldNames.RemoveAt(Model.FieldNames.Count - 1);
ValidationModel.FieldNames.RemoveAt(ValidationModel.FieldNames.Count - 1);
}
while (Model.FieldDescriptions.Count < Model.NumFields)
while (ValidationModel.FieldDescriptions.Count < ValidationModel.NumFields)
{
Model.FieldDescriptions.Add("");
ValidationModel.FieldDescriptions.Add("");
}
while (Model.FieldDescriptions.Count > Model.NumFields)
while (ValidationModel.FieldDescriptions.Count > ValidationModel.NumFields)
{
Model.FieldDescriptions.RemoveAt(Model.FieldDescriptions.Count - 1);
ValidationModel.FieldDescriptions.RemoveAt(ValidationModel.FieldDescriptions.Count - 1);
}
UpdateFormatPreview();
@@ -123,8 +127,8 @@
private void UpdateFormatPreview()
{
var fieldNames = Model.FieldNames.Select(name => string.IsNullOrEmpty(name) ? "<...>" : $"<{name}>");
FormatPreview = string.Join(Model.FieldSeparator, fieldNames);
var fieldNames = ValidationModel.FieldNames.Select(name => string.IsNullOrEmpty(name) ? "<...>" : $"<{name}>");
FormatPreview = string.Join(ValidationModel.FieldSeparator, fieldNames);
}
private async Task Submit()
@@ -132,17 +136,7 @@
await _form.Validate();
if (!_form.IsValid) return;
var categoryToSave = Model.ToCategory();
if (IsUpdate)
{
int lines = await CategoryProvider.UpdateCategoryAsync(OriginalName, categoryToSave);
Console.WriteLine($"{lines} effected");
}
else
{
await CategoryProvider.InsertCategoryAsync(categoryToSave);
}
MudDialog.Close(DialogResult.Ok(Model.ToCategory()));
MudDialog.Close(DialogResult.Ok(ValidationModel));
}
private void Cancel() => MudDialog.Cancel();
@@ -151,18 +145,18 @@
private void HandleNameUpdate((int Index, string NewValue) data)
{
if (data.Index < Model.FieldNames.Count)
if (data.Index < ValidationModel.FieldNames.Count)
{
Model.FieldNames[data.Index] = data.NewValue;
ValidationModel.FieldNames[data.Index] = data.NewValue;
UpdateFormatPreview(); // Update the preview in real-time
}
}
private void HandleDescriptionUpdate((int Index, string NewValue) data)
{
if (data.Index < Model.FieldDescriptions.Count)
if (data.Index < ValidationModel.FieldDescriptions.Count)
{
Model.FieldDescriptions[data.Index] = data.NewValue;
ValidationModel.FieldDescriptions[data.Index] = data.NewValue;
}
}
}

View File

@@ -1,6 +1,4 @@
@* CategoryFieldCardComponent.razor *@
<MudCard Outlined="true">
<MudCard Outlined="true">
<MudCardContent>
<MudTextField @bind-Value="FieldName"
@bind-Value:after="OnNameChanged"

View File

@@ -1,9 +0,0 @@
using System.ComponentModel.DataAnnotations;
public class CategoryFieldValidationModel
{
[Required(ErrorMessage = "A field name must be provided.")]
public string FieldName { get; set; } = "";
public string Description { get; set; } = "";
}

View File

@@ -1,10 +1,19 @@
using OpenArchival.Core;
namespace OpenArchival.Blazor;
using Microsoft.IdentityModel.Abstractions;
using Microsoft.IdentityModel.Tokens;
using OpenArchival.DataAccess;
using System.ComponentModel.DataAnnotations;
public class CategoryValidationModel
{
public int? DatabaseId { get; set; }
[Required(ErrorMessage = "Category name is required.")]
public string Name { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
[Required(ErrorMessage = "Field separator is required.")]
[StringLength(1, ErrorMessage = "Separator must be a single character.")]
@@ -18,12 +27,48 @@ public class CategoryValidationModel
public List<string> FieldDescriptions { get; set; } = [""];
public Category ToCategory()
public IEnumerable<ValidationResult> Validate(ValidationContext context)
{
return new Category() { CategoryName = Name, FieldSeparator = FieldSeparator, FieldNames = FieldNames.ToArray(), FieldDescriptions = FieldDescriptions.ToArray() };
if (FieldNames.IsNullOrEmpty() || FieldDescriptions.IsNullOrEmpty())
{
yield return new ValidationResult(
"Either the FieldNames or FieldDescriptions were null or empty. At least one is required",
new[] { nameof(FieldNames), nameof(FieldDescriptions) }
);
}
}
public static CategoryValidationModel FromCategory(Category category)
public static CategoryValidationModel FromArchiveCategory(ArchiveCategory category)
{
return new CategoryValidationModel() { Name = category.CategoryName, FieldSeparator=category.FieldSeparator, NumFields=category.FieldNames.Length, FieldNames = new(category.FieldNames), FieldDescriptions = new(category.FieldDescriptions)};
return new CategoryValidationModel()
{
Name = category.Name,
Description = category.Description,
DatabaseId = category.Id,
FieldSeparator = category.FieldSeparator,
FieldNames = category.FieldNames,
FieldDescriptions = category.FieldDescriptions,
};
}
public static ArchiveCategory ToArchiveCategory(CategoryValidationModel model)
{
return new ArchiveCategory()
{
Name = model.Name,
FieldSeparator = model.FieldSeparator,
Description = model.Description,
FieldNames = model.FieldNames,
FieldDescriptions = model.FieldDescriptions
};
}
public static void UpdateArchiveValidationModel(CategoryValidationModel model, ArchiveCategory category)
{
category.Name = model.Name ?? throw new ArgumentNullException(nameof(model.Name), "The model name was null.");
category.Description = model.Description;
category.FieldSeparator = model.FieldSeparator;
category.FieldNames = model.FieldNames;
category.FieldDescriptions = model.FieldDescriptions;
}
}

View File

@@ -1,10 +1,11 @@
@page "/categories"
@using OpenArchival.Core;
@using OpenArchival.Database;
@using OpenArchival.DataAccess;
@inject IDialogService DialogService
@inject ICategoryProvider CategoryProvider;
@inject IArchiveCategoryProvider CategoryProvider;
@inject ArchiveDbContext Context;
@inject ILogger<ViewAddCategoriesComponent> Logger;
<CategoriesListComponent @ref=_categoriesListComponent ListItemClickedCallback="ShowFilledDialog">
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="OnAddClick">Add Category</MudButton>
@@ -14,18 +15,11 @@
@code {
CategoriesListComponent _categoriesListComponent = default!;
private async Task ShowFilledDialog(string categoryName)
private async Task ShowFilledDialog(ArchiveCategory category)
{
Category? category = await CategoryProvider.GetCategoryAsync(categoryName);
CategoryValidationModel validationModel = CategoryValidationModel.FromArchiveCategory(category);
if (category is null)
{
throw new ArgumentNullException($"The passed in categoryName={categoryName} resulted in no category in the database");
}
CategoryValidationModel validationModel = CategoryValidationModel.FromCategory(category);
var parameters = new DialogParameters { ["Model"] = validationModel, ["IsUpdate"] = true, ["OriginalName"] = category.CategoryName};
var parameters = new DialogParameters { ["ValidationModel"] = validationModel, ["IsUpdate"] = true, ["OriginalName"] = category.Name};
var options = new DialogOptions { CloseOnEscapeKey = true, BackdropClick=false};
@@ -34,6 +28,16 @@
if (result is not null && !result.Canceled && _categoriesListComponent is not null)
{
if (result.Data is null)
{
Logger.LogError($"The new category received by the result had a null data result member.");
throw new NullReferenceException($"The new category received by the result had a null data result member.");
}
CategoryValidationModel model = (CategoryValidationModel)result.Data;
CategoryValidationModel.UpdateArchiveValidationModel(model, category);
await Context.SaveChangesAsync();
StateHasChanged();
await _categoriesListComponent.RefreshData();
}

View File

@@ -13,5 +13,5 @@
@using MudBlazor.Services
@using OpenArchival.Blazor
@using OpenArchival.Blazor.Components
@using OpenArchival.Core
@using OpenArchival.DataAccess

View File

@@ -13,6 +13,7 @@
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.*" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.*" />
<PackageReference Include="MudBlazor" Version="8.*" />
@@ -23,8 +24,7 @@
<ItemGroup>
<ProjectReference Include="..\OpenArchival.Core\OpenArchival.Core.csproj" />
<ProjectReference Include="..\OpenArchival.Database\OpenArchival.Database.csproj" />
<ProjectReference Include="..\OpenArchival.DataAccess\OpenArchival.DataAccess.csproj" />
</ItemGroup>
</Project>

View File

@@ -5,10 +5,10 @@ using MudBlazor.Services;
using OpenArchival.Blazor.Components;
using OpenArchival.Blazor.Components.Account;
using OpenArchival.Blazor.Data;
using OpenArchival.Database;
using Dapper;
using Npgsql;
using OpenArchival.Core;
using OpenArchival.DataAccess;
using Microsoft.IdentityModel.Tokens;
var builder = WebApplication.CreateBuilder(args);
@@ -19,30 +19,39 @@ builder.Services.AddMudServices();
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddMudExtensions();
var postgresOptions = builder.Configuration
.GetSection(PostgresConnectionOptions.Key)
.Get<PostgresConnectionOptions>();
if (postgresOptions == null || string.IsNullOrEmpty(postgresOptions.ConnectionString)) throw new InvalidOperationException("Postgres connection options are not configured properly.");
var postgresConnectionString = builder.Configuration.GetConnectionString("PostgresConnection");
builder.Services.AddDbContextFactory<ArchiveDbContext>
(
options => options.UseNpgsql(postgresConnectionString)
);
builder.Services.AddNpgsqlDataSource(postgresOptions.ConnectionString);
builder.Services.AddOptions<FileUploadOptions>().Bind(builder.Configuration.GetSection(FileUploadOptions.Key));
// Add options
builder.Services.AddOptions<PostgresConnectionOptions>().Bind(builder.Configuration.GetSection(PostgresConnectionOptions.Key));
var uploadSettings = builder.Configuration.GetSection(FileUploadOptions.Key).Get<FileUploadOptions>();
if (uploadSettings is null)
{
throw new ArgumentNullException(nameof(uploadSettings), $"The provided {nameof(FileUploadOptions)} did not have a max upload size.");
}
builder.Services.AddServerSideBlazor().AddHubOptions(options =>
{
options.MaximumReceiveMessageSize = uploadSettings.MaxUploadSizeBytes;
});
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<IdentityUserAccessor>();
builder.Services.AddScoped<IdentityRedirectManager>();
builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();
builder.Services.AddScoped<ICategoryProvider, CategoryProvider>();
builder.Services.AddScoped<IArtifactTypesProvider, ArtifactTypesProvider>();
builder.Services.AddScoped<IArtifactAssociatedNamesProvider, ArtifactAssociatedNamesProvider>();
builder.Services.AddScoped<IArchiveStorageLocationProvider, ArchiveStorageLocationProvider>();
builder.Services.AddScoped<ITagsProvider, TagsProvider>();
builder.Services.AddScoped<IDefectsProvider, DefectsProvider>();
builder.Services.AddScoped<IFilePathProvider, FilePathProvider>();
builder.Services.AddScoped<IArchiveCategoryProvider, ArchiveCategoryProvider>();
builder.Services.AddScoped<IFilePathListingProvider, FilePathListingProvider>();
builder.Services.AddScoped<IArtifactStorageLocationProvider, ArtifactStorageLocationProvider>();
builder.Services.AddScoped<IArtifactDefectProvider, ArtifactDefectProvider>();
builder.Services.AddScoped<IArtifactTypeProvider, ArtifactTypeProvider>();
builder.Services.AddScoped<IArchiveEntryTagProvider, ArchiveEntryTagProvider>();
builder.Services.AddScoped<IListedNameProvider, ListedNameProvider>();
builder.Services.AddAuthentication(options =>
{
@@ -92,46 +101,21 @@ app.MapRazorComponents<App>()
app.MapAdditionalIdentityEndpoints();
await InitializeDatabaseAsync(app.Services);
async Task InitializeDatabaseAsync(IServiceProvider services)
{
using var scope = services.CreateScope();
var serviceProvider = scope.ServiceProvider;
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Initializing database...");
var categoryProvider = serviceProvider.GetRequiredService<IArchiveCategoryProvider>();
var dataSource = serviceProvider.GetRequiredService<NpgsqlDataSource>();
await using var connection = await dataSource.OpenConnectionAsync();
await connection.ExecuteAsync(Tables.CategoryTable);
await connection.ExecuteAsync(Tables.ArtifactTypesTable);
await connection.ExecuteAsync(Tables.ArtifactAssociatedNamesTable);
await connection.ExecuteAsync(Tables.TagsTable);
await connection.ExecuteAsync(Tables.DefectsTable);
await connection.ExecuteAsync(Tables.ArchiveFiles);
var categoryProvider = serviceProvider.GetRequiredService<ICategoryProvider>();
await categoryProvider.InsertCategoryAsync(new Category() {CategoryName="Pictures", FieldSeparator="-", FieldNames=new string[]{"one", "two"},FieldDescriptions=new string[] { "one", "two"} });
await categoryProvider.InsertCategoryAsync(new Category() {CategoryName="Yearbooks", FieldSeparator="-", FieldNames=new string[]{"one", "two"},FieldDescriptions=new string[] { "one", "two"}});
await categoryProvider.InsertCategoryAsync(new Category() {CategoryName="Books", FieldSeparator="-", FieldNames=new string[]{"one", "two"}, FieldDescriptions = new string[] { "one", "two" } });
await categoryProvider.InsertCategoryAsync(new Category() {CategoryName="Newspapers", FieldSeparator="-", FieldNames=new string[]{"one", "two"}, FieldDescriptions = new string[] { "one", "two" }});
await categoryProvider.InsertCategoryAsync(new Category() {CategoryName="Letters", FieldSeparator="-", FieldNames=new string[]{"one", "two"}, FieldDescriptions = new string[] { "one", "two" } });
var artifactTypesProvider = serviceProvider.GetRequiredService<IArtifactTypesProvider>();
await artifactTypesProvider.AddType("Photo");
await artifactTypesProvider.AddType("Yearbook");
await artifactTypesProvider.AddType("Book");
var associatedNamesProvider = serviceProvider.GetRequiredService<IArtifactAssociatedNamesProvider>();
await associatedNamesProvider.InsertName("Sawyer Allen");
await associatedNamesProvider.InsertName("Vincent Allen");
logger.LogInformation("Database initialization complete.");
// await categoryProvider.CreateCategoryAsync(new ArchiveCategory {Name="Yearbooks", Description="This is a description", FieldSeparator="-", FieldNames = [], FieldDescriptions = [] });
}
app.Run();
//TODO: Periodic clean of the uploaded files to prune ones not in the database

View File

@@ -1,6 +1,7 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-OpenArchival.Blazor-2bdd9108-567b-4b19-b97f-47edace03070;Trusted_Connection=True;MultipleActiveResultSets=true"
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-OpenArchival.Blazor-2bdd9108-567b-4b19-b97f-47edace03070;Trusted_Connection=True;MultipleActiveResultSets=true",
"PostgresConnection": "Host=localhost;Database=postgres;Username=postgres;Password="
},
"Logging": {
"LogLevel": {
@@ -15,5 +16,10 @@
"Database": "postgres",
"Username": "postgres",
"Password": ""
},
"FileUploadOptions": {
"MaxUploadSizeBytes": 2147483648,
"UploadFolderPath": "C:\\TestUpload\\",
"MaxFileCount": 100
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"ContentRoots":["D:\\Open-Archival\\OpenArchival.Blazor\\wwwroot\\","D:\\Open-Archival\\OpenArchival.Blazor\\obj\\Debug\\net9.0\\compressed\\","C:\\Users\\vallen\\.nuget\\packages\\codebeam.mudextensions\\6.3.0\\staticwebassets\\","C:\\Users\\vallen\\.nuget\\packages\\mudblazor\\8.10.0\\staticwebassets\\"],"Root":{"Children":{"favicon.ico":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"favicon.ico"},"Patterns":null},"favicon.ico.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"uorc1pfmvs-2jeq8efc6q.gz"},"Patterns":null},"_content":{"Children":{"CodeBeam.MudExtensions":{"Children":{"Mud_Secondary.png":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"Mud_Secondary.png"},"Patterns":null},"MudExtensions.min.css":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"MudExtensions.min.css"},"Patterns":null},"MudExtensions.min.css.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"24gzn4tg1a-qz4batx9cb.gz"},"Patterns":null},"MudExtensions.min.js":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"MudExtensions.min.js"},"Patterns":null},"MudExtensions.min.js.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"stwk5nfoxp-loe7cozwzj.gz"},"Patterns":null}},"Asset":null,"Patterns":null},"MudBlazor":{"Children":{"MudBlazor.min.css":{"Children":null,"Asset":{"ContentRootIndex":3,"SubPath":"MudBlazor.min.css"},"Patterns":null},"MudBlazor.min.css.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"tzxjg6is5z-vu9q1asft2.gz"},"Patterns":null},"MudBlazor.min.js":{"Children":null,"Asset":{"ContentRootIndex":3,"SubPath":"MudBlazor.min.js"},"Patterns":null},"MudBlazor.min.js.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"0wz98yz2xy-i93b8idyg2.gz"},"Patterns":null}},"Asset":null,"Patterns":null}},"Asset":null,"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}
{"ContentRoots":["E:\\Open-Archival\\OpenArchival.Blazor\\wwwroot\\","E:\\Open-Archival\\OpenArchival.Blazor\\obj\\Debug\\net9.0\\compressed\\","C:\\Users\\Vincent Allen\\.nuget\\packages\\codebeam.mudextensions\\6.3.0\\staticwebassets\\","C:\\Users\\Vincent Allen\\.nuget\\packages\\mudblazor\\8.11.0\\staticwebassets\\"],"Root":{"Children":{"favicon.ico":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"favicon.ico"},"Patterns":null},"favicon.ico.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"uorc1pfmvs-2jeq8efc6q.gz"},"Patterns":null},"_content":{"Children":{"CodeBeam.MudExtensions":{"Children":{"Mud_Secondary.png":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"Mud_Secondary.png"},"Patterns":null},"MudExtensions.min.css":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"MudExtensions.min.css"},"Patterns":null},"MudExtensions.min.css.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"24gzn4tg1a-qz4batx9cb.gz"},"Patterns":null},"MudExtensions.min.js":{"Children":null,"Asset":{"ContentRootIndex":2,"SubPath":"MudExtensions.min.js"},"Patterns":null},"MudExtensions.min.js.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"stwk5nfoxp-loe7cozwzj.gz"},"Patterns":null}},"Asset":null,"Patterns":null},"MudBlazor":{"Children":{"MudBlazor.min.css":{"Children":null,"Asset":{"ContentRootIndex":3,"SubPath":"MudBlazor.min.css"},"Patterns":null},"MudBlazor.min.css.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"tzxjg6is5z-n8rndlt7dy.gz"},"Patterns":null},"MudBlazor.min.js":{"Children":null,"Asset":{"ContentRootIndex":3,"SubPath":"MudBlazor.min.js"},"Patterns":null},"MudBlazor.min.js.gz":{"Children":null,"Asset":{"ContentRootIndex":1,"SubPath":"0wz98yz2xy-ofbdodmtsc.gz"},"Patterns":null}},"Asset":null,"Patterns":null}},"Asset":null,"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
{
"runtimeOptions": {
"tfm": "net9.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "9.0.0"
}
],
"configProperties": {
"System.GC.Server": true,
"System.Reflection.NullabilityInfoContext.IsSupported": true,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View File

@@ -0,0 +1 @@
{"Version":1,"ManifestType":"Build","Endpoints":[]}

View File

@@ -1,674 +0,0 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v9.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v9.0": {
"OpenArchival.Database/1.0.0": {
"dependencies": {
"Dapper": "2.1.66",
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Hosting": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7",
"Npgsql": "9.0.3",
"Npgsql.DependencyInjection": "9.0.3",
"OpenArchival.Core": "1.0.0"
},
"runtime": {
"OpenArchival.Database.dll": {}
}
},
"Dapper/2.1.66": {
"runtime": {
"lib/net8.0/Dapper.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.1.66.48463"
}
}
},
"Microsoft.Extensions.Configuration/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.Abstractions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.Binder/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.CommandLine/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.CommandLine.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.EnvironmentVariables/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.FileExtensions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7",
"Microsoft.Extensions.FileProviders.Physical": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.FileExtensions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.Json/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Configuration.FileExtensions": "9.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.Json.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Configuration.UserSecrets/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Configuration.Json": "9.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7",
"Microsoft.Extensions.FileProviders.Physical": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.UserSecrets.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.DependencyInjection/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/9.0.7": {
"runtime": {
"lib/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Diagnostics/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.7",
"Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Diagnostics.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Diagnostics.Abstractions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Diagnostics.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.FileProviders.Abstractions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.FileProviders.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.FileProviders.Physical/9.0.7": {
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7",
"Microsoft.Extensions.FileSystemGlobbing": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.FileProviders.Physical.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.FileSystemGlobbing/9.0.7": {
"runtime": {
"lib/net9.0/Microsoft.Extensions.FileSystemGlobbing.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Hosting/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Configuration.Binder": "9.0.7",
"Microsoft.Extensions.Configuration.CommandLine": "9.0.7",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "9.0.7",
"Microsoft.Extensions.Configuration.FileExtensions": "9.0.7",
"Microsoft.Extensions.Configuration.Json": "9.0.7",
"Microsoft.Extensions.Configuration.UserSecrets": "9.0.7",
"Microsoft.Extensions.DependencyInjection": "9.0.7",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Diagnostics": "9.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7",
"Microsoft.Extensions.FileProviders.Physical": "9.0.7",
"Microsoft.Extensions.Hosting.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging.Configuration": "9.0.7",
"Microsoft.Extensions.Logging.Console": "9.0.7",
"Microsoft.Extensions.Logging.Debug": "9.0.7",
"Microsoft.Extensions.Logging.EventLog": "9.0.7",
"Microsoft.Extensions.Logging.EventSource": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Hosting.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Hosting.Abstractions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Hosting.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.Configuration/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration": "9.0.7",
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Configuration.Binder": "9.0.7",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7",
"Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.Configuration.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.Console/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging.Configuration": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.Console.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.Debug/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.Debug.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.EventLog/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7",
"System.Diagnostics.EventLog": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.EventLog.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Logging.EventSource/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Logging": "9.0.7",
"Microsoft.Extensions.Logging.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.EventSource.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Options/9.0.7": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Options.ConfigurationExtensions/9.0.7": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.7",
"Microsoft.Extensions.Configuration.Binder": "9.0.7",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Microsoft.Extensions.Options": "9.0.7",
"Microsoft.Extensions.Primitives": "9.0.7"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Microsoft.Extensions.Primitives/9.0.7": {
"runtime": {
"lib/net9.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"Npgsql/9.0.3": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "9.0.7"
},
"runtime": {
"lib/net8.0/Npgsql.dll": {
"assemblyVersion": "9.0.3.0",
"fileVersion": "9.0.3.0"
}
}
},
"Npgsql.DependencyInjection/9.0.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.7",
"Npgsql": "9.0.3"
},
"runtime": {
"lib/net8.0/Npgsql.DependencyInjection.dll": {
"assemblyVersion": "9.0.3.0",
"fileVersion": "9.0.3.0"
}
}
},
"System.Diagnostics.EventLog/9.0.7": {
"runtime": {
"lib/net9.0/System.Diagnostics.EventLog.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
},
"runtimeTargets": {
"runtimes/win/lib/net9.0/System.Diagnostics.EventLog.Messages.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "9.0.0.0",
"fileVersion": "0.0.0.0"
},
"runtimes/win/lib/net9.0/System.Diagnostics.EventLog.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.725.31616"
}
}
},
"OpenArchival.Core/1.0.0": {
"runtime": {
"OpenArchival.Core.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"OpenArchival.Database/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Dapper/2.1.66": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/q77jUgDOS+bzkmk3Vy9SiWMaetTw+NOoPAV0xPBsGVAyljd5S6P+4RUW7R3ZUGGr9lDRyPKgAMj2UAOwvqZYw==",
"path": "dapper/2.1.66",
"hashPath": "dapper.2.1.66.nupkg.sha512"
},
"Microsoft.Extensions.Configuration/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oxGR51+w5cXm5B9gU6XwpAB2sTiyPSmZm7hjvv0rzRnmL5o/KZzE103AuQj7sK26OBupjVzU/bZxDWvvU4nhEg==",
"path": "microsoft.extensions.configuration/9.0.7",
"hashPath": "microsoft.extensions.configuration.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lut/kiVvNsQ120VERMUYSFhpXPpKjjql+giy03LesASPBBcC0o6+aoFdzJH9GaYpFTQ3fGVhVjKjvJDoAW5/IQ==",
"path": "microsoft.extensions.configuration.abstractions/9.0.7",
"hashPath": "microsoft.extensions.configuration.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Binder/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ExY+zXHhU4o9KC2alp3ZdLWyVWVRSn5INqax5ABk+HEOHlAHzomhJ7ek9HHliyOMiVGoYWYaMFOGr9q59mSAGA==",
"path": "microsoft.extensions.configuration.binder/9.0.7",
"hashPath": "microsoft.extensions.configuration.binder.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.CommandLine/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-LqwdkMNFeRyuqExewBSaWj8roEgZH8JQ9zEAmHl5ZFcnhCvjAdHICdYVRIiSEq9RWGB731LL8kZJM8tdTKEscA==",
"path": "microsoft.extensions.configuration.commandline/9.0.7",
"hashPath": "microsoft.extensions.configuration.commandline.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.EnvironmentVariables/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-R8kgazVpDr4k1K7MeWPLAwsi5VpwrhE3ubXK38D9gpHEvf9XhZhJ8kWHKK00LDg5hJ7pMQLggdZ7XFdQ5182Ug==",
"path": "microsoft.extensions.configuration.environmentvariables/9.0.7",
"hashPath": "microsoft.extensions.configuration.environmentvariables.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.FileExtensions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3LVg32iMfR9ENeegXAo73L+877iOcQauLJsXlKZNVSsLA/HbPgClZdeMGdjLSkaidYw3l02XbXTlOdGYNgu91Q==",
"path": "microsoft.extensions.configuration.fileextensions/9.0.7",
"hashPath": "microsoft.extensions.configuration.fileextensions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Json/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3HQV326liEInT9UKEc+k73f1ECwNhvDS/DJAe5WvtMKDJTJqTH2ujrUC2ZlK/j6pXyPbV9f0Ku8JB20JveGImg==",
"path": "microsoft.extensions.configuration.json/9.0.7",
"hashPath": "microsoft.extensions.configuration.json.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.UserSecrets/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ouDuPgRdeF4TJXKUh+lbm6QwyWwnCy+ijiqfFM2cI5NmW83MwKg1WNp2nCdMVcwQW8wJXteF/L9lA6ZPS3bCIQ==",
"path": "microsoft.extensions.configuration.usersecrets/9.0.7",
"hashPath": "microsoft.extensions.configuration.usersecrets.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-i05AYA91vgq0as84ROVCyltD2gnxaba/f1Qw2rG7mUsS0gv8cPTr1Gm7jPQHq7JTr4MJoQUcanLVs16tIOUJaQ==",
"path": "microsoft.extensions.dependencyinjection/9.0.7",
"hashPath": "microsoft.extensions.dependencyinjection.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iPK1FxbGFr2Xb+4Y+dTYI8Gupu9pOi8I3JPuPsrogUmEhe2hzZ9LpCmolMEBhVDo2ikcSr7G5zYiwaapHSQTew==",
"path": "microsoft.extensions.dependencyinjection.abstractions/9.0.7",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Diagnostics/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6ykfInm6yw7pPHJACgnrPUXxUWVslFnzad44K/siXk6Ovan6fNMnXxI5X9vphHJuZ4JbMOdPIgsfTmLD+Dyxug==",
"path": "microsoft.extensions.diagnostics/9.0.7",
"hashPath": "microsoft.extensions.diagnostics.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Diagnostics.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d39Ov1JpeWCGLCOTinlaDkujhrSAQ0HFxb7Su1BjhCKBfmDcQ6Ia1i3JI6kd3NFgwi1dexTunu82daDNwt7E6w==",
"path": "microsoft.extensions.diagnostics.abstractions/9.0.7",
"hashPath": "microsoft.extensions.diagnostics.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-y9djCca1cz/oz/J8jTxtoecNiNvaiGBJeWd7XOPxonH+FnfHqcfslJMcSr5JMinmWFyS7eh3C9L6m6oURZ5lSA==",
"path": "microsoft.extensions.fileproviders.abstractions/9.0.7",
"hashPath": "microsoft.extensions.fileproviders.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Physical/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JYEPYrb+YBpFTCdmSBrk8cg3wAi1V4so7ccq04qbhg3FQHQqgJk28L3heEOKMXcZobOBUjTnGCFJD49Ez9kG5w==",
"path": "microsoft.extensions.fileproviders.physical/9.0.7",
"hashPath": "microsoft.extensions.fileproviders.physical.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.FileSystemGlobbing/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5VKpTH2ME0SSs0lrtkpKgjCeHzXR5ka/H+qThPwuWi78wHubApZ/atD7w69FDt0OOM7UMV6LIbkqEQgoby4IXA==",
"path": "microsoft.extensions.filesystemglobbing/9.0.7",
"hashPath": "microsoft.extensions.filesystemglobbing.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Hosting/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Dkv55VfitwJjPUk9mFHxT9MJAd8su7eJNaCHhBU/Y9xFqw3ZNHwrpeptXeaXiaPtfQq+alMmawIz1Impk5pHkQ==",
"path": "microsoft.extensions.hosting/9.0.7",
"hashPath": "microsoft.extensions.hosting.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Hosting.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yG2JCXAR+VqI1mKqynLPNJlNlrUJeEISEpX4UznOp2uM4IEFz3pDDauzyMvTjICutEJtOigJ1yWBvxbaIlibBw==",
"path": "microsoft.extensions.hosting.abstractions/9.0.7",
"hashPath": "microsoft.extensions.hosting.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-fdIeQpXYV8yxSWG03cCbU2Otdrq4NWuhnQLXokWLv3L9YcK055E7u8WFJvP+uuP4CFeCEoqZQL4yPcjuXhCZrg==",
"path": "microsoft.extensions.logging/9.0.7",
"hashPath": "microsoft.extensions.logging.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-sMM6NEAdUTE/elJ2wqjOi0iBWqZmSyaTByLF9e8XHv6DRJFFnOe0N+s8Uc6C91E4SboQCfLswaBIZ+9ZXA98AA==",
"path": "microsoft.extensions.logging.abstractions/9.0.7",
"hashPath": "microsoft.extensions.logging.abstractions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Configuration/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AEBty9rvFGvdFRqgIDEhQmiCnIfQWyzVoOZrO244cfu+n9M+wI1QLDpuROVILlplIBtLVmOezAF7d1H3Qog6Xw==",
"path": "microsoft.extensions.logging.configuration/9.0.7",
"hashPath": "microsoft.extensions.logging.configuration.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Console/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pEHlNa8iCfKsBFA3YVDn/8EicjSU/m8uDfyoR0i4svONDss4Yu9Kznw53E/TyI+TveTo7CwRid4kfd4pLYXBig==",
"path": "microsoft.extensions.logging.console/9.0.7",
"hashPath": "microsoft.extensions.logging.console.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Debug/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MxzZj7XbsYJwfjclVTjJym2/nVIkksu7l7tC/4HYy+YRdDmpE4B+hTzCXu3BNfLNhdLPZsWpyXuYe6UGgWDm3g==",
"path": "microsoft.extensions.logging.debug/9.0.7",
"hashPath": "microsoft.extensions.logging.debug.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.EventLog/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-usrMVsY7c8M8fESt34Y3eEIQIlRlKXfPDlI+vYEb6xT7SUjhua2ey3NpHgQktiTgz8Uo5RiWqGD8ieiyo2WaDA==",
"path": "microsoft.extensions.logging.eventlog/9.0.7",
"hashPath": "microsoft.extensions.logging.eventlog.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Logging.EventSource/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/wwi6ckTEegCExFV6gVToCO7CvysZnmE50fpdkYUsSMh0ue9vRkQ7uOqkHyHol93ASYTEahrp+guMtS/+fZKaA==",
"path": "microsoft.extensions.logging.eventsource/9.0.7",
"hashPath": "microsoft.extensions.logging.eventsource.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Options/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-trJnF6cRWgR5uMmHpGoHmM1wOVFdIYlELlkO9zX+RfieK0321Y55zrcs4AaEymKup7dxgEN/uJU25CAcMNQRXw==",
"path": "microsoft.extensions.options/9.0.7",
"hashPath": "microsoft.extensions.options.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Options.ConfigurationExtensions/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pE/jeAWHEIy/8HsqYA+I1+toTsdvsv+WywAcRoNSvPoFwjOREa8Fqn7D0/i0PbiXsDLFupltTTctliePx8ib4w==",
"path": "microsoft.extensions.options.configurationextensions/9.0.7",
"hashPath": "microsoft.extensions.options.configurationextensions.9.0.7.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ti/zD9BuuO50IqlvhWQs9GHxkCmoph5BHjGiWKdg2t6Or8XoyAfRJiKag+uvd/fpASnNklfsB01WpZ4fhAe0VQ==",
"path": "microsoft.extensions.primitives/9.0.7",
"hashPath": "microsoft.extensions.primitives.9.0.7.nupkg.sha512"
},
"Npgsql/9.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tPvY61CxOAWxNsKLEBg+oR646X4Bc8UmyQ/tJszL/7mEmIXQnnBhVJZrZEEUv0Bstu0mEsHZD5At3EO8zQRAYw==",
"path": "npgsql/9.0.3",
"hashPath": "npgsql.9.0.3.nupkg.sha512"
},
"Npgsql.DependencyInjection/9.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-McQ/xmBW9txjNzPyVKdmyx5bNVKDyc6ryz+cBOnLKxFH8zg9XAKMFvyNNmhzNjJbzLq8Rx+FFq/CeHjVT3s35w==",
"path": "npgsql.dependencyinjection/9.0.3",
"hashPath": "npgsql.dependencyinjection.9.0.3.nupkg.sha512"
},
"System.Diagnostics.EventLog/9.0.7": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AJ+9fyCtQUImntxAJ9l4PZiCd4iepuk4pm7Qcno7PBIWQnfXlvwKuFsGk2H+QyY69GUVzDP2heELW6ho5BCXUg==",
"path": "system.diagnostics.eventlog/9.0.7",
"hashPath": "system.diagnostics.eventlog.9.0.7.nupkg.sha512"
},
"OpenArchival.Core/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -1,12 +0,0 @@
{
"runtimeOptions": {
"tfm": "net9.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
},
"configProperties": {
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View File

@@ -1,6 +1,7 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-OpenArchival.Blazor-2bdd9108-567b-4b19-b97f-47edace03070;Trusted_Connection=True;MultipleActiveResultSets=true"
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-OpenArchival.Blazor-2bdd9108-567b-4b19-b97f-47edace03070;Trusted_Connection=True;MultipleActiveResultSets=true",
"PostgresConnection": "Host=localhost;Database=postgres;Username=postgres;Password="
},
"Logging": {
"LogLevel": {
@@ -15,5 +16,10 @@
"Database": "postgres",
"Username": "postgres",
"Password": ""
},
"FileUploadOptions": {
"MaxUploadSizeBytes": 2147483648,
"UploadFolderPath": "C:\\TestUpload\\",
"MaxFileCount": 100
}
}

View File

@@ -15,7 +15,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("OpenArchival.Blazor")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+167a8f6fc66bf3d9361bcbe1b051e38e703d0c04")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+57f67e85356af6759fc0211e8a510bd5b9f63dfa")]
[assembly: System.Reflection.AssemblyProductAttribute("OpenArchival.Blazor")]
[assembly: System.Reflection.AssemblyTitleAttribute("OpenArchival.Blazor")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
f35f4774bd9271fa994a802b54ed51512a57daf1231bddfd04df8ae9b020d795
a1b35575568c1043399b569538c23ee93b0a3fde5462a39aaab68b815fa02e10

View File

@@ -1,256 +1,260 @@
is_global = true
build_property.TargetFramework = net9.0
build_property.TargetFramework = net9.0
build_property.TargetPlatformMinVersion =
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb = true
build_property.UsingMicrosoftNETSdkWeb = true
build_property.ProjectTypeGuids =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.MudDebugAnalyzer =
build_property.MudAllowedAttributePattern =
build_property.MudAllowedAttributeList =
build_property.TargetFramework = net9.0
build_property.TargetFramework = net9.0
build_property.TargetPlatformMinVersion =
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb = true
build_property.UsingMicrosoftNETSdkWeb = true
build_property.ProjectTypeGuids =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = OpenArchival.Blazor
build_property.RootNamespace = OpenArchival.Blazor
build_property.ProjectDir = D:\Open-Archival\OpenArchival.Blazor\
build_property.ProjectDir = E:\Open-Archival\OpenArchival.Blazor\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.RazorLangVersion = 9.0
build_property.SupportLocalizedComponentNames =
build_property.GenerateRazorMetadataSourceChecksumAttributes =
build_property.MSBuildProjectDirectory = D:\Open-Archival\OpenArchival.Blazor
build_property.MSBuildProjectDirectory = E:\Open-Archival\OpenArchival.Blazor
build_property._RazorSourceGeneratorDebug =
build_property.EffectiveAnalysisLevelStyle = 9.0
build_property.EnableCodeStyleSeverity =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/AccessDenied.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/AccessDenied.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEFjY2Vzc0RlbmllZC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ConfirmEmail.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ConfirmEmail.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXENvbmZpcm1FbWFpbC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ConfirmEmailChange.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ConfirmEmailChange.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXENvbmZpcm1FbWFpbENoYW5nZS5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ExternalLogin.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ExternalLogin.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEV4dGVybmFsTG9naW4ucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ForgotPassword.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ForgotPassword.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEZvcmdvdFBhc3N3b3JkLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ForgotPasswordConfirmation.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ForgotPasswordConfirmation.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEZvcmdvdFBhc3N3b3JkQ29uZmlybWF0aW9uLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/InvalidPasswordReset.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/InvalidPasswordReset.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEludmFsaWRQYXNzd29yZFJlc2V0LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/InvalidUser.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/InvalidUser.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXEludmFsaWRVc2VyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Lockout.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Lockout.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXExvY2tvdXQucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Login.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Login.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXExvZ2luLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/LoginWith2fa.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/LoginWith2fa.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXExvZ2luV2l0aDJmYS5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/LoginWithRecoveryCode.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/LoginWithRecoveryCode.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXExvZ2luV2l0aFJlY292ZXJ5Q29kZS5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ChangePassword.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ChangePassword.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxDaGFuZ2VQYXNzd29yZC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/DeletePersonalData.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/DeletePersonalData.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxEZWxldGVQZXJzb25hbERhdGEucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Disable2fa.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Disable2fa.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxEaXNhYmxlMmZhLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Email.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Email.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxFbWFpbC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/EnableAuthenticator.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/EnableAuthenticator.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxFbmFibGVBdXRoZW50aWNhdG9yLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ExternalLogins.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ExternalLogins.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxFeHRlcm5hbExvZ2lucy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxHZW5lcmF0ZVJlY292ZXJ5Q29kZXMucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Index.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/Index.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxJbmRleC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/PersonalData.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/PersonalData.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxQZXJzb25hbERhdGEucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ResetAuthenticator.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/ResetAuthenticator.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxSZXNldEF1dGhlbnRpY2F0b3IucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/SetPassword.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/SetPassword.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxTZXRQYXNzd29yZC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/TwoFactorAuthentication.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/TwoFactorAuthentication.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxUd29GYWN0b3JBdXRoZW50aWNhdGlvbi5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/_Imports.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Manage/_Imports.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXE1hbmFnZVxfSW1wb3J0cy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Register.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/Register.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXFJlZ2lzdGVyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/RegisterConfirmation.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/RegisterConfirmation.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXFJlZ2lzdGVyQ29uZmlybWF0aW9uLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResendEmailConfirmation.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResendEmailConfirmation.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXFJlc2VuZEVtYWlsQ29uZmlybWF0aW9uLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResetPassword.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResetPassword.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXFJlc2V0UGFzc3dvcmQucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResetPasswordConfirmation.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/ResetPasswordConfirmation.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXFJlc2V0UGFzc3dvcmRDb25maXJtYXRpb24ucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/_Imports.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Pages/_Imports.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFBhZ2VzXF9JbXBvcnRzLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ExternalLoginPicker.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ExternalLoginPicker.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxFeHRlcm5hbExvZ2luUGlja2VyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ManageLayout.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ManageLayout.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxNYW5hZ2VMYXlvdXQucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ManageNavMenu.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ManageNavMenu.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxNYW5hZ2VOYXZNZW51LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/RedirectToLogin.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/RedirectToLogin.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxSZWRpcmVjdFRvTG9naW4ucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ShowRecoveryCodes.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/ShowRecoveryCodes.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxTaG93UmVjb3ZlcnlDb2Rlcy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/StatusMessage.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Account/Shared/StatusMessage.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBY2NvdW50XFNoYXJlZFxTdGF0dXNNZXNzYWdlLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/App.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/App.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xBcHAucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/CustomComponents/ChipTagInput.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xDdXN0b21Db21wb25lbnRzXENoaXBUYWdJbnB1dC5yYXpvcg==
[E:/Open-Archival/OpenArchival.Blazor/Components/CustomComponents/ChipContainer.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xDdXN0b21Db21wb25lbnRzXENoaXBDb250YWluZXIucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/CustomComponents/UploadDropBox.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/CustomComponents/UploadDropBox.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xDdXN0b21Db21wb25lbnRzXFVwbG9hZERyb3BCb3gucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Layout/MainLayout.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Layout/MainLayout.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xMYXlvdXRcTWFpbkxheW91dC5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Layout/NavMenu.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Layout/NavMenu.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xMYXlvdXRcTmF2TWVudS5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/AddArchiveItemComponent.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxBcmNoaXZlSXRlbXNcQWRkQXJjaGl2ZUl0ZW1Db21wb25lbnQucmF6b3I=
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/AddArchiveGroupingComponent.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxBcmNoaXZlSXRlbXNcQWRkQXJjaGl2ZUdyb3VwaW5nQ29tcG9uZW50LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/Component.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/ArchiveEntryCreatorCard.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxBcmNoaXZlSXRlbXNcQXJjaGl2ZUVudHJ5Q3JlYXRvckNhcmQucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/Component.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxBcmNoaXZlSXRlbXNcQ29tcG9uZW50LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/IdentifierTextBox.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/ArchiveItems/IdentifierTextBox.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxBcmNoaXZlSXRlbXNcSWRlbnRpZmllclRleHRCb3gucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoriesListComponent.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoriesListComponent.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxDYXRlZ29yaWVzXENhdGVnb3JpZXNMaXN0Q29tcG9uZW50LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoryCreatorDialog.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoryCreatorDialog.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxDYXRlZ29yaWVzXENhdGVnb3J5Q3JlYXRvckRpYWxvZy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoryFieldCardComponent.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/CategoryFieldCardComponent.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxDYXRlZ29yaWVzXENhdGVnb3J5RmllbGRDYXJkQ29tcG9uZW50LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/ViewAddCategoriesComponent.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Administration/Categories/ViewAddCategoriesComponent.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBZG1pbmlzdHJhdGlvblxDYXRlZ29yaWVzXFZpZXdBZGRDYXRlZ29yaWVzQ29tcG9uZW50LnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Auth.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Auth.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xBdXRoLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Counter.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Counter.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xDb3VudGVyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Error.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Error.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xFcnJvci5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Home.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Home.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xIb21lLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Pages/Weather.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Pages/Weather.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xQYWdlc1xXZWF0aGVyLnJhem9y
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/Routes.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/Routes.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xSb3V0ZXMucmF6b3I=
build_metadata.AdditionalFiles.CssScope =
[D:/Open-Archival/OpenArchival.Blazor/Components/_Imports.razor]
[E:/Open-Archival/OpenArchival.Blazor/Components/_Imports.razor]
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50c1xfSW1wb3J0cy5yYXpvcg==
build_metadata.AdditionalFiles.CssScope =

View File

@@ -1 +1 @@
51688d5aea80ea454f629a24e9fa4c0c433425ccc897eb8ada22062c9165a43f
326eba80d7bb6026e445989e7f52bb482aaae70f7db3f2ee6b6719c19b6c0c05

Some files were not shown because too many files have changed in this diff Show More