@namespace Oqtane.Modules.Controls @using System.Threading @inherits ModuleControlBase @inject IFolderService FolderService @inject IFileService FileService @inject ISettingService SettingService @inject IUserService UserService @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer @if (_initialized) {
@if (ShowFolders) {
} @if (ShowFiles) {
} else { if (FileId != -1 && _file != null && !UploadMultiple) { } } @if (ShowUpload && _haseditpermission) {
@if (UploadMultiple) { } else { }
@if (FileId != -1 && !UploadMultiple) { }
@if (ShowProgress) {
} else { if (_uploading) {
} } } @if (!string.IsNullOrEmpty(_message)) {
}
@if (_image != string.Empty) {
@((MarkupString) _image)
}
} @code { private bool _initialized = false; private List _folders; private List _files = new List(); private string _fileinputid = string.Empty; private string _progressinfoid = string.Empty; private string _progressbarid = string.Empty; private string _filter = "*"; private bool _haseditpermission = false; private string _image = string.Empty; private File _file = null; private string _guid; private string _message = string.Empty; private MessageType _messagetype; private bool _uploading = false; [Parameter] public string Id { get; set; } // optional - for setting the id of the FileManager component for accessibility [Parameter] public int FolderId { get; set; } = -1; // optional - for setting a specific default folder by folderid [Parameter] public string Folder { get; set; } = ""; // optional - for setting a specific default folder by folder path [Parameter] public int FileId { get; set; } = -1; // optional - for selecting a specific file by default [Parameter] public string Filter { get; set; } // optional - comma delimited list of file types that can be selected or uploaded ie. "jpg,gif" [Parameter] public bool ShowFiles { get; set; } = true; // optional - for indicating whether a list of files should be displayed - default is true [Parameter] public bool ShowUpload { get; set; } = true; // optional - for indicating whether a Upload controls should be displayed - default is true [Parameter] public bool ShowFolders { get; set; } = true; // optional - for indicating whether a list of folders should be displayed - default is true [Parameter] public bool ShowImage { get; set; } = true; // optional - for indicating whether an image thumbnail should be displayed - default is true [Parameter] public bool ShowProgress { get; set; } = true; // optional - for indicating whether progress info should be displayed during upload - default is true [Parameter] public bool ShowSuccess { get; set; } = false; // optional - for indicating whether a success message should be displayed upon successful upload - default is false [Parameter] public bool UploadMultiple { get; set; } = false; // optional - enable multiple file uploads - default false [Parameter] public int ChunkSize { get; set; } = 1; // optional - size of file chunks to upload in MB [Parameter] public EventCallback OnUpload { get; set; } // optional - executes a method in the calling component when a file is uploaded [Parameter] public EventCallback OnSelect { get; set; } // optional - executes a method in the calling component when a file is selected [Parameter] public EventCallback OnDelete { get; set; } // optional - executes a method in the calling component when a file is deleted protected override void OnInitialized() { // create unique id for component _guid = Guid.NewGuid().ToString("N"); _fileinputid = "FileInput_" + _guid; _progressinfoid = "ProgressInfo_" + _guid; _progressbarid = "ProgressBar_" + _guid; } protected override async Task OnParametersSetAsync() { // packages folder is a framework folder for uploading installable nuget packages if (Folder == Constants.PackagesFolder) { ShowFiles = false; ShowFolders = false; Filter = "nupkg"; ShowSuccess = true; } if (!string.IsNullOrEmpty(Folder) && Folder != Constants.PackagesFolder) { Folder folder = await FolderService.GetFolderAsync(ModuleState.SiteId, Folder); if (folder != null) { FolderId = folder.FolderId; } else { FolderId = -1; _message = "Folder Path " + Folder + " Does Not Exist"; _messagetype = MessageType.Error; } } if (ShowFolders) { _folders = await FolderService.GetFoldersAsync(ModuleState.SiteId); } else { if (FolderId != -1) { var folder = await FolderService.GetFolderAsync(FolderId); if (folder != null) { _folders = new List { folder }; } } } if (FileId != -1) { File file = await FileService.GetFileAsync(FileId); if (file != null) { FolderId = file.FolderId; } else { _message = "FileId " + FileId.ToString() + " Does Not Exist"; _messagetype = MessageType.Error; FileId = -1; // file does not exist } } await SetImage(); if (!string.IsNullOrEmpty(Filter)) { _filter = "." + Filter.Replace(",", ",."); } await GetFiles(); _initialized = true; } private async Task GetFiles() { _haseditpermission = false; if (Folder == Constants.PackagesFolder) { _haseditpermission = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host); _files = new List(); } else { Folder folder = _folders.FirstOrDefault(item => item.FolderId == FolderId); if (folder != null) { _haseditpermission = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, folder.PermissionList); if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Browse, folder.PermissionList)) { _files = await FileService.GetFilesAsync(FolderId); } else { _files = new List(); } } else { _haseditpermission = false; _files = new List(); } if (_filter != "*") { List filtered = new List(); foreach (File file in _files) { if (_filter.ToUpper().IndexOf("." + file.Extension.ToUpper()) != -1) { filtered.Add(file); } } _files = filtered; } } } private async Task FolderChanged(ChangeEventArgs e) { _message = string.Empty; try { FolderId = int.Parse((string)e.Value); await GetFiles(); FileId = -1; _file = null; _image = string.Empty; StateHasChanged(); } catch (Exception ex) { await logger.LogError(ex, "Error Loading Files {Error}", ex.Message); _message = Localizer["Error.File.Load"]; _messagetype = MessageType.Error; } } private async Task FileChanged(ChangeEventArgs e) { _message = string.Empty; FileId = int.Parse((string)e.Value); await SetImage(); await OnSelect.InvokeAsync(FileId); StateHasChanged(); } private async Task SetImage() { _image = string.Empty; _file = null; if (FileId != -1) { _file = await FileService.GetFileAsync(FileId); if (_file != null && ShowImage && _file.ImageHeight != 0 && _file.ImageWidth != 0) { var maxwidth = 200; var maxheight = 200; var ratioX = (double)maxwidth / (double)_file.ImageWidth; var ratioY = (double)maxheight / (double)_file.ImageHeight; var ratio = ratioX < ratioY ? ratioX : ratioY; _image = "\"""; } } } private async Task UploadFiles() { _message = string.Empty; var interop = new Interop(JSRuntime); var uploads = await interop.GetFiles(_fileinputid); if (uploads.Length > 0) { string restricted = ""; foreach (var upload in uploads) { var filename = upload.Split(':')[0]; var extension = (filename.LastIndexOf(".") != -1) ? filename.Substring(filename.LastIndexOf(".") + 1) : ""; if (!PageState.Site.UploadableFiles.Split(',').Contains(extension.ToLower())) { restricted += (restricted == "" ? "" : ",") + extension; } } if (restricted == "") { try { // upload the files var posturl = Utilities.TenantUrl(PageState.Alias, "/api/file/upload"); var folder = (Folder == Constants.PackagesFolder) ? Folder : FolderId.ToString(); var jwt = ""; if (PageState.Runtime == Shared.Runtime.Hybrid) { jwt = await UserService.GetTokenAsync(); if (string.IsNullOrEmpty(jwt)) { await logger.LogInformation("File Upload Failed From .NET MAUI Due To Missing Security Token. Token Options Must Be Set In User Settings."); _message = "Security Token Not Specified"; _messagetype = MessageType.Error; return; } } if (!ShowProgress) { _uploading = true; StateHasChanged(); } // upload files var success = await interop.UploadFiles(posturl, folder, _guid, SiteState.AntiForgeryToken, jwt, ChunkSize); // reset progress indicators if (ShowProgress) { await interop.SetElementAttribute(_progressinfoid, "style", "display: none;"); await interop.SetElementAttribute(_progressbarid, "style", "display: none;"); } else { _uploading = false; StateHasChanged(); } if (success) { await logger.LogInformation("File Upload Succeeded {Files}", uploads); if (ShowSuccess) { _message = Localizer["Success.File.Upload"]; _messagetype = MessageType.Success; } } else { await logger.LogInformation("File Upload Failed {Files}", uploads); _message = Localizer["Error.File.Upload"]; _messagetype = MessageType.Error; } if (Folder == Constants.PackagesFolder) { await OnUpload.InvokeAsync(-1); } else { // set FileId to first file in upload collection var file = await FileService.GetFileAsync(int.Parse(folder), uploads[0].Split(":")[0]); if (file != null) { FileId = file.FileId; await SetImage(); await OnSelect.InvokeAsync(FileId); await OnUpload.InvokeAsync(FileId); } await GetFiles(); StateHasChanged(); } } catch (Exception ex) { await logger.LogError(ex, "File Upload Failed {Error}", ex.Message); _message = Localizer["Error.File.Upload"]; _messagetype = MessageType.Error; _uploading = false; } } else { _message = string.Format(Localizer["Message.File.Restricted"], restricted); _messagetype = MessageType.Warning; } } else { _message = Localizer["Message.File.NotSelected"]; _messagetype = MessageType.Warning; } } private async Task DeleteFile() { _message = string.Empty; try { await FileService.DeleteFileAsync(FileId); await logger.LogInformation("File Deleted {File}", FileId); await OnDelete.InvokeAsync(FileId); if (ShowSuccess) { _message = Localizer["Success.File.Delete"]; _messagetype = MessageType.Success; } await GetFiles(); FileId = -1; await SetImage(); await OnSelect.InvokeAsync(FileId); StateHasChanged(); } catch (Exception ex) { await logger.LogError(ex, "Error Deleting File {File} {Error}", FileId, ex.Message); _message = Localizer["Error.File.Delete"]; _messagetype = MessageType.Error; } } public int GetFileId() => FileId; public int GetFolderId() => FolderId; public File GetFile() => _file; public async Task Refresh() { await Refresh(-1); } public async Task Refresh(int fileId) { await GetFiles(); if (fileId != -1) { var file = _files.Where(item => item.FileId == fileId).FirstOrDefault(); if (file != null) { FileId = file.FileId; await SetImage(); } } StateHasChanged(); } }