@namespace OpenArchival.Blazor.CustomComponents @using Microsoft.Extensions.Logging @using Microsoft.Extensions.Options @using OpenArchival.DataAccess @using Microsoft.AspNetCore.Components.Forms @using MudBlazor Drag and drop files here or click @if (Files.Any() || ExistingFiles.Any()) { @foreach (var file in Files) { var color = _fileToDiskFileName.Keys.Contains(file) ? Color.Success : Color.Warning; } @foreach (var filelisting in ExistingFiles) { } } Open file picker Upload Clear @if (Files.Count != _fileToDiskFileName.Count) { *Files must be uploaded } @inject IOptions _options; @inject IFilePathListingProvider PathProvider; @inject ISnackbar Snackbar; @inject ILogger _logger; @code { 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; public readonly List Files = new(); private readonly Dictionary _fileToDiskFileName = new(); private MudFileUpload>? _fileUpload; public int SelectedFileCount { get => Files.Count; } public bool UploadsComplete { get; set; } = true; [Parameter] public EventCallback> FilesUploaded {get; set; } [Parameter] public EventCallback ClearClicked { get; set; } [Parameter] public List ExistingFiles { get; set; } = new(); protected override Task OnParametersSetAsync() { StateHasChanged(); return base.OnParametersSetAsync(); } 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); } } foreach (var listing in ExistingFiles) { try { FileInfo targetFile = new(listing.Path); if (targetFile.Exists) { targetFile.Delete(); } await PathProvider.DeleteFilePathListingAsync(listing.OriginalName, listing.Path); } catch (Exception ex) { _logger.LogError(ex, $"Error deleting file {listing.Path}"); Snackbar.Add($"Error cleaning up file: {listing.OriginalName}", Severity.Warning); } } _fileToDiskFileName.Clear(); Files.Clear(); await (_fileUpload?.ClearAsync() ?? Task.CompletedTask); ClearDragClass(); UploadsComplete = true; await ClearClicked.InvokeAsync(); } private Task OpenFilePickerAsync() => _fileUpload?.OpenFilePickerAsync() ?? Task.CompletedTask; private void OnInputFileChanged(InputFileChangeEventArgs e) { ClearDragClass(); var files = e.GetMultipleFiles(maximumFileCount: _options.Value.MaxFileCount); Files.AddRange(files); UploadsComplete = false; StateHasChanged(); } private async Task Upload() { if (!Files.Any()) { Snackbar.Add("No files to upload.", Severity.Warning); return; } Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; List 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() => _dragClass = $"{DefaultDragClass} mud-border-primary"; private void ClearDragClass() => _dragClass = DefaultDragClass; public void RemoveFile(string filename) { var existingFile = ExistingFiles.Where(f => f.OriginalName == filename).FirstOrDefault(); if (existingFile is not null) { ExistingFiles.Remove(existingFile); } var file = Files.Where(f => f.Name == filename).FirstOrDefault(); if (file is not null) { Files.Remove(file); } } }