diff --git a/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs b/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs index 32317e1295..083fefed8c 100644 --- a/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs +++ b/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs @@ -36,11 +36,20 @@ public class ModulesController : Controller private readonly ISettingsManager _settingsManager; private readonly PlatformOptions _platformOptions; private readonly ExternalModuleCatalogOptions _externalModuleCatalogOptions; + private readonly LocalStorageModuleCatalogOptions _localStorageModuleCatalogOptions; private readonly IPlatformRestarter _platformRestarter; private static readonly object _lockObject = new object(); private static readonly FormOptions _defaultFormOptions = new FormOptions(); - public ModulesController(IExternalModuleCatalog externalModuleCatalog, IModuleInstaller moduleInstaller, IPushNotificationManager pushNotifier, IUserNameResolver userNameResolver, ISettingsManager settingsManager, IOptions platformOptions, IOptions externalModuleCatalogOptions, IPlatformRestarter platformRestarter) + public ModulesController(IExternalModuleCatalog externalModuleCatalog, + IModuleInstaller moduleInstaller, + IPushNotificationManager pushNotifier, + IUserNameResolver userNameResolver, + ISettingsManager settingsManager, + IOptions platformOptions, + IOptions externalModuleCatalogOptions, + IOptions localStorageModuleCatalogOptions, + IPlatformRestarter platformRestarter) { _externalModuleCatalog = externalModuleCatalog; _moduleInstaller = moduleInstaller; @@ -49,6 +58,7 @@ public ModulesController(IExternalModuleCatalog externalModuleCatalog, IModuleIn _settingsManager = settingsManager; _platformOptions = platformOptions.Value; _externalModuleCatalogOptions = externalModuleCatalogOptions.Value; + _localStorageModuleCatalogOptions = localStorageModuleCatalogOptions.Value; _platformRestarter = platformRestarter; } @@ -143,22 +153,29 @@ public ActionResult GetMissingDependencies([FromBody] Module public async Task> UploadModuleArchive() { EnsureModulesCatalogInitialized(); - ModuleDescriptor result = null; + + if (!_localStorageModuleCatalogOptions.RefreshProbingFolderOnStart) + { + return BadRequest("The process is not completed because RefreshProbingFolderOnStart is set to false."); + } + if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) { return BadRequest($"Expected a multipart request, but got {Request.ContentType}"); } + var uploadPath = Path.GetFullPath(_platformOptions.LocalUploadFolderPath); if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } - string targetFilePath = null; + ModuleDescriptor result = null; + string targetFilePath = null; var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit); var reader = new MultipartReader(boundary, HttpContext.Request.Body); - var section = await reader.ReadNextSectionAsync(); + if (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); @@ -205,6 +222,7 @@ public async Task> UploadModuleArchive() } } } + return Ok(result); } @@ -394,27 +412,42 @@ public void ModuleBackgroundJob(ModuleBackgroundJobOptions options, ModulePushNo try { notification.Started = DateTime.UtcNow; - var moduleInfos = _externalModuleCatalog.Modules.OfType() - .Where(x => options.Modules.Any(y => y.Identity.Equals(x.Identity))) - .ToArray(); - var reportProgress = new Progress(m => + + if (_localStorageModuleCatalogOptions.RefreshProbingFolderOnStart) { - lock (_lockObject) + var moduleInfos = _externalModuleCatalog.Modules.OfType() + .Where(x => options.Modules.Any(y => y.Identity.Equals(x.Identity))) + .ToArray(); + var reportProgress = new Progress(m => { - notification.Description = m.Message; - notification.ProgressLog.Add(m); - _pushNotifier.Send(notification); - } - }); + lock (_lockObject) + { + notification.Description = m.Message; + notification.ProgressLog.Add(m); + _pushNotifier.Send(notification); + } + }); - switch (options.Action) + switch (options.Action) + { + case ModuleAction.Install: + _moduleInstaller.Install(moduleInfos, reportProgress); + break; + case ModuleAction.Uninstall: + _moduleInstaller.Uninstall(moduleInfos, reportProgress); + break; + } + } + else { - case ModuleAction.Install: - _moduleInstaller.Install(moduleInfos, reportProgress); - break; - case ModuleAction.Uninstall: - _moduleInstaller.Uninstall(moduleInfos, reportProgress); - break; + notification.Finished = DateTime.UtcNow; + notification.Description = "The process is not completed because RefreshProbingFolderOnStart is set to false."; + notification.ProgressLog.Add(new ProgressMessage + { + Level = ProgressMessageLevel.Error, + Message = notification.Description, + }); + _pushNotifier.Send(notification); } } catch (Exception ex) @@ -430,7 +463,7 @@ public void ModuleBackgroundJob(ModuleBackgroundJobOptions options, ModulePushNo _settingsManager.SetValue(PlatformConstants.Settings.Setup.ModulesAutoInstallState.Name, AutoInstallState.Completed); notification.Finished = DateTime.UtcNow; - notification.Description = "Installation finished."; + notification.Description = options.Action == ModuleAction.Install ? "Installation finished." : "Uninstalling finished."; notification.ProgressLog.Add(new ProgressMessage { Level = ProgressMessageLevel.Info, diff --git a/src/VirtoCommerce.Platform.Web/wwwroot/js/app/modularity/blades/modules-main.js b/src/VirtoCommerce.Platform.Web/wwwroot/js/app/modularity/blades/modules-main.js index b2077bd5bd..6eda7d130e 100644 --- a/src/VirtoCommerce.Platform.Web/wwwroot/js/app/modularity/blades/modules-main.js +++ b/src/VirtoCommerce.Platform.Web/wwwroot/js/app/modularity/blades/modules-main.js @@ -129,10 +129,13 @@ angular.module('platformWebApp') blade.currentEntities = [ nodeExisting = { name: 'platform.blades.modules-main.labels.browse', mode: 'browse' }, nodeInstalled = { name: 'platform.blades.modules-main.labels.installed', mode: 'installed' }, - nodeUpdate = { name: 'platform.blades.modules-main.labels.updates', mode: 'update' }, - { name: 'platform.blades.modules-main.labels.advanced', mode: 'advanced' } + nodeUpdate = { name: 'platform.blades.modules-main.labels.updates', mode: 'update' } ]; + if ($scope.allowInstallModules) { + blade.currentEntities.push({ name: 'platform.blades.modules-main.labels.advanced', mode: 'advanced' }); + } + var nodeWithErrors = { name: 'platform.blades.modules-main.labels.withErrors', mode: 'withErrors' }; var openFirstBladeInitially = _.once(function () { blade.openBlade(blade.currentEntities[0]); });