diff --git a/src/applications/Mixcore/Controllers/AppController.cs b/src/applications/Mixcore/Controllers/AppController.cs index 1383d76d2..b4d9b6686 100644 --- a/src/applications/Mixcore/Controllers/AppController.cs +++ b/src/applications/Mixcore/Controllers/AppController.cs @@ -58,7 +58,7 @@ public async Task Index(string baseRoute) { if (IsValid) { - return await App(baseRoute); + return await App($"/app/{baseRoute}"); } else { diff --git a/src/applications/Mixcore/wwwroot/mix-app/views/app-portal/pages/application/list.html b/src/applications/Mixcore/wwwroot/mix-app/views/app-portal/pages/application/list.html index 9ea1f2752..cc5c53e0a 100644 --- a/src/applications/Mixcore/wwwroot/mix-app/views/app-portal/pages/application/list.html +++ b/src/applications/Mixcore/wwwroot/mix-app/views/app-portal/pages/application/list.html @@ -1 +1 @@ -
Display NameSystem NamePrimary DomainCreatedAuthor
{{item.createdDateTime | utcToLocal:'dd.MM.yy hh:mm a'}}{{item.createdBy}}🟢 🟡 🔴 ⚫️
\ No newline at end of file +
Display NameSystem NamePrimary DomainCreatedAuthor
{{item.createdDateTime | utcToLocal:'dd.MM.yy hh:mm a'}}{{item.createdBy}}🟢 🟡 🔴 ⚫️
\ No newline at end of file diff --git a/src/modules/mix.portal/Controllers/MixApplicationController.cs b/src/modules/mix.portal/Controllers/MixApplicationController.cs index ee9170985..a2b597516 100644 --- a/src/modules/mix.portal/Controllers/MixApplicationController.cs +++ b/src/modules/mix.portal/Controllers/MixApplicationController.cs @@ -46,6 +46,14 @@ public async Task> Install([FromBody] MixA await _applicationService.Install(app, cancellationToken); return base.Ok(app); } + + [HttpPost] + [Route("restore-package")] + public async Task> Restore([FromBody] RestoreMixApplicationPackageDto dto, CancellationToken cancellationToken = default) + { + MixApplicationViewModel app = await _applicationService.RestorePackage(dto, cancellationToken); + return base.Ok(app); + } #endregion @@ -64,7 +72,7 @@ protected override async Task> Sear var result = await base.SearchHandler(req, cancellationToken); foreach (var item in result.Items) { - item.DetailUrl = $"{CurrentTenant.PrimaryDomain}/app/{item.BaseRoute}"; + item.DetailUrl = $"{CurrentTenant.PrimaryDomain}{item.BaseRoute}"; } return result; } diff --git a/src/modules/mix.portal/Domain/Dtos/RestoreMixApplicationPackageDto.cs b/src/modules/mix.portal/Domain/Dtos/RestoreMixApplicationPackageDto.cs new file mode 100644 index 000000000..b66cff7dc --- /dev/null +++ b/src/modules/mix.portal/Domain/Dtos/RestoreMixApplicationPackageDto.cs @@ -0,0 +1,8 @@ +namespace Mix.Portal.Domain.Dtos +{ + public sealed class RestoreMixApplicationPackageDto + { + public int AppId { get; set; } + public string PackageFilePath { get; set; } + } +} diff --git a/src/modules/mix.portal/Domain/Interfaces/IMixApplicationService.cs b/src/modules/mix.portal/Domain/Interfaces/IMixApplicationService.cs index 4805d8ef1..5eedbdbf8 100644 --- a/src/modules/mix.portal/Domain/Interfaces/IMixApplicationService.cs +++ b/src/modules/mix.portal/Domain/Interfaces/IMixApplicationService.cs @@ -8,5 +8,6 @@ public interface IMixApplicationService public Task UpdatePackage(MixApplicationViewModel app, string pakageFilePath, CancellationToken cancellationToken = default); public Task AlertAsync(IClientProxy clients, string action, int status, T message); + Task RestorePackage(RestoreMixApplicationPackageDto dto, CancellationToken cancellationToken); } } diff --git a/src/modules/mix.portal/Domain/Services/MixApplicationService.cs b/src/modules/mix.portal/Domain/Services/MixApplicationService.cs index a4fc9ad56..5cd4228ef 100644 --- a/src/modules/mix.portal/Domain/Services/MixApplicationService.cs +++ b/src/modules/mix.portal/Domain/Services/MixApplicationService.cs @@ -7,6 +7,7 @@ using Mix.Shared.Services; using Mix.SignalR.Constants; using Mix.SignalR.Hubs; +using System.IO.Packaging; using System.Text.RegularExpressions; namespace Mix.Portal.Domain.Services @@ -45,7 +46,7 @@ public async Task Install(MixApplicationViewModel app, string filePath = await DownloadPackage(name, app.PackageFilePath, appFolder); MixFileHelper.UnZipFile(filePath, appFolder); - var template = await CreateTemplate(name, appFolder, app.BaseRoute); + var template = await SaveTemplate(app.TemplateId, name, appFolder, app.BaseRoute); if (template != null) { app.SetUowInfo(_cmsUow, CacheService); @@ -60,7 +61,7 @@ public async Task Install(MixApplicationViewModel app, return null; } - private async Task CreateTemplate(string name, string appFolder, string baseRoute) + private async Task SaveTemplate(int? templateId, string name, string appFolder, string baseRoute) { try { @@ -79,19 +80,20 @@ private async Task CreateTemplate(string name, string appF .Replace("options['baseHref']", $"'{appFolder}'"); var activeTheme = await _themeService.GetActiveTheme(); - MixTemplateViewModel template = new(_cmsUow) + MixTemplateViewModel template = await MixTemplateViewModel.GetRepository(_cmsUow, CacheService).GetSingleAsync(m => m.Id == templateId); + template ??= new(_cmsUow) { MixThemeId = activeTheme.Id, FileName = name, FileFolder = $"{MixFolders.TemplatesFolder}/{CurrentTenant.SystemName}/{activeTheme.SystemName}/{MixTemplateFolderType.Pages}", FolderType = MixTemplateFolderType.Pages, Extension = MixFileExtensions.CsHtml, - Content = indexFile.Content.Replace("@", "@@"), MixTenantId = CurrentTenant.Id, Scripts = string.Empty, Styles = string.Empty, CreatedBy = _mixIdentityService.GetClaim(HttpContextAccessor.HttpContext.User, MixClaims.Username) }; + template.Content = indexFile.Content.Replace("@", "@@"); await template.SaveAsync(); _queueService.PushQueue(CurrentTenant.Id, MixQueueTopics.MixViewModelChanged, MixRestAction.Post.ToString(), template); MixFileHelper.SaveFile(indexFile); @@ -122,10 +124,11 @@ private async Task DownloadPackage(string name, string packageUrl, strin } }; var cancellationToken = new CancellationToken(); - - string filePath = $"{appFolder}/{name}-{DateTime.UtcNow.ToString("dd-MM-yyyy-hh:mm:ss")}{MixFileExtensions.Zip}"; - await _httpService.DownloadAsync(packageUrl, appFolder, name, MixFileExtensions.Zip, progress, cancellationToken); - + + string fileName = $"{name}-{DateTime.UtcNow.ToString("dd-MM-yyyy-hh-mm-ss")}"; + string filePath = $"{appFolder}/{fileName}{MixFileExtensions.Zip}"; + await _httpService.DownloadAsync(packageUrl, appFolder, fileName, MixFileExtensions.Zip, progress, cancellationToken); + return filePath; } catch (Exception ex) @@ -144,11 +147,11 @@ public async Task UpdatePackage(MixApplicationViewModel } var packages = app.AppSettings.Value("packages") ?? new(); - + string appFolder = $"{MixFolders.StaticFiles}/{MixFolders.MixApplications}/{app.DisplayName}"; string package = await DownloadPackage(app.DisplayName, app.PackageFilePath, appFolder); MixFileHelper.UnZipFile(package, appFolder); - + var template = await SaveTemplate(app.TemplateId, app.DisplayName, appFolder, app.BaseRoute); packages.Add(package); app.AppSettings["activePackage"] = package; app.AppSettings["packages"] = packages; @@ -158,7 +161,40 @@ public async Task UpdatePackage(MixApplicationViewModel { throw; } - catch(Exception ex) + catch (Exception ex) + { + throw new MixException(MixErrorStatus.Badrequest, ex); + } + } + + public async Task RestorePackage(RestoreMixApplicationPackageDto dto, CancellationToken cancellationToken) + { + try + { + var app = await MixApplicationViewModel.GetRepository(_cmsUow, CacheService).GetSingleAsync(m => m.Id == dto.AppId); + if (app == null) + { + throw new MixException(MixErrorStatus.NotFound, "App Not Found"); + } + if (!File.Exists(dto.PackageFilePath)) + { + throw new MixException(MixErrorStatus.NotFound, $"Package {dto.PackageFilePath} Not Found"); + } + + string appFolder = $"{MixFolders.StaticFiles}/{MixFolders.MixApplications}/{app.DisplayName}"; + MixFileHelper.UnZipFile(dto.PackageFilePath, appFolder); + var template = await SaveTemplate(app.TemplateId, app.DisplayName, appFolder, app.BaseRoute); + app.AppSettings["activePackage"] = dto.PackageFilePath; + + await app.SaveAsync(cancellationToken); + + return app; + } + catch (MixException) + { + throw; + } + catch (Exception ex) { throw new MixException(MixErrorStatus.Badrequest, ex); } @@ -190,6 +226,8 @@ public async Task AlertAsync(IClientProxy clients, string action, int status, await clients.SendAsync( HubMethods.ReceiveMethod, logMsg.ToString(Formatting.None)); } + + #endregion } }