From eb6be17333e18f72541c61a2f1f22d3806269dc4 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 12:32:43 +0300 Subject: [PATCH 01/14] Backup: removed notify reference --- .../ASC.Data.Backup/ASC.Data.Backup.csproj | 2 +- .../ASC.Data.Backup/Core/NotifyHelper.cs | 166 ++++++++++++------ .../ASC.Data.Backup/Service/BackupWorker.cs | 22 +-- web/ASC.Web.Core/Notify/Actions.cs | 6 +- .../Notify/StudioNotifyService.cs | 78 +------- web/ASC.Web.Core/Notify/Tags.cs | 2 +- 6 files changed, 132 insertions(+), 144 deletions(-) diff --git a/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj index 8a5e267b9c..50fd239cea 100644 --- a/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj +++ b/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj @@ -26,10 +26,10 @@ + - diff --git a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs index 920897eb64..2d0abf8120 100644 --- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs +++ b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs @@ -25,79 +25,141 @@ using System; +using System.Linq; + using ASC.Common; -using ASC.Common.Logging; -using Microsoft.Extensions.Options; -using ASC.Notify; - +using ASC.Core; +using ASC.Core.Notify; +using ASC.Core.Tenants; +using ASC.Core.Users; +using ASC.Notify.Model; +using ASC.Notify.Patterns; +using ASC.Notify.Recipients; +using ASC.Web.Core.Users; +using ASC.Web.Studio.Core.Notify; +using ASC.Web.Studio.Utility; + +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Data.Backup { public class NotifyHelper - { - private const string NotifyService = "ASC.Web.Studio.Core.Notify.StudioNotifyService, ASC.Web.Studio"; - private const string MethodTransferStart = "MigrationPortalStart"; - private const string MethodTransferCompleted = "MigrationPortalSuccess"; - private const string MethodTransferError = "MigrationPortalError"; - private const string MethodBackupCompleted = "SendMsgBackupCompleted"; - private const string MethodRestoreStarted = "SendMsgRestoreStarted"; - private const string MethodRestoreCompleted = "SendMsgRestoreCompleted"; - private readonly ILog log; - private readonly NotifyService notifyService; + { + public IServiceProvider ServiceProvider { get; } + + public NotifyHelper(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } - public NotifyHelper(IOptionsMonitor options, NotifyService notifyService) - { - this.notifyService = notifyService; - log = options.CurrentValue; - } - public void SendAboutTransferStart(int tenantId, string targetRegion, bool notifyUsers) - { - SendNotification(MethodTransferStart, tenantId, targetRegion, notifyUsers); + public void SendAboutTransferStart(Tenant tenant, string targetRegion, bool notifyUsers) + { + MigrationNotify(tenant, Actions.MigrationPortalStart, targetRegion, string.Empty, notifyUsers); } - public void SendAboutTransferComplete(int tenantId, string targetRegion, string targetAddress, bool notifyOnlyOwner) - { - SendNotification(MethodTransferCompleted, tenantId, targetRegion, targetAddress, !notifyOnlyOwner); + public void SendAboutTransferComplete(Tenant tenant, string targetRegion, string targetAddress, bool notifyOnlyOwner) + { + MigrationNotify(tenant, Actions.MigrationPortalSuccess, targetRegion, targetAddress, !notifyOnlyOwner); } - public void SendAboutTransferError(int tenantId, string targetRegion, string resultAddress, bool notifyOnlyOwner) - { - SendNotification(MethodTransferError, tenantId, targetRegion, resultAddress, !notifyOnlyOwner); + public void SendAboutTransferError(Tenant tenant, string targetRegion, string resultAddress, bool notifyOnlyOwner) + { + MigrationNotify(tenant, !string.IsNullOrEmpty(targetRegion) ? Actions.MigrationPortalError : Actions.MigrationPortalServerFailure, targetRegion, resultAddress, !notifyOnlyOwner); } - public void SendAboutBackupCompleted(int tenantId, Guid userId, string link) - { - SendNotification(MethodBackupCompleted, tenantId, userId, link); + public void SendAboutBackupCompleted(Guid userId) + { + using var scope = ServiceProvider.CreateScope(); + var userManager = scope.ServiceProvider.GetService(); + var studioNotifyHelper = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); + var displayUserSettingsHelper = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + client.SendNoticeToAsync( + Actions.BackupCreated, + new[] { studioNotifyHelper.ToRecipient(userId) }, + new[] { StudioNotifyService.EMailSenderName }, + new TagValue(Tags.OwnerName, userManager.GetUsers(userId).DisplayUserName(displayUserSettingsHelper))); } - public void SendAboutRestoreStarted(int tenantId, bool notifyAllUsers) - { - SendNotification(MethodRestoreStarted, tenantId, notifyAllUsers); + public void SendAboutRestoreStarted(Tenant tenant, bool notifyAllUsers) + { + using var scope = ServiceProvider.CreateScope(); + var userManager = scope.ServiceProvider.GetService(); + var studioNotifyHelper = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); + var displayUserSettingsHelper = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var owner = userManager.GetUsers(tenant.OwnerId); + var users = + notifyAllUsers + ? studioNotifyHelper.RecipientFromEmail(userManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false) + : owner.ActivationStatus == EmployeeActivationStatus.Activated ? studioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0]; + + client.SendNoticeToAsync( + Actions.RestoreStarted, + users, + new[] { StudioNotifyService.EMailSenderName }); } - public void SendAboutRestoreCompleted(int tenantId, bool notifyAllUsers) - { - SendNotification(MethodRestoreCompleted, tenantId, notifyAllUsers); - } - - private void SendNotification(string method, int tenantId, params object[] args) - { - try - { - notifyService.InvokeSendMethod(NotifyService, method, tenantId, args); - } - catch (Exception error) - { - log.Warn("Error while sending notification", error); - } + public void SendAboutRestoreCompleted(Tenant tenant, bool notifyAllUsers) + { + using var scope = ServiceProvider.CreateScope(); + var userManager = scope.ServiceProvider.GetService(); + var studioNotifyHelper = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); + var displayUserSettingsHelper = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var owner = userManager.GetUsers(tenant.OwnerId); + + var users = + notifyAllUsers + ? userManager.GetUsers(EmployeeStatus.Active).Select(u => studioNotifyHelper.ToRecipient(u.ID)).ToArray() + : new[] { studioNotifyHelper.ToRecipient(owner.ID) }; + + client.SendNoticeToAsync( + Actions.RestoreCompleted, + users, + new[] { StudioNotifyService.EMailSenderName }, + new TagValue(Tags.OwnerName, owner.DisplayUserName(displayUserSettingsHelper))); + } + + private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify) + { + using var scope = ServiceProvider.CreateScope(); + var userManager = scope.ServiceProvider.GetService(); + var studioNotifyHelper = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var users = userManager.GetUsers() + .Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant)) + .Select(u => studioNotifyHelper.ToRecipient(u.ID)) + .ToArray(); + + if (users.Any()) + { + client.SendNoticeToAsync( + action, + users, + new[] { StudioNotifyService.EMailSenderName }, + new TagValue(Tags.RegionName, TransferResourceHelper.GetRegionDescription(region)), + new TagValue(Tags.PortalUrl, url)); + } } } public static class NotifyHelperExtension { public static DIHelper AddNotifyHelperService(this DIHelper services) { - services.TryAddScoped(); - return services - .AddNotifyService(); + services.TryAddSingleton(); + return services + .AddUserManagerService() + .AddStudioNotifyHelperService() + .AddDisplayUserSettingsService(); } } } diff --git a/common/services/ASC.Data.Backup/Service/BackupWorker.cs b/common/services/ASC.Data.Backup/Service/BackupWorker.cs index 6a5397514b..9230e01619 100644 --- a/common/services/ASC.Data.Backup/Service/BackupWorker.cs +++ b/common/services/ASC.Data.Backup/Service/BackupWorker.cs @@ -376,7 +376,8 @@ namespace ASC.Data.Backup.Service var backupWorker = scope.ServiceProvider.GetService(); - var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", tenantManager.GetTenant(TenantId).TenantAlias, DateTime.UtcNow, ArchiveFormat); + var tenant = tenantManager.GetTenant(TenantId); + var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", tenant.TenantAlias, DateTime.UtcNow, ArchiveFormat); var tempFile = Path.Combine(TempFolder, backupName); var storagePath = tempFile; try @@ -424,7 +425,7 @@ namespace ASC.Data.Backup.Service if (UserId != Guid.Empty && !IsScheduled) { - notifyHelper.SendAboutBackupCompleted(TenantId, UserId, Link); + notifyHelper.SendAboutBackupCompleted(UserId); } IsCompleted = true; @@ -503,13 +504,13 @@ namespace ASC.Data.Backup.Service var tempFile = PathHelper.GetTempFileName(TempFolder); try { - notifyHelper.SendAboutRestoreStarted(TenantId, Notify); + tenant = tenantManager.GetTenant(TenantId); + notifyHelper.SendAboutRestoreStarted(tenant, Notify); var storage = backupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); storage.Download(StoragePath, tempFile); Percentage = 10; - tenant = tenantManager.GetTenant(TenantId); tenant.SetStatus(TenantStatus.Restoring); tenantManager.SaveTenant(tenant); @@ -536,7 +537,7 @@ namespace ASC.Data.Backup.Service var tenants = tenantManager.GetTenants(); foreach (var t in tenants) { - notifyHelper.SendAboutRestoreCompleted(t.TenantId, Notify); + notifyHelper.SendAboutRestoreCompleted(t, Notify); } } } @@ -557,7 +558,7 @@ namespace ASC.Data.Backup.Service // sleep until tenants cache expires Thread.Sleep(TimeSpan.FromMinutes(2)); - notifyHelper.SendAboutRestoreCompleted(restoredTenant.TenantId, Notify); + notifyHelper.SendAboutRestoreCompleted(restoredTenant, Notify); } Percentage = 75; @@ -649,11 +650,12 @@ namespace ASC.Data.Backup.Service var backupWorker = scope.ServiceProvider.GetService(); var tempFile = PathHelper.GetTempFileName(TempFolder); - var alias = tenantManager.GetTenant(TenantId).TenantAlias; + var tenant = tenantManager.GetTenant(TenantId); + var alias = tenant.TenantAlias; try { - notifyHelper.SendAboutTransferStart(TenantId, TargetRegion, Notify); + notifyHelper.SendAboutTransferStart(tenant, TargetRegion, Notify); var transferProgressItem = scope.ServiceProvider.GetService(); transferProgressItem.Init(TenantId, ConfigPaths[CurrentRegion], ConfigPaths[TargetRegion], Limit, TempFolder); transferProgressItem.ProgressChanged += (sender, args) => @@ -668,7 +670,7 @@ namespace ASC.Data.Backup.Service transferProgressItem.RunJob(); Link = GetLink(alias, false); - notifyHelper.SendAboutTransferComplete(TenantId, TargetRegion, Link, !Notify); + notifyHelper.SendAboutTransferComplete(tenant, TargetRegion, Link, !Notify); } catch (Exception error) { @@ -676,7 +678,7 @@ namespace ASC.Data.Backup.Service Error = error; Link = GetLink(alias, true); - notifyHelper.SendAboutTransferError(TenantId, TargetRegion, Link, !Notify); + notifyHelper.SendAboutTransferError(tenant, TargetRegion, Link, !Notify); } finally { diff --git a/web/ASC.Web.Core/Notify/Actions.cs b/web/ASC.Web.Core/Notify/Actions.cs index ba43919d91..2e637686a0 100644 --- a/web/ASC.Web.Core/Notify/Actions.cs +++ b/web/ASC.Web.Core/Notify/Actions.cs @@ -28,7 +28,7 @@ using ASC.Notify.Model; namespace ASC.Web.Studio.Core.Notify { - static class Actions + public static class Actions { public static readonly INotifyAction AdminNotify = new NotifyAction("admin_notify", "admin notifications"); public static readonly INotifyAction PeriodicNotify = new NotifyAction("periodic_notify", "periodic notifications"); @@ -49,8 +49,8 @@ namespace ASC.Web.Studio.Core.Notify public static readonly INotifyAction RestoreCompleted = new NotifyAction("restore_completed", "restore_completed"); public static readonly INotifyAction PortalDeactivate = new NotifyAction("portal_deactivate", "portal deactivate"); public static readonly INotifyAction PortalDelete = new NotifyAction("portal_delete", "portal delete"); - public static readonly INotifyAction PortalDeleteSuccessV10 = new NotifyAction("portal_delete_success_v10"); - + public static readonly INotifyAction PortalDeleteSuccessV10 = new NotifyAction("portal_delete_success_v10"); + public static readonly INotifyAction ProfileDelete = new NotifyAction("profile_delete", "profile_delete"); public static readonly INotifyAction ProfileHasDeletedItself = new NotifyAction("profile_has_deleted_itself", "profile_has_deleted_itself"); public static readonly INotifyAction ReassignsCompleted = new NotifyAction("reassigns_completed", "reassigns_completed"); diff --git a/web/ASC.Web.Core/Notify/StudioNotifyService.cs b/web/ASC.Web.Core/Notify/StudioNotifyService.cs index 78cc8fa97a..e31f5050cb 100644 --- a/web/ASC.Web.Core/Notify/StudioNotifyService.cs +++ b/web/ASC.Web.Core/Notify/StudioNotifyService.cs @@ -58,7 +58,7 @@ namespace ASC.Web.Studio.Core.Notify { private readonly StudioNotifyServiceHelper client; - private static string EMailSenderName { get { return ASC.Core.Configuration.Constants.NotifyEMailSenderSysName; } } + public static string EMailSenderName { get { return ASC.Core.Configuration.Constants.NotifyEMailSenderSysName; } } private UserManager UserManager { get; } private StudioNotifyHelper StudioNotifyHelper { get; } @@ -653,49 +653,6 @@ namespace ASC.Web.Studio.Core.Notify tagValues.ToArray()); } - #region Backup & Restore - - public void SendMsgBackupCompleted(Guid userId, string link) - { - client.SendNoticeToAsync( - Actions.BackupCreated, - new[] { StudioNotifyHelper.ToRecipient(userId) }, - new[] { EMailSenderName }, - new TagValue(Tags.OwnerName, UserManager.GetUsers(userId).DisplayUserName(DisplayUserSettingsHelper))); - } - - public void SendMsgRestoreStarted(Tenant tenant, bool notifyAllUsers) - { - var owner = UserManager.GetUsers(tenant.OwnerId); - var users = - notifyAllUsers - ? StudioNotifyHelper.RecipientFromEmail(UserManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false) - : owner.ActivationStatus == EmployeeActivationStatus.Activated ? StudioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0]; - - client.SendNoticeToAsync( - Actions.RestoreStarted, - users, - new[] { EMailSenderName }); - } - - public void SendMsgRestoreCompleted(Tenant tenant, bool notifyAllUsers) - { - var owner = UserManager.GetUsers(tenant.OwnerId); - - var users = - notifyAllUsers - ? UserManager.GetUsers(EmployeeStatus.Active).Select(u => StudioNotifyHelper.ToRecipient(u.ID)).ToArray() - : new[] { StudioNotifyHelper.ToRecipient(owner.ID) }; - - client.SendNoticeToAsync( - Actions.RestoreCompleted, - users, - new[] { EMailSenderName }, - new TagValue(Tags.OwnerName, owner.DisplayUserName(DisplayUserSettingsHelper))); - } - - #endregion - #region Portal Deactivation & Deletion public void SendMsgPortalDeactivation(Tenant t, string deactivateUrl, string activateUrl) @@ -861,39 +818,6 @@ namespace ASC.Web.Studio.Core.Notify #region Migration Portal - public void MigrationPortalStart(Tenant tenant, string region, bool notify) - { - MigrationNotify(tenant, Actions.MigrationPortalStart, region, string.Empty, notify); - } - - public void MigrationPortalSuccess(Tenant tenant, string region, string url, bool notify) - { - MigrationNotify(tenant, Actions.MigrationPortalSuccess, region, url, notify); - } - - public void MigrationPortalError(Tenant tenant, string region, string url, bool notify) - { - MigrationNotify(tenant, !string.IsNullOrEmpty(region) ? Actions.MigrationPortalError : Actions.MigrationPortalServerFailure, region, url, notify); - } - - private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify) - { - var users = UserManager.GetUsers() - .Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant)) - .Select(u => StudioNotifyHelper.ToRecipient(u.ID)) - .ToArray(); - - if (users.Any()) - { - client.SendNoticeToAsync( - action, - users, - new[] { EMailSenderName }, - new TagValue(Tags.RegionName, TransferResourceHelper.GetRegionDescription(region)), - new TagValue(Tags.PortalUrl, url)); - } - } - public void PortalRenameNotify(Tenant tenant, string oldVirtualRootPath) { var users = UserManager.GetUsers() diff --git a/web/ASC.Web.Core/Notify/Tags.cs b/web/ASC.Web.Core/Notify/Tags.cs index 76e364b95e..d6eb5c9bd5 100644 --- a/web/ASC.Web.Core/Notify/Tags.cs +++ b/web/ASC.Web.Core/Notify/Tags.cs @@ -25,7 +25,7 @@ namespace ASC.Web.Studio.Core.Notify { - static class Tags + public static class Tags { public const string UserName = "UserName"; public const string UserLastName = "UserLastName"; From 4a848ea535cd045452e6a75ea40a3649689e3505 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 15:15:09 +0300 Subject: [PATCH 02/14] Backup: notify fix --- .../ASC.Data.Backup/BackupServiceLauncher.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/common/services/ASC.Data.Backup/BackupServiceLauncher.cs b/common/services/ASC.Data.Backup/BackupServiceLauncher.cs index 66adcb4ba3..bf8dd87b3d 100644 --- a/common/services/ASC.Data.Backup/BackupServiceLauncher.cs +++ b/common/services/ASC.Data.Backup/BackupServiceLauncher.cs @@ -24,32 +24,37 @@ */ +using System; using System.Threading; using System.Threading.Tasks; using ASC.Common; using ASC.Common.Utils; - +using ASC.Web.Studio.Core.Notify; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; namespace ASC.Data.Backup.Service { internal class BackupServiceLauncher : IHostedService - { + { + public IServiceProvider ServiceProvider { get; } private BackupCleanerService CleanerService { get; set; } private BackupSchedulerService SchedulerService { get; set; } private BackupWorker BackupWorker { get; set; } private IConfiguration Configuration { get; set; } public BackupServiceNotifier BackupServiceNotifier { get; } - public BackupServiceLauncher( + public BackupServiceLauncher( + IServiceProvider serviceProvider, BackupCleanerService cleanerService, BackupSchedulerService schedulerService, BackupWorker backupWorker, IConfiguration configuration, BackupServiceNotifier backupServiceNotifier) - { + { + ServiceProvider = serviceProvider; CleanerService = cleanerService; SchedulerService = schedulerService; BackupWorker = backupWorker; @@ -58,7 +63,9 @@ namespace ASC.Data.Backup.Service } public Task StartAsync(CancellationToken cancellationToken) - { + { + NotifyConfiguration.Configure(ServiceProvider); + var settings = Configuration.GetSetting("backup"); BackupWorker.Start(settings); From 3f97755c929a701a2058785e7fda035b4f62a8a1 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 15:45:38 +0300 Subject: [PATCH 03/14] Backup: fix notify --- .../ASC.Data.Backup/Core/NotifyHelper.cs | 4 ++- .../ASC.Data.Backup/Service/BackupWorker.cs | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs index 2d0abf8120..088aa011f5 100644 --- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs +++ b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs @@ -155,8 +155,10 @@ namespace ASC.Data.Backup { public static DIHelper AddNotifyHelperService(this DIHelper services) { - services.TryAddSingleton(); + services.TryAddSingleton(); + return services + .AddStudioNotifySourceService() .AddUserManagerService() .AddStudioNotifyHelperService() .AddDisplayUserSettingsService(); diff --git a/common/services/ASC.Data.Backup/Service/BackupWorker.cs b/common/services/ASC.Data.Backup/Service/BackupWorker.cs index 9230e01619..8efe6f5ffd 100644 --- a/common/services/ASC.Data.Backup/Service/BackupWorker.cs +++ b/common/services/ASC.Data.Backup/Service/BackupWorker.cs @@ -429,6 +429,7 @@ namespace ASC.Data.Backup.Service } IsCompleted = true; + backupWorker.PublishProgress(this); } catch (Exception error) { @@ -438,6 +439,15 @@ namespace ASC.Data.Backup.Service } finally { + try + { + backupWorker.PublishProgress(this); + } + catch (Exception error) + { + Log.Error("publish", error); + } + try { if (!(storagePath == tempFile && StorageType == BackupStorageType.Local)) @@ -563,9 +573,12 @@ namespace ASC.Data.Backup.Service Percentage = 75; + backupWorker.PublishProgress(this); + File.Delete(tempFile); Percentage = 100; + backupWorker.PublishProgress(this); } catch (Exception error) { @@ -580,6 +593,15 @@ namespace ASC.Data.Backup.Service } finally { + try + { + backupWorker.PublishProgress(this); + } + catch (Exception error) + { + Log.Error("publish", error); + } + if (File.Exists(tempFile)) { File.Delete(tempFile); @@ -671,6 +693,7 @@ namespace ASC.Data.Backup.Service Link = GetLink(alias, false); notifyHelper.SendAboutTransferComplete(tenant, TargetRegion, Link, !Notify); + backupWorker.PublishProgress(this); } catch (Exception error) { @@ -682,6 +705,15 @@ namespace ASC.Data.Backup.Service } finally { + try + { + backupWorker.PublishProgress(this); + } + catch (Exception error) + { + Log.Error("publish", error); + } + if (File.Exists(tempFile)) { File.Delete(tempFile); From d7cb638a1ed44b62ca29e1f12d9c6867e79fe361 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 15:58:56 +0300 Subject: [PATCH 04/14] Backup: notify fix --- common/services/ASC.Data.Backup/Core/NotifyHelper.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs index 088aa011f5..4ac8e56eea 100644 --- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs +++ b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs @@ -29,7 +29,6 @@ using System.Linq; using ASC.Common; using ASC.Core; -using ASC.Core.Notify; using ASC.Core.Tenants; using ASC.Core.Users; using ASC.Notify.Model; @@ -72,7 +71,7 @@ namespace ASC.Data.Backup using var scope = ServiceProvider.CreateScope(); var userManager = scope.ServiceProvider.GetService(); var studioNotifyHelper = scope.ServiceProvider.GetService(); - var notifySource = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); var displayUserSettingsHelper = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -88,7 +87,7 @@ namespace ASC.Data.Backup using var scope = ServiceProvider.CreateScope(); var userManager = scope.ServiceProvider.GetService(); var studioNotifyHelper = scope.ServiceProvider.GetService(); - var notifySource = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); var displayUserSettingsHelper = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -109,7 +108,7 @@ namespace ASC.Data.Backup using var scope = ServiceProvider.CreateScope(); var userManager = scope.ServiceProvider.GetService(); var studioNotifyHelper = scope.ServiceProvider.GetService(); - var notifySource = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); var displayUserSettingsHelper = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -132,7 +131,7 @@ namespace ASC.Data.Backup using var scope = ServiceProvider.CreateScope(); var userManager = scope.ServiceProvider.GetService(); var studioNotifyHelper = scope.ServiceProvider.GetService(); - var notifySource = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); var users = userManager.GetUsers() From feedc8a1b090eb325fc0b839a509e6d2aa36afdd Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 16:53:55 +0300 Subject: [PATCH 05/14] Core: fix --- web/ASC.Web.Core/ASC.Web.Core.csproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/ASC.Web.Core/ASC.Web.Core.csproj b/web/ASC.Web.Core/ASC.Web.Core.csproj index 5303f4e2fe..d245f2c7ba 100644 --- a/web/ASC.Web.Core/ASC.Web.Core.csproj +++ b/web/ASC.Web.Core/ASC.Web.Core.csproj @@ -20,6 +20,14 @@ + + + + + + + + From b035a6347e3fff829eb15f7d8a3630eba5b2f8e0 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 17:49:15 +0300 Subject: [PATCH 06/14] Notify: fix --- .../Notify/Engine/NotifyEngine.cs | 7 +- ...WebstudioNotifyPatternResource.Designer.cs | 785 +++++++----------- 2 files changed, 323 insertions(+), 469 deletions(-) diff --git a/common/ASC.Core.Common/Notify/Engine/NotifyEngine.cs b/common/ASC.Core.Common/Notify/Engine/NotifyEngine.cs index 394fc6d834..3f7b612829 100644 --- a/common/ASC.Core.Common/Notify/Engine/NotifyEngine.cs +++ b/common/ASC.Core.Common/Notify/Engine/NotifyEngine.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; + using ASC.Common.Logging; using ASC.Common.Notify.Patterns; using ASC.Notify.Channels; @@ -36,6 +37,7 @@ using ASC.Notify.Cron; using ASC.Notify.Messages; using ASC.Notify.Patterns; using ASC.Notify.Recipients; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -360,9 +362,10 @@ namespace ASC.Notify.Engine PrepareRequestFillPatterns(request); PrepareRequestFillTags(request); } - catch (Exception) + catch (Exception ex) { - responses.Add(new SendResponse(request.NotifyAction, null, request.Recipient, SendResult.Impossible)); + responses.Add(new SendResponse(request.NotifyAction, null, request.Recipient, SendResult.Impossible)); + log.Error("Prepare", ex); } if (request.SenderNames != null && request.SenderNames.Length > 0) diff --git a/web/ASC.Web.Core/PublicResources/WebstudioNotifyPatternResource.Designer.cs b/web/ASC.Web.Core/PublicResources/WebstudioNotifyPatternResource.Designer.cs index 96d29c9625..936eb3fbcb 100644 --- a/web/ASC.Web.Core/PublicResources/WebstudioNotifyPatternResource.Designer.cs +++ b/web/ASC.Web.Core/PublicResources/WebstudioNotifyPatternResource.Designer.cs @@ -105,15 +105,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to CRM task was created at. - /// - internal static string ActionCreateCrmTask { - get { - return ResourceManager.GetString("ActionCreateCrmTask", resourceCulture); - } - } - /// /// Looks up a localized string similar to CRM opportunity was created at. /// @@ -411,15 +402,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to Move Right Now. - /// - internal static string ButtonMoveRightNow { - get { - return ResourceManager.GetString("ButtonMoveRightNow", resourceCulture); - } - } - /// /// Looks up a localized string similar to Remove profile. /// @@ -492,87 +474,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to Add your email account to ${LetterLogoText} Mail and manage all correspondence in one place. - /// - internal static string ItemAddEmailAccount { - get { - return ResourceManager.GetString("ItemAddEmailAccount", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Connect cloud storages you use to ONLYOFFICE to create a single workspace for all your docs.. - /// - internal static string ItemAddFilesCreatWorkspace { - get { - return ResourceManager.GetString("ItemAddFilesCreatWorkspace", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Add your email account and manage all correspondence in one place. - /// - internal static string ItemAddTeamlabMail { - get { - return ResourceManager.GetString("ItemAddTeamlabMail", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Explore different ways of co-authoring documents - real-time co-editing, chat, comments, review.. - /// - internal static string ItemCoAuthoringDocuments { - get { - return ResourceManager.GetString("ItemCoAuthoringDocuments", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Create a single workspace for all your docs. - /// - internal static string ItemCreateWorkspaceDocs { - get { - return ResourceManager.GetString("ItemCreateWorkspaceDocs", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Import projects. - /// - internal static string ItemImportProjects { - get { - return ResourceManager.GetString("ItemImportProjects", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Import projects from Basecamp. - /// - internal static string ItemImportProjectsBasecamp { - get { - return ResourceManager.GetString("ItemImportProjectsBasecamp", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Integrate documents. - /// - internal static string ItemIntegrateDocs { - get { - return ResourceManager.GetString("ItemIntegrateDocs", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Integrate your IM client with ONLYOFFICE talk and stay tuned. - /// - internal static string ItemIntegrateIM { - get { - return ResourceManager.GetString("ItemIntegrateIM", resourceCulture); - } - } - /// /// Looks up a localized string similar to <b>Tip #1.</b> Use the <b>Real-time Co-editing</b> feature to speed up the interaction process when specifying details or proofreading a document. Choose between two co-editing modes - <b>Fast</b> when you see changes as your co-author is typing or <b>Strict</b> when the changes are shown only after saving the document.. /// @@ -636,51 +537,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to Share documents with your teammates.. - /// - internal static string ItemShareDocuments { - get { - return ResourceManager.GetString("ItemShareDocuments", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Try full-featured online document editing in your browser. - /// - internal static string ItemTryOnlineDocEditor { - get { - return ResourceManager.GetString("ItemTryOnlineDocEditor", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Upload CRM contacts. - /// - internal static string ItemUploadCrm { - get { - return ResourceManager.GetString("ItemUploadCrm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Upload CRM contacts to ONLYOFFICE to access them everywhere. - /// - internal static string ItemUploadCrmContacts { - get { - return ResourceManager.GetString("ItemUploadCrmContacts", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Upload CRM contacts from a csv. file. - /// - internal static string ItemUploadCrmContactsCsv { - get { - return ResourceManager.GetString("ItemUploadCrmContactsCsv", resourceCulture); - } - } - /// /// Looks up a localized string similar to Learn More >>. /// @@ -691,14 +547,14 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Activate your email for "${__VirtualRootPath}":"$InviteLink" portal. - /// - ///Hello $UserDisplayName, - /// - ///To start participating in the "${__VirtualRootPath}":"$InviteLink" portal life you need to activate your email address. This is done for security reasons. - /// - ///$GreenButton - /// + /// Looks up a localized string similar to h1.Activate your email for "${__VirtualRootPath}":"$InviteLink" portal. + /// + ///Hello! + /// + ///To start participating in the "${__VirtualRootPath}":"$InviteLink" portal life you need to activate your email address. This is done for security reasons. + /// + ///$GreenButton + /// ///This link is valid for 7 days only. Please complete your email activation within that period.. /// internal static string pattern_activate_email { @@ -707,26 +563,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to h1.Message from the "${__VirtualRootPath}":"${__VirtualRootPath}" VoIP disabled. - /// - internal static string pattern_admin_voip_blocked { - get { - return ResourceManager.GetString("pattern_admin_voip_blocked", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1.Message from the "${__VirtualRootPath}":"${__VirtualRootPath}" portal - /// - ///VoIP Balance: $Body. - /// - internal static string pattern_admin_voip_warning { - get { - return ResourceManager.GetString("pattern_admin_voip_warning", resourceCulture); - } - } - /// /// Looks up a localized string similar to h1."${__VirtualRootPath}":"${__VirtualRootPath}" portal backup created /// @@ -734,12 +570,12 @@ namespace ASC.Web.Core.PublicResources { /// ///A backup file containing data from your "${__VirtualRootPath}":"${__VirtualRootPath}" portal has been created. /// - ///To learn more on the backup procedure please refer to our "Data backup":"${__HelpLink}/tipstricks/data-backup-restore.aspx" user guide. + ///To learn more on the backup procedure please refer to our "Data backup":"http://helpcenter.onlyoffice.com/tipstricks/data-backup-restore.aspx" user guide. + /// /// ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" /// - ///Best regards, - ///ONLYOFFICE™ [rest of string was truncated]";. + ///Best [rest of string was truncated]";. /// internal static string pattern_backup_created { get { @@ -748,19 +584,19 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Email address change request - /// - ///You have requested to change your email address used to enter the ${LetterLogoText} portal. - /// - ///Please follow the link below to change your email address: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete your email change process within that period. - /// - ///You might need your old email address to access the portal when you follow the link. If you do not remember the old email address, please contact your portal administrator. - /// - ///If you do not want [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Email address change request + /// + ///You have requested to change your email address used to enter the ${LetterLogoText} portal. + /// + ///Please follow the link below to change your email address: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete your email change process within that period. + /// + ///You might need your old email address to access the portal when you follow the link. If you do not remember the old email address, please contact your portal administrator. + /// + ///If you do not want to change yo [rest of string was truncated]";. /// internal static string pattern_change_email { get { @@ -769,17 +605,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Password change request for the "${__VirtualRootPath}":"${__VirtualRootPath}" portal - /// - ///There has been a request to change your password used to enter the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. - /// - ///Please follow the link below to change your password: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the password change process within that period. - /// - ///If you do not want to change your password or received this email by mistake, please ignore it or contact your "$ [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Password change request for the "${__VirtualRootPath}":"${__VirtualRootPath}" portal + /// + ///There has been a request to change your password used to enter the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. + /// + ///Please follow the link below to change your password: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the password change process within that period. + /// + ///If you do not want to change your password or received this email by mistake, please ignore it or contact your "${__Virtual [rest of string was truncated]";. /// internal static string pattern_change_password { get { @@ -788,14 +624,14 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Mobile phone change request - /// - ///You have requested to change your mobile phone used to enter the ${LetterLogoText} portal. - /// - ///Please follow the link below to change your mobile phone: - /// - ///$GreenButton - /// + /// Looks up a localized string similar to h1.Mobile phone change request + /// + ///You have requested to change your mobile phone used to enter the ${LetterLogoText} portal. + /// + ///Please follow the link below to change your mobile phone: + /// + ///$GreenButton + /// ///If you do not want to change your mobile phone or received this email by mistake, please ignore it or contact your portal administrator to find out the details.. /// internal static string pattern_change_phone { @@ -821,19 +657,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Change of "${__VirtualRootPath}":"${__VirtualRootPath}" portal owner - /// - ///Dear $OwnerName, - /// - ///There has been a request to change the "${__VirtualRootPath}":"${__VirtualRootPath}" portal owner to $UserName. - /// - ///Please follow the link below to confirm the operation: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the portal owner change process within that period. - /// - ///If you have any questions or need assistance please feel free to contact us at "support@onlyoffice.com":"mailto:s [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Change of "${__VirtualRootPath}":"${__VirtualRootPath}" portal owner + /// + ///Dear $OwnerName, + /// + ///There has been a request to change the "${__VirtualRootPath}":"${__VirtualRootPath}" portal owner to $UserName. + /// + ///Please follow the link below to confirm the operation: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the portal owner change process within that period.. /// internal static string pattern_confirm_owner_change { get { @@ -842,19 +676,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Change of portal address - /// - ///Dear $OwnerName, - /// - ///There has been a request to change the "${__VirtualRootPath}":"${__VirtualRootPath}" portal address to "$PortalAddress":"$PortalAddress" #if($PortalDns != "") ("$PortalDns":"$PortalDns" )#end. - /// - ///Please follow the link below to confirm the operation: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the portal address change process within that period. - /// - ///If you have any questions or need assistance please feel free to contact u [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Change of portal address + /// + ///Dear $OwnerName, + /// + ///There has been a request to change the "${__VirtualRootPath}":"${__VirtualRootPath}" portal address to "$PortalAddress":"$PortalAddress" #if($PortalDns != "") ("$PortalDns":"$PortalDns" )#end. + /// + ///Please follow the link below to confirm the operation: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the portal address change process within that period.. /// internal static string pattern_dns_change { get { @@ -1115,10 +947,10 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello, $UserName! - /// - ///We hope you enjoy using ONLYOFFICE. How everything is going with your trial? We would really appreciate you feedback! - /// + /// Looks up a localized string similar to Hello, $UserName! + /// + ///We hope you enjoy using ONLYOFFICE. How everything is going with your trial? We would really appreciate your feedback! + /// ///Please, don’t hesitate to contact us at "support.onlyoffice.com":"https://support.onlyoffice.com" whenever you have questions or ideas.. /// internal static string pattern_enterprise_admin_without_activity_v10 { @@ -1354,16 +1186,16 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Invitation to join "${__VirtualRootPath}":"$InviteLink" portal - /// - ///Hello, - /// - ///You have requested to join the "${__VirtualRootPath}":"$InviteLink" portal at ${LetterLogoText} - a platform for document and project management. Join the portal and start collaborating with your colleagues or friends right away. - /// - ///To accept the invitation please enter your name and password following this link: - /// - ///$GreenButton - /// + /// Looks up a localized string similar to h1.Invitation to join "${__VirtualRootPath}":"$InviteLink" portal + /// + ///Hello, + /// + ///You have requested to join the "${__VirtualRootPath}":"$InviteLink" portal at ${LetterLogoText} - a platform for document and project management. Join the portal and start collaborating with your colleagues or friends right away. + /// + ///To accept the invitation please enter your name and password following this link: + /// + ///$GreenButton + /// ///*Note*: this link is valid for 48 hours only. Please complete the operation within that period.. /// internal static string pattern_join { @@ -1438,7 +1270,9 @@ namespace ASC.Web.Core.PublicResources { /// ///Best regards, ///ONLYOFFICE™ Support Team - ///"www.onlyoffice.com":"http://onlyoffice.com/". + ///"www.onlyoffice.com":"http://onlyoffice.com/" + /// + ///^You receive this email because you are a registered user of the " [rest of string was truncated]";. /// internal static string pattern_migration_error { get { @@ -1456,7 +1290,9 @@ namespace ASC.Web.Core.PublicResources { /// ///Best regards, ///ONLYOFFICE™ Support Team - ///"www.onlyoffice.com":"http://onlyoffice.com/". + ///"www.onlyoffice.com":"http://onlyoffice.com/" + /// + ///^You receive this email because you are a registered user of the "${__Virt [rest of string was truncated]";. /// internal static string pattern_migration_server_failure { get { @@ -1503,15 +1339,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Dear $UserName, - /// - ///You have just created your ONLYOFFICE portal, your safe and secure web office. Your portal address is "${__VirtualRootPath}":"${__VirtualRootPath}". Follow the link below to confirm your email address: - /// - ///$GreenButton - /// - ///Please, complete your email activation within a week as the link is valid for 7 days only. - /// - ///Note: we do not send out confidential information (like your password) in emails for safety reasons. You may change your email or password in your "Profile page":"$MyStaffLink" [rest of string was truncated]";. + /// Looks up a localized string similar to Dear $UserName, + /// + ///You have just created your ONLYOFFICE portal, your safe and secure web office. Your portal address is "${__VirtualRootPath}":"${__VirtualRootPath}". Follow the link below to confirm your email address: + /// + ///$GreenButton + /// + ///Please, complete your email activation within a week as the link is valid for 7 days only. + /// + ///Note: we do not send out confidential information (like your password) in emails for safety reasons. You may change your email or password in your "Profile page":"$MyStaffLink". + /// + ///To se [rest of string was truncated]";. /// internal static string pattern_opensource_admin_activation { get { @@ -1573,15 +1411,15 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Welcome to ONLYOFFICE Personal - /// - ///You have just created your personal office in the cloud. - /// - ///h3.It's a virtual workspace where you can edit and store documents, work with them from anywhere providing access to your friends or colleagues. - /// - ///ONLYOFFICE is compatible with Microsoft Office™ document formats and guarantees no loss of formatting or quality of created objects. We promise to relieve you from formatting fidelity headache and give full professional editing toolset in your hands. - /// - ///h3.For a quic [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Welcome to ONLYOFFICE Personal + /// + ///You have just created your personal office in the cloud. + /// + ///h3.It's a virtual workspace where you can edit and store documents, work with them from anywhere providing access to your friends or colleagues. + /// + ///ONLYOFFICE is compatible with Microsoft Office™ document formats and guarantees no loss of formatting or quality of created objects. We promise to relieve you from formatting fidelity headache and give full professional editing toolset in your hands. + /// + ///h3.For a quick start, [rest of string was truncated]";. /// internal static string pattern_personal_after_registration1 { get { @@ -1653,11 +1491,11 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to $PersonalHeaderStart Connect your favorite cloud storage to ONLYOFFICE $PersonalHeaderEnd - /// - ///It has been a week since you created your cloud office, so we believe it's time to unveil some beneficial features you might have missed. - /// - ///Connect *Dropbox*, *Google Drive*, *Box*, *OneDrive*, *Nextcloud*, *ownCloud* or *Yandex.Disk* to ONLYOFFICE and create a single document management space for all your documents. You'll be able to edit external files in ONLYOFFICE and save them to the storage you keep documents [rest of string was truncated]";. + /// Looks up a localized string similar to $PersonalHeaderStart Connect your favorite cloud storage to ONLYOFFICE $PersonalHeaderEnd + /// + ///It has been a week since you created your cloud office, so we believe it's time to unveil some beneficial features you might have missed. + /// + ///Connect *Dropbox*, *Google Drive*, *Box*, *OneDrive*, *Nextcloud*, *ownCloud* or *Yandex.Disk* to ONLYOFFICE and create a single document management space for all your documents. You'll be able to edit external files in ONLYOFFICE and save them to the storage you keep documents in. [rest of string was truncated]";. /// internal static string pattern_personal_after_registration7 { get { @@ -1666,17 +1504,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to You have requested to change your email address used to enter the ${LetterLogoText} portal. - /// - ///Please follow the link below to change your email address: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete your email change process within that period. - /// - ///If you do not want to change your email or received this email by mistake, please ignore it. - /// - ///Sincerely, + /// Looks up a localized string similar to You have requested to change your email address used to enter the ${LetterLogoText} portal. + /// + ///Please follow the link below to change your email address: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete your email change process within that period. + /// + ///If you do not want to change your email or received this email by mistake, please ignore it. + /// + ///Sincerely, ///ONLYOFFICE team. /// internal static string pattern_personal_change_email { @@ -1686,17 +1524,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to There has been a request to change your password used to enter the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. - /// - ///Please follow the link below to change your password: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the password change process within that period. - /// - ///If you do not want to change your password or received this email by mistake, please ignore it. - /// - ///Sincerely, + /// Looks up a localized string similar to There has been a request to change your password used to enter the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. + /// + ///Please follow the link below to change your password: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the password change process within that period. + /// + ///If you do not want to change your password or received this email by mistake, please ignore it. + /// + ///Sincerely, ///ONLYOFFICE team. /// internal static string pattern_personal_change_password { @@ -1706,13 +1544,13 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello, - /// - ///you've just registered an account at the ONLYOFFICE solution for personal use. Click "here":"$InviteLink" to confirm the registration and create a password. - /// - ///If you can't open the link, please copy the following "$InviteLink":"$InviteLink" and paste it into your browser address bar. - /// - ///Sincerely, + /// Looks up a localized string similar to Hello, + /// + ///You've just registered an account at the ONLYOFFICE solution for personal use. Click "here":"$InviteLink" to confirm the registration and create a password. + /// + ///If you can't open the link, please copy the following "$InviteLink":"$InviteLink" and paste it into your browser address bar. + /// + ///Sincerely, ///ONLYOFFICE team. /// internal static string pattern_personal_confirmation { @@ -1722,13 +1560,13 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period): - /// - ///$GreenButton - /// - ///*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our "Privacy statement":"https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0". - /// - ///Ignore this email if you do not wa [rest of string was truncated]";. + /// Looks up a localized string similar to You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period): + /// + ///$GreenButton + /// + ///*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our "Privacy statement":"https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0". + /// + ///Ignore this email if you do not want to [rest of string was truncated]";. /// internal static string pattern_personal_profile_delete { get { @@ -1737,18 +1575,18 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Deactivation of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal - /// - ///Dear $OwnerName, - /// - ///You have requested a temporary deactivation of your "${__VirtualRootPath}":"${__VirtualRootPath}" portal. Please follow the link below to confirm the operation: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the portal deactivation process within that period. - /// - ///You can reactivate your portal any time by clicking the following link: - ///p=. "Reactivate Portal":"$ActivateUrl" (this [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Deactivation of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal + /// + ///Dear $OwnerName, + /// + ///You have requested a temporary deactivation of your "${__VirtualRootPath}":"${__VirtualRootPath}" portal. Please follow the link below to confirm the operation: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the portal deactivation process within that period. + /// + ///You can reactivate your portal any time by clicking the following link: + ///p=. "Reactivate Portal":"$ActivateUrl" (this link has no [rest of string was truncated]";. /// internal static string pattern_portal_deactivate { get { @@ -1757,16 +1595,16 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Deletion of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal - /// - ///Dear $OwnerName, - /// - ///You have requested to permanently delete your "${__VirtualRootPath}":"${__VirtualRootPath}" portal. - /// - ///*Important! All the data stored on your portal, as well as your registration details will be lost and cannot be recovered.* - /// - ///#if($AutoRenew == "True") - ///Before you delete the portal, please make sure that automatic billing is turned off. You may check the status of automatic billing in your "Avangate account":"h [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Deletion of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal + /// + ///Dear $OwnerName, + /// + ///You have requested to permanently delete your "${__VirtualRootPath}":"${__VirtualRootPath}" portal. + /// + ///*Important! All the data stored on your portal, as well as your registration details will be lost and cannot be recovered.* + /// + ///#if($AutoRenew == "True") + ///Before you delete the portal, please make sure that automatic billing is turned off. You may check the status of automatic billing in your "Avangate account":"https://se [rest of string was truncated]";. /// internal static string pattern_portal_delete { get { @@ -1794,13 +1632,13 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Change of portal address - /// - ///Dear $UserDisplayName, - /// - ///Your $PortalUrl portal address was changed to the new "${__VirtualRootPath}":"${__VirtualRootPath}" address. - /// - ///*Note*: All the shared documents links are inaccessible now, as well as DNS settings and single sign-on options stop working until you change them. The third party iCal links added to your calendar will also stop updating until you reload them.. + /// Looks up a localized string similar to h1.Change of portal address + /// + ///Dear $UserDisplayName, + /// + ///Your $PortalUrl portal address was changed to the new "${__VirtualRootPath}":"${__VirtualRootPath}" address. + /// + ///*Note*: All the shared documents links are inaccessible now, as well as DNS settings and single sign-on options stop working until you change them. The third-party iCal links added to your calendar will also stop updating until you reload them.. /// internal static string pattern_portal_rename { get { @@ -1809,17 +1647,15 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Removal of the profile from the "${__VirtualRootPath}":"${__VirtualRootPath}" portal - /// - ///You have requested to permanently delete your profile from the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. - /// - ///If you still want to delete your profile please follow the link below to confirm the operation: - /// - ///$GreenButton - /// - ///*Note*: this link is valid for 7 days only. Please complete the profile deletion process within that period. - /// - ///If you have any questions or need assistance please feel free to contact u [rest of string was truncated]";. + /// Looks up a localized string similar to h1.Removal of the profile from the "${__VirtualRootPath}":"${__VirtualRootPath}" portal + /// + ///You have requested to permanently delete your profile from the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. + /// + ///If you still want to delete your profile please follow the link below to confirm the operation: + /// + ///$GreenButton + /// + ///*Note*: this link is valid for 7 days only. Please complete the profile deletion process within that period.. /// internal static string pattern_profile_delete { get { @@ -1828,17 +1664,30 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to h1.Your profile at "$__VirtualRootPath":"$__VirtualRootPath" has been changed + /// Looks up a localized string similar to User "$FromUserName":"$FromUserLink" has deleted his/her profile, and this profile is now blocked. All user’s files are still assigned to him/her and occupy disk space. /// - ///Dear $UserName, + ///You can reassign the user’s documents shared with others to another active user or remove them to free up the portal disk space. /// - ///Your user profile details at "$__VirtualRootPath":"$__VirtualRootPath" have been changed by "$__AuthorName":"$__AuthorUrl". - /// - ///To view your profile follow the link below: - ///"$UserName":"$MyStaffLink" - /// - ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^ - ///. + ///Please go to the user profile using "this link":"$FromUserLink" to reassign documents to another user or remove the data.. + /// + internal static string pattern_profile_has_deleted_itself { + get { + return ResourceManager.GetString("pattern_profile_has_deleted_itself", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.Your profile at "$__VirtualRootPath":"$__VirtualRootPath" has been changed + /// + ///Dear $UserName, + /// + ///Your user profile details at "$__VirtualRootPath":"$__VirtualRootPath" have been changed by "$__AuthorName":"$__AuthorUrl". + /// + ///To view your profile follow the link below: + ///"$UserName":"$MyStaffLink" + /// + /// + ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^. /// internal static string pattern_profile_updated { get { @@ -1847,10 +1696,10 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Dear $UserName, - /// - ///The process of reassign data from user "$FromUserName":"$FromUserLink" to user "$ToUserName":"$ToUserLink" has been successfully completed. - /// + /// Looks up a localized string similar to Dear $UserName, + /// + ///The process of data reassignment from user "$FromUserName":"$FromUserLink" to user "$ToUserName":"$ToUserLink" has been successfully completed. + /// ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^. /// internal static string pattern_reassigns_completed { @@ -1860,12 +1709,12 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Dear $UserName, - /// - ///The process of reassign data from user "$FromUserName":"$FromUserLink" to user "$ToUserName":"$ToUserLink" has been failed. - /// - ///Exception message: $Message - /// + /// Looks up a localized string similar to Dear $UserName, + /// + ///The process of data reassignment from user "$FromUserName":"$FromUserLink" to user "$ToUserName":"$ToUserLink" failed. + /// + ///Exception message: $Message + /// ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^. /// internal static string pattern_reassigns_failed { @@ -1875,17 +1724,17 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Dear $UserName, - /// - ///The process of removing data from user "$FromUserName":"$FromUserLink" has been successfully completed. - /// - ///The deletion of personal data allowed to free: - /// - ///# Documents - $DocsSpace - ///# CRM - $CrmSpace - ///# Mail - $MailSpace - ///# Talk - $TalkSpace - /// + /// Looks up a localized string similar to Dear $UserName, + /// + ///The process of data removal from user "$FromUserName":"$FromUserLink" has been successfully completed. + /// + ///The deletion of personal data allowed to free: + /// + ///# Documents - $DocsSpace + ///# CRM - $CrmSpace + ///# Mail - $MailSpace + ///# Talk - $TalkSpace + /// ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^. /// internal static string pattern_remove_user_data_completed { @@ -1895,12 +1744,12 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Dear $UserName, - /// - ///The process of removing data from user "$FromUserName":"$FromUserLink" has been failed. - /// - ///Exception message: $Message - /// + /// Looks up a localized string similar to Dear $UserName, + /// + ///The process of data removal for user "$FromUserName":"$FromUserLink" failed. + /// + ///Exception message: $Message + /// ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^. /// internal static string pattern_remove_user_data_failed { @@ -1986,7 +1835,9 @@ namespace ASC.Web.Core.PublicResources { /// ///Best regards, ///ONLYOFFICE™ Support Team - ///"www.onlyoffice.com":"http://onlyoffice.com/". + ///"www.onlyoffice.com":"http://onlyoffice.com/" + /// + ///^You receive this email because you are a registered user of the "${__VirtualRoot [rest of string was truncated]";. /// internal static string pattern_restore_started { get { @@ -2102,20 +1953,20 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello, $UserName! - /// - ///You haven’t added any teammates, so maybe ONLYOFFICE Personal suits you more? It free and you will be able to: - /// - ///# Work with text documents, spreadsheets, and presentations. - ///# Share docs with your friends and collaborate on them in real-time. - ///# Embed documents to your web page. - ///# Connect 3rd party cloud storage like Dropbox or Google Drive to manage docs from one place. - /// - ///To get a quick start, sign up via your Facebook or Google account. - /// - ///$GreenButton - /// - ///You can also install this [rest of string was truncated]";. + /// Looks up a localized string similar to Hello, $UserName! + /// + ///You haven’t added any teammates, so maybe ONLYOFFICE Personal suits you more? It is free and you will be able to: + /// + ///# Work with text documents, spreadsheets, and presentations. + ///# Share docs with your friends and collaborate on them in real-time. + ///# Embed documents to your web page. + ///# Connect 3rd party cloud storage like Dropbox or Google Drive to manage docs from one place. + /// + ///To get a quick start, sign up via your Facebook or Google account. + /// + ///$GreenButton + /// + ///You can also install this "Chrome e [rest of string was truncated]";. /// internal static string pattern_saas_admin_trial_warning_after30_v10 { get { @@ -2448,14 +2299,14 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello, $UserName! - /// - ///We hope you enjoy using ONLYOFFICE. How everything is going with your trial? We would really appreciate you feedback! - /// - ///Please, don’t hesitate to contact us at "support@onlyoffice.com":"mailto:support@onlyoffice.com" whenever you have questions or ideas. - /// - ///Truly yours, - ///ONLYOFFICE Team + /// Looks up a localized string similar to Hello, $UserName! + /// + ///We hope you enjoy using ONLYOFFICE. How everything is going with your trial? We would really appreciate your feedback! + /// + ///Please, don’t hesitate to contact us at "support@onlyoffice.com":"mailto:support@onlyoffice.com" whenever you have questions or ideas. + /// + ///Truly yours, + ///ONLYOFFICE Team ///"www.onlyoffice.com":"http://onlyoffice.com/". /// internal static string pattern_saas_admin_without_activity_v10 { @@ -2465,16 +2316,16 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello! - /// - ///$__AuthorName has invited you as a guest user to "${__VirtualRootPath}":"${__VirtualRootPath}". Accept the invitation by clicking the link: - /// - ///$GreenButton - /// - ///We will also send you useful tips, latest ONLYOFFICE news, and special offers once in a while. You can cancel the subscriptions on your Profile page at any moment as well as re-enable them. - /// - ///Truly yours, - ///ONLYOFFICE Team + /// Looks up a localized string similar to Hello! + /// + ///You are invited to join "${__VirtualRootPath}":"${__VirtualRootPath}" as a guest user. Accept the invitation by clicking the link: + /// + ///$GreenButton + /// + ///We will also send you useful tips, latest ONLYOFFICE news, and special offers once in a while. You can cancel the subscriptions on your Profile page at any moment as well as re-enable them. + /// + ///Truly yours, + ///ONLYOFFICE Team ///"www.onlyoffice.com":"http://onlyoffice.com/". /// internal static string pattern_saas_guest_activation_v10 { @@ -2484,14 +2335,14 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello $UserName! - /// - ///Your guest profile has been successfully added to "${__VirtualRootPath}":"${__VirtualRootPath}". Now you can: - /// - ///# Edit your "profile":"$MyStaffLink". - ///# View and comment the content available in the "Community":"${__VirtualRootPath}/products/community/" and "Projects":"${__VirtualRootPath}/products/projects/". - ///# Add and download files available for you in the "Documents":"${__VirtualRootPath}/products/files/". - ///# Organize your schedule with the built-in "Calendar":"${__VirtualRootPath [rest of string was truncated]";. + /// Looks up a localized string similar to Hello! + /// + ///Your guest profile has been successfully added to "${__VirtualRootPath}":"${__VirtualRootPath}". Now you can: + /// + ///# Edit your "profile":"$MyStaffLink". + ///# View and comment the content available in the "Community":"${__VirtualRootPath}/products/community/" and "Projects":"${__VirtualRootPath}/products/projects/". + ///# Add and download files available for you in the "Documents":"${__VirtualRootPath}/products/files/". + ///# Organize your schedule with the built-in "Calendar":"${__VirtualRootPath}/addons/calendar [rest of string was truncated]";. /// internal static string pattern_saas_guest_welcome_v10 { get { @@ -2500,16 +2351,16 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello! - /// - ///$__AuthorName has invited you to join ONLYOFFICE at "${__VirtualRootPath}":"${__VirtualRootPath}". Accept the invitation by clicking the link: - /// - ///$GreenButton - /// - ///We will also send you useful tips, latest ONLYOFFICE news and special offers once in a while. You can cancel the subscriptions on your Profile page at any moment as well as re-enable them. - /// - ///Truly yours, - ///ONLYOFFICE Team + /// Looks up a localized string similar to Hello! + /// + ///You are invited to join ONLYOFFICE at "${__VirtualRootPath}":"${__VirtualRootPath}". Accept the invitation by clicking the link: + /// + ///$GreenButton + /// + ///We will also send you useful tips, latest ONLYOFFICE news and special offers once in a while. You can cancel the subscriptions on your Profile page at any moment as well as re-enable them. + /// + ///Truly yours, + ///ONLYOFFICE Team ///"www.onlyoffice.com":"http://onlyoffice.com/". /// internal static string pattern_saas_user_activation_v10 { @@ -2519,13 +2370,13 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to Hello, $UserName! - /// - ///Welcome to ONLYOFFICE! Your user profile has been successfully added to the portal at "${__VirtualRootPath}":"${__VirtualRootPath}". Now you can: - /// - ///# Create and edit "Documents":"${__VirtualRootPath}/products/files/", share them with teammates, and collaborate in real time. - ///# Add your email accounts and manage all correspondence in one place with "Mail":"${__VirtualRootPath}/addons/mail/". - ///# Manage your workflow with "Projects":"${__VirtualRootPath}/products/projects/" and your custo [rest of string was truncated]";. + /// Looks up a localized string similar to Hello! + /// + ///Welcome to ONLYOFFICE! Your user profile has been successfully added to the portal at "${__VirtualRootPath}":"${__VirtualRootPath}". Now you can: + /// + ///# Create and edit "Documents":"${__VirtualRootPath}/products/files/", share them with teammates, and collaborate in real time. + ///# Add your email accounts and manage all correspondence in one place with "Mail":"${__VirtualRootPath}/addons/mail/". + ///# Manage your workflow with "Projects":"${__VirtualRootPath}/products/projects/" and your customer relationships [rest of string was truncated]";. /// internal static string pattern_saas_user_welcome_v10 { get { @@ -2536,7 +2387,10 @@ namespace ASC.Web.Core.PublicResources { /// /// Looks up a localized string similar to h1."${__VirtualRootPath}":"${__VirtualRootPath}" portal profile change notification /// - ///"$__AuthorName":"$__AuthorUrl" has changed his/her profile details at the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.. + ///"$__AuthorName":"$__AuthorUrl" has changed his/her profile details at the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. + /// + /// + ///^You receive this email because you are an administrator of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. If you do not want to receive the notifications about profile updates, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. /// internal static string pattern_self_profile_updated { get { @@ -2559,7 +2413,10 @@ namespace ASC.Web.Core.PublicResources { /// ///#end /// - ///#end. + ///#end + /// + /// + ///^You receive this email because you are a regi [rest of string was truncated]";. /// internal static string pattern_send_whats_new { get { @@ -2585,7 +2442,10 @@ namespace ASC.Web.Core.PublicResources { /// /// Looks up a localized string similar to h1.New user added to "${__VirtualRootPath}":"${__VirtualRootPath}" portal /// - ///"$__AuthorName":"$__AuthorUrl" has joined your portal at "${__VirtualRootPath}":"${__VirtualRootPath}".. + ///"$__AuthorName":"$__AuthorUrl" has joined your portal at "${__VirtualRootPath}":"${__VirtualRootPath}". + /// + /// + ///^You receive this email because you are an administrator user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. If you do not want to receive the notifications about new users, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. /// internal static string pattern_user_has_join { get { @@ -2619,24 +2479,6 @@ namespace ASC.Web.Core.PublicResources { } } - /// - /// Looks up a localized string similar to VoIP disabled. - /// - internal static string subject_admin_voip_blocked { - get { - return ResourceManager.GetString("subject_admin_voip_blocked", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Notification to administrators about VoIP balance. - /// - internal static string subject_admin_voip_warning { - get { - return ResourceManager.GetString("subject_admin_voip_warning", resourceCulture); - } - } - /// /// Looks up a localized string similar to ${LetterLogoText}. ${__VirtualRootPath} portal backup created. /// @@ -3141,6 +2983,15 @@ namespace ASC.Web.Core.PublicResources { } } + /// + /// Looks up a localized string similar to User has deleted his/her profile. + /// + internal static string subject_profile_has_deleted_itself { + get { + return ResourceManager.GetString("subject_profile_has_deleted_itself", resourceCulture); + } + } + /// /// Looks up a localized string similar to Your profile at ${__VirtualRootPath} has been changed. /// @@ -3151,7 +3002,7 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to ${LetterLogoText}. Reassigns user data is completed. + /// Looks up a localized string similar to ${LetterLogoText}. User data reassignment is completed. /// internal static string subject_reassigns_completed { get { @@ -3160,7 +3011,7 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to ${LetterLogoText}. Reassigns user data is failed. + /// Looks up a localized string similar to ${LetterLogoText}. User data reassignment failed. /// internal static string subject_reassigns_failed { get { @@ -3169,7 +3020,7 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to ${LetterLogoText}. Remove user data is completed. + /// Looks up a localized string similar to ${LetterLogoText}. User data removal completed. /// internal static string subject_remove_user_data_completed { get { @@ -3178,7 +3029,7 @@ namespace ASC.Web.Core.PublicResources { } /// - /// Looks up a localized string similar to ${LetterLogoText}. Remove user data is failed. + /// Looks up a localized string similar to ${LetterLogoText}. User data removal failed. /// internal static string subject_remove_user_data_failed { get { From 7950db51ffb2c877cba863fb6a946c6ac20ff254 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 18:10:31 +0300 Subject: [PATCH 07/14] Notify: fix --- common/services/ASC.Data.Backup/Core/NotifyHelper.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs index 4ac8e56eea..80a86d5546 100644 --- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs +++ b/common/services/ASC.Data.Backup/Core/NotifyHelper.cs @@ -157,6 +157,7 @@ namespace ASC.Data.Backup services.TryAddSingleton(); return services + .AddNotifyConfiguration() .AddStudioNotifySourceService() .AddUserManagerService() .AddStudioNotifyHelperService() From 314206639f4a007b8fd5da754c4dc8b3c85fef24 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Mon, 29 Jun 2020 19:15:18 +0300 Subject: [PATCH 08/14] Notify: fix --- common/services/ASC.Notify/DbWorker.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/common/services/ASC.Notify/DbWorker.cs b/common/services/ASC.Notify/DbWorker.cs index a2d2c873d4..43332a403f 100644 --- a/common/services/ASC.Notify/DbWorker.cs +++ b/common/services/ASC.Notify/DbWorker.cs @@ -156,6 +156,7 @@ namespace ASC.Notify } dbContext.SaveChanges(); + tx.Commit(); return messages; } From a3dd53878e0869e13316292a302a9db050c22ec4 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 30 Jun 2020 09:40:09 +0300 Subject: [PATCH 09/14] Web: Files/Common: added ViewSelector component --- .../pages/Home/Section/Filter/index.js | 5 +- .../ASC.Files/Client/src/helpers/constants.js | 1 + .../Client/src/helpers/converters.js | 3 + web/ASC.Web.Common/src/api/files/filter.js | 5 ++ .../src/components/FilterInput/FilterInput.js | 44 +++++++++----- .../FilterInput/FilterInput.stories.js | 3 +- .../FilterInput/StyledFilterInput.js | 54 ++++++++++++++++- .../sub-components/ViewSelector.js | 60 +++++++++++++++++++ .../svg/filter.view.selector.row.react.svg | 3 + .../svg/filter.view.selector.tile.react.svg | 3 + .../src/components/icons/svg/index.js | 10 ++++ 11 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 web/ASC.Web.Common/src/components/FilterInput/sub-components/ViewSelector.js create mode 100644 web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.row.react.svg create mode 100644 web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.tile.react.svg diff --git a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js index b626c90d84..2e85f21d95 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js +++ b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js @@ -79,6 +79,7 @@ class SectionFilterContent extends React.Component { const sortBy = data.sortId; const sortOrder = data.sortDirection === "desc" ? "descending" : "ascending"; + const viewAs = data.viewAs; const authorType = getAuthorType(data.filterValues); const withSubfolders = getSearchParams(data.filterValues); @@ -95,6 +96,7 @@ class SectionFilterContent extends React.Component { newFilter.page = 0; newFilter.sortBy = sortBy; newFilter.sortOrder = sortOrder; + newFilter.viewAs = viewAs; newFilter.filterType = filterType; newFilter.search = search; newFilter.authorType = authorType; @@ -222,7 +224,8 @@ class SectionFilterContent extends React.Component { const selectedFilterData = { filterValues: [], sortDirection: filter.sortOrder === "ascending" ? "asc" : "desc", - sortId: filter.sortBy + sortId: filter.sortBy, + viewAs: filter.viewAs }; selectedFilterData.inputValue = filter.search; diff --git a/products/ASC.Files/Client/src/helpers/constants.js b/products/ASC.Files/Client/src/helpers/constants.js index 49202b2f6d..c26212e918 100644 --- a/products/ASC.Files/Client/src/helpers/constants.js +++ b/products/ASC.Files/Client/src/helpers/constants.js @@ -5,6 +5,7 @@ export const FILTER_TYPE = "filterType"; export const SEARCH = "search"; export const SORT_BY = "sortby"; export const SORT_ORDER = "sortorder"; +export const VIEW_AS = "viewas"; export const PAGE = "page"; export const PAGE_COUNT = "pagecount"; export const FOLDER = "folder"; diff --git a/products/ASC.Files/Client/src/helpers/converters.js b/products/ASC.Files/Client/src/helpers/converters.js index 91a467c20d..00d1859d59 100644 --- a/products/ASC.Files/Client/src/helpers/converters.js +++ b/products/ASC.Files/Client/src/helpers/converters.js @@ -4,6 +4,7 @@ import { SEARCH, SORT_BY, SORT_ORDER, + VIEW_AS, PAGE, PAGE_COUNT, AUTHOR_TYPE, @@ -28,6 +29,7 @@ export function getFilterByLocation(location) { defaultFilter.withSubfolders; const search = urlFilter[SEARCH] || defaultFilter.search; const sortBy = urlFilter[SORT_BY] || defaultFilter.sortBy; + const viewAs = urlFilter[VIEW_AS] || defaultFilter.viewAs; const sortOrder = urlFilter[SORT_ORDER] || defaultFilter.sortOrder; const page = (urlFilter[PAGE] && (+urlFilter[PAGE]-1)) || defaultFilter.page; const pageCount = @@ -41,6 +43,7 @@ export function getFilterByLocation(location) { defaultFilter.total, sortBy, sortOrder, + viewAs, filterType, withSubfolders, search, diff --git a/web/ASC.Web.Common/src/api/files/filter.js b/web/ASC.Web.Common/src/api/files/filter.js index c6ff447764..08ff87ce97 100644 --- a/web/ASC.Web.Common/src/api/files/filter.js +++ b/web/ASC.Web.Common/src/api/files/filter.js @@ -5,6 +5,7 @@ const DEFAULT_PAGE_COUNT = 25; const DEFAULT_TOTAL = 0; const DEFAULT_SORT_BY = "lastModifiedDate"; const DEFAULT_SORT_ORDER = "ascending"; +const DEFAULT_VIEW = "row"; const DEFAULT_FILTER_TYPE = null; const DEFAULT_SEARCH_TYPE = true; //withSubfolders const DEFAULT_SEARCH = null; @@ -29,6 +30,7 @@ class FilesFilter { total = DEFAULT_TOTAL, sortBy = DEFAULT_SORT_BY, sortOrder = DEFAULT_SORT_ORDER, + viewAs = DEFAULT_VIEW, filterType = DEFAULT_FILTER_TYPE, withSubfolders = DEFAULT_SEARCH_TYPE, search = DEFAULT_SEARCH, @@ -41,6 +43,7 @@ class FilesFilter { this.pageCount = pageCount; this.sortBy = sortBy; this.sortOrder = sortOrder; + this.viewAs = viewAs; this.filterType = filterType; this.withSubfolders = withSubfolders; this.search = search; @@ -106,6 +109,7 @@ class FilesFilter { this.total, this.sortBy, this.sortOrder, + this.viewAs, this.filterType, this.withSubfolders, this.search, @@ -124,6 +128,7 @@ class FilesFilter { this.search === filter.search && this.sortBy === filter.sortBy && this.sortOrder === filter.sortOrder && + this.viewAs === filter.viewAs && this.page === filter.page && this.selectedItem.key === filter.selectedItem.key && this.folder === filter.folder && diff --git a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js index 019cbaf101..b610161f1a 100644 --- a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js +++ b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js @@ -5,6 +5,7 @@ import isEqual from 'lodash/isEqual'; import throttle from 'lodash/throttle'; import FilterBlock from './sub-components/FilterBlock'; import SortComboBox from './sub-components/SortComboBox'; +import ViewSelector from './sub-components/ViewSelector'; import map from 'lodash/map'; import clone from 'lodash/clone'; import StyledFilterInput from './StyledFilterInput'; @@ -92,6 +93,7 @@ class FilterInput extends React.Component { this.state = { sortDirection: props.selectedFilterData.sortDirection === "desc" ? true : false, + viewAs: props.selectedFilterData.viewAs, sortId: props.getSortData().findIndex(x => x.key === props.selectedFilterData.sortId) != -1 ? props.selectedFilterData.sortId : props.getSortData().length > 0 ? props.getSortData()[0].key : "", searchText: props.selectedFilterData.inputValue || props.value, @@ -120,6 +122,8 @@ class FilterInput extends React.Component { this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this); this.clearFilter = this.clearFilter.bind(this); + this.onClickViewSelector = this.onClickViewSelector.bind(this); + this.throttledResize = throttle(this.resize, 300); } @@ -230,9 +234,15 @@ class FilterInput extends React.Component { }) } onChangeSortDirection(key) { - this.onFilter(this.state.filterValues, this.state.sortId, key ? "desc" : "asc"); + this.onFilter(this.state.filterValues, this.state.sortId, key ? "desc" : "asc", this.state.viewAs); this.setState({ sortDirection: !!key }); } + onClickViewSelector(item) { + const itemId = item.target.dataset.for; + const viewAs = itemId.indexOf("row") === -1 ? "tile" : "row" + this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", viewAs); + this.setState({ viewAs: viewAs }); + } getDefaultSelectedIndex() { const sortData = this.props.getSortData(); if (sortData.length > 0) { @@ -243,19 +253,19 @@ class FilterInput extends React.Component { } onClickSortItem(key) { this.setState({ sortId: key }); - this.onFilter(this.state.filterValues, key, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(this.state.filterValues, key, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); } onSortDirectionClick() { - this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "desc" : "asc"); + this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "desc" : "asc", this.state.viewAs); this.setState({ sortDirection: !this.state.sortDirection }); } onSearchChanged(value) { this.setState({ searchText: value }); - this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", value); + this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, value); } onSearch(result) { - this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); } getFilterData() { const _this = this; @@ -280,7 +290,7 @@ class FilterInput extends React.Component { openFilterItems: [], hideFilterItems: [] }); - this.onFilter([], this.state.sortId, this.state.sortDirection ? "desc" : "asc", ''); + this.onFilter([], this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, ''); } updateFilter(inputFilterItems) { const currentFilterItems = inputFilterItems || cloneObjectsArray(this.state.filterValues); @@ -344,9 +354,9 @@ class FilterInput extends React.Component { item.key = item.key.replace(item.group + "_", ''); return item; }) - this.onFilter(filterValues.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(filterValues.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); } - onFilter(filterValues, sortId, sortDirection, searchText) { + onFilter(filterValues, sortId, sortDirection, viewAs, searchText) { let cloneFilterValues = cloneObjectsArray(filterValues); cloneFilterValues = cloneFilterValues.map(function (item) { item.key = item.key.replace(item.group + "_", ''); @@ -356,7 +366,8 @@ class FilterInput extends React.Component { inputValue: searchText != undefined ? searchText : this.state.searchText, filterValues: cloneFilterValues.filter(item => item.key != '-1'), sortId: sortId, - sortDirection: sortDirection + sortDirection: sortDirection, + viewAs: viewAs }); } onChangeFilter(result) { @@ -364,7 +375,7 @@ class FilterInput extends React.Component { searchText: result.inputValue, filterValues: result.filterValues, }); - this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", result.inputValue); + this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs, result.inputValue); } onFilterRender() { if (this.isResizeUpdate) { @@ -419,7 +430,7 @@ class FilterInput extends React.Component { }) - this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); } return; @@ -467,7 +478,7 @@ class FilterInput extends React.Component { item.key = item.key.replace(item.group + "_", ''); return item; }) - this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); this.setState({ filterValues: currentFilterItems, openFilterItems: currentFilterItems, @@ -503,7 +514,7 @@ class FilterInput extends React.Component { item.key = item.key.replace(item.group + "_", ''); return item; }) - this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc"); + this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "desc" : "asc", this.state.viewAs); } } @@ -517,7 +528,7 @@ class FilterInput extends React.Component { /* eslint-enable react/prop-types */ const { searchText, filterValues, openFilterItems, - hideFilterItems, sortId, sortDirection } = this.state; + hideFilterItems, sortId, sortDirection, viewAs } = this.state; // console.log("filter input render, openFilterItems", openFilterItems, 'hideFilterItems', hideFilterItems); let iconSize = 33; @@ -581,6 +592,11 @@ class FilterInput extends React.Component { directionAscLabel={directionAscLabel} directionDescLabel={directionDescLabel} /> + ); diff --git a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.stories.js b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.stories.js index 39e90c3635..57372d314a 100644 --- a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.stories.js +++ b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.stories.js @@ -43,7 +43,8 @@ class FilterStory extends React.Component { inputValue: "text", filterValues: [ {key: "1", group: "filter-status"} - ] + ], + viewAs: "row" } }; this.buttonClick = this.buttonClick.bind(this); diff --git a/web/ASC.Web.Common/src/components/FilterInput/StyledFilterInput.js b/web/ASC.Web.Common/src/components/FilterInput/StyledFilterInput.js index 81923efadb..726ff190dd 100644 --- a/web/ASC.Web.Common/src/components/FilterInput/StyledFilterInput.js +++ b/web/ASC.Web.Common/src/components/FilterInput/StyledFilterInput.js @@ -17,7 +17,10 @@ const StyledFilterInput = styled.div` .styled-search-input { display: block; float: left; - width: calc(100% - 140px); + width: calc(100% - 212px); + @media (max-width: 460px) { + width: calc(100% - 140px); + } @media ${mobile} { width: calc(100% - 58px); } @@ -121,8 +124,50 @@ const StyledFilterInput = styled.div` color: #333; } } +`; +export const StyledViewSelector = styled.div` + display: flex; + float: left; + width: 64px; + margin-left: 8px; + @media (max-width: 460px) { + display:none; + } + + .view-selector-button{ + border: 1px solid ${props => props.isDisabled ? '#ECEEF1' : '#D0D5DA'}; + border-radius: 3px; + padding: 7px; + ${props => props.isDisabled && 'background-color: #F8F9F9;' } + + svg{ + pointer-events: none; + } + + &.active{ + background-color:#A3A9AE; + border-color: #A3A9AE; + } + + &:hover{ + ${props => !props.isDisabled && 'background-color: #A3A9AE;' } + ${props => !props.isDisabled && 'border-color: #A3A9AE;' } + } + + &:first-child{ + border-right: none; + border-top-right-radius:0; + border-bottom-right-radius:0; + } + + &:last-child{ + border-left: none; + border-top-left-radius:0; + border-bottom-left-radius:0; + } + } `; export const StyledFilterItem = styled.div` @@ -228,4 +273,11 @@ export const StyledIconButton = styled.div` transform: ${state => !state.sortDirection ? 'scale(1, -1)' : 'scale(1)'}; `; + +export const StyledIconWrapper = styled.div` + display: inline-flex; + width: 32px; + height: 100%; +`; + export default StyledFilterInput; \ No newline at end of file diff --git a/web/ASC.Web.Common/src/components/FilterInput/sub-components/ViewSelector.js b/web/ASC.Web.Common/src/components/FilterInput/sub-components/ViewSelector.js new file mode 100644 index 0000000000..4f375879e4 --- /dev/null +++ b/web/ASC.Web.Common/src/components/FilterInput/sub-components/ViewSelector.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { IconButton } from 'asc-web-components'; +import PropTypes from 'prop-types'; +import { StyledViewSelector } from '../StyledFilterInput'; + + +class ViewSelector extends React.Component { + constructor(props) { + super(props) + + this.state = { + viewAs: props.viewAs + } + } + + render(){ + const { isDisabled, viewAs} = this.props; + + return( + + this.props.onClickViewSelector(item)} + size={16} + id="rowSelectorButton" + /> + + this.props.onClickViewSelector(item)} + size={16} + id="tileSelectorButton" + /> + + ) + } +} +ViewSelector.propTypes = { + isDisabled: PropTypes.bool, + viewAs: PropTypes.string, + onClickViewSelector: PropTypes.func +} + +ViewSelector.defaultProps = { + isDisabled: false +} + +export default ViewSelector; diff --git a/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.row.react.svg b/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.row.react.svg new file mode 100644 index 0000000000..3ef016e328 --- /dev/null +++ b/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.row.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.tile.react.svg b/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.tile.react.svg new file mode 100644 index 0000000000..8c7b17dccf --- /dev/null +++ b/web/ASC.Web.Components/src/components/icons/svg/filter.view.selector.tile.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/ASC.Web.Components/src/components/icons/svg/index.js b/web/ASC.Web.Components/src/components/icons/svg/index.js index c5f564a246..d3b56ffc79 100644 --- a/web/ASC.Web.Components/src/components/icons/svg/index.js +++ b/web/ASC.Web.Components/src/components/icons/svg/index.js @@ -133,6 +133,8 @@ import OrigCrossSidebarIcon from './cross.sidebar.react.svg'; import OrigCheckboxIcon from './checkbox.react.svg'; import OrigCheckboxCheckedIcon from './checkbox.checked.react.svg'; import OrigCheckboxIndeterminateIcon from './checkbox.indeterminate.react.svg'; +import OrigFilterViewSelectorRowIcon from './filter.view.selector.row.react.svg'; +import OrigFilterViewSelectorTileIcon from './filter.view.selector.tile.react.svg'; import OrigEyeIcon from './eye.react.svg'; import OrigEyeOffIcon from './eye.off.react.svg'; @@ -800,4 +802,12 @@ export const ShareLinkedInIcon = createStyledIcon( export const KeyIcon = createStyledIcon( OrigKeyIcon, 'KeyIcon' +); +export const FilterViewSelectorRowIcon = createStyledIcon( + OrigFilterViewSelectorRowIcon, + 'FilterViewSelectorRowIcon' +); +export const FilterViewSelectorTileIcon = createStyledIcon( + OrigFilterViewSelectorTileIcon, + 'FilterViewSelectorTileIcon' ); \ No newline at end of file From c2a9189d4e3eed7c9a2ff84908285339c8527052 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jun 2020 11:43:40 +0300 Subject: [PATCH 10/14] Web: Files: Home: Filter: Added viewSettings to SortComboBox for mobile devices --- .../pages/Home/Section/Filter/index.js | 15 +- .../src/components/FilterInput/FilterInput.js | 3 +- .../sub-components/SortComboBox.js | 269 ++++++++++-------- 3 files changed, 163 insertions(+), 124 deletions(-) diff --git a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js index 2e85f21d95..f701d71487 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js +++ b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js @@ -209,14 +209,21 @@ class SectionFilterContent extends React.Component { getSortData = () => { const { t } = this.props; - return [ + let commonOptions = [ { key: "lastModifiedDate", label: t("ByLastModifiedDate"), default: true }, { key: "creationDate", label: t("ByCreationDate"), default: true }, { key: "title", label: t("ByTitle"), default: true }, { key: "type", label: t("ByType"), default: true }, { key: "size", label: t("BySize"), default: true }, - { key: "author", label: t("ByAuthor"), default: true }, + { key: "author", label: t("ByAuthor"), default: true } ]; + + let viewSettings = [ + { key: "row", label: "Row", isSetting: true, default: true }, + { key: "tile", label: "Tile", isSetting: true, default: true } + ] + //TODO: Need use mobile detect for better result + return window.innerWidth < 460 ? [...commonOptions,...viewSettings] : commonOptions; }; getSelectedFilterData = () => { @@ -272,12 +279,12 @@ class SectionFilterContent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return (!isEqual(this.props.filter, nextProps.filter) || this.props.selectedFolderId !== nextProps.selectedFolderId || this.state.isReady !== nextState.isReady); } - + render() { const selectedFilterData = this.getSelectedFilterData(); const { t, i18n } = this.props; - const filterColumnCount = window.innerWidth < 500 ? {} : {filterColumnCount: 3} + const filterColumnCount = window.innerWidth < 500 ? {} : { filterColumnCount: 3 } return ( 0 ? getSortData().find(x => x.key === sortId) : {}} onButtonClick={this.onSortDirectionClick} diff --git a/web/ASC.Web.Common/src/components/FilterInput/sub-components/SortComboBox.js b/web/ASC.Web.Common/src/components/FilterInput/sub-components/SortComboBox.js index bc65f7114a..5901259040 100644 --- a/web/ASC.Web.Common/src/components/FilterInput/sub-components/SortComboBox.js +++ b/web/ASC.Web.Common/src/components/FilterInput/sub-components/SortComboBox.js @@ -5,137 +5,168 @@ import PropTypes from 'prop-types'; import { StyledIconButton } from '../StyledFilterInput'; class SortComboBox extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); - const { sortDirection } = props; + const { sortDirection } = props; - this.state = { - sortDirection - } - - this.combobox = React.createRef(); - } - onButtonClick = () => { - const { onChangeSortDirection } = this.props; - const { sortDirection } = this.state; - typeof onChangeSortDirection === 'function' && onChangeSortDirection(+(sortDirection === 0 ? 1 : 0)); - this.setState({ - sortDirection: sortDirection === 0 ? 1 : 0 - }); + this.state = { + sortDirection } - onChangeSortId = (e) => { - const { onChangeSortId } = this.props; - typeof onChangeSortId === 'function' && onChangeSortId(e.target.value); - } - onChangeSortDirection = (e) => { - const sortDirection = +e.target.value; - const { onChangeSortDirection } = this.props; - this.setState({ sortDirection }); - typeof onChangeSortDirection === 'function' && onChangeSortDirection(sortDirection); - } - shouldComponentUpdate(nextProps, nextState) { - //TODO - /*const comboboxText = this.combobox.current.ref.current.children[0].children[1]; - if(comboboxText.scrollWidth > Math.round(comboboxText.getBoundingClientRect().width)){ - comboboxText.style.opacity = "0"; - }else{ - comboboxText.style.opacity = "1"; - }*/ - const { sortDirection } = nextProps; - if (this.props.sortDirection !== sortDirection) { - this.setState({ - sortDirection - }); - return true; - } - return (!isEqual(this.props, nextProps) || !isEqual(this.state, nextState)); - } - render() { - const { options, directionAscLabel, directionDescLabel, isDisabled, - selectedOption } = this.props; - const { sortDirection } = this.state; - let sortArray = options.map(function (item) { - item.value = item.key - return item; - }); - let sortDirectionArray = [ - { value: '0', label: directionAscLabel }, - { value: '1', label: directionDescLabel } - ]; + this.combobox = React.createRef(); + } + onButtonClick = () => { + const { onChangeSortDirection } = this.props; + const { sortDirection } = this.state; + typeof onChangeSortDirection === 'function' && onChangeSortDirection(+(sortDirection === 0 ? 1 : 0)); + this.setState({ + sortDirection: sortDirection === 0 ? 1 : 0 + }); + } - const advancedOptions = ( - <> - - - - - - - - - ); - return ( - { + const { onChangeSortId } = this.props; + typeof onChangeSortId === 'function' && onChangeSortId(e.target.value); + } + + onChangeView = (e) => { + const { onChangeView } = this.props; + typeof onChangeView === 'function' && onChangeView(e.target.value); + } + + onChangeSortDirection = (e) => { + const sortDirection = +e.target.value; + const { onChangeSortDirection } = this.props; + this.setState({ sortDirection }); + typeof onChangeSortDirection === 'function' && onChangeSortDirection(sortDirection); + } + shouldComponentUpdate(nextProps, nextState) { + //TODO + /*const comboboxText = this.combobox.current.ref.current.children[0].children[1]; + if(comboboxText.scrollWidth > Math.round(comboboxText.getBoundingClientRect().width)){ + comboboxText.style.opacity = "0"; + }else{ + comboboxText.style.opacity = "1"; + }*/ + const { sortDirection } = nextProps; + if (this.props.sortDirection !== sortDirection) { + this.setState({ + sortDirection + }); + return true; + } + return (!isEqual(this.props, nextProps) || !isEqual(this.state, nextState)); + } + render() { + const { options, directionAscLabel, directionDescLabel, isDisabled, + selectedOption } = this.props; + const { sortDirection } = this.state; + + let settingsArray = options.filter(item => { + item.value = item.key + return item.isSetting === true; + }); + + let sortArray = options.filter(item => { + item.value = item.key + return item.isSetting !== true; + }); + + let sortDirectionArray = [ + { value: '0', label: directionAscLabel }, + { value: '1', label: directionDescLabel } + ]; + + const advancedOptions = ( + <> + + + + + + + + {settingsArray.length !== 0 && + <> + + + - - - - - ); - } + name={'view'} + onClick={this.onChangeView} + options={settingsArray} + orientation='vertical' + selected={selectedOption.key} + spacing='0px' + /> + + + } + + ); + return ( + + + + + + ); + } } SortComboBox.propTypes = { - directionAscLabel: PropTypes.string, - directionDescLabel: PropTypes.string, - isDisabled: PropTypes.bool, - onButtonClick: PropTypes.func, - onChangeSortDirection: PropTypes.func, - onChangeSortId: PropTypes.func, - sortDirection: PropTypes.number, + directionAscLabel: PropTypes.string, + directionDescLabel: PropTypes.string, + isDisabled: PropTypes.bool, + onButtonClick: PropTypes.func, + onChangeSortDirection: PropTypes.func, + onChangeSortId: PropTypes.func, + onChangeView: PropTypes.func, + sortDirection: PropTypes.number, } SortComboBox.defaultProps = { - isDisabled: false, - sortDirection: 0 + isDisabled: false, + sortDirection: 0 } From f8832977009140669a8e50d017a0ab96a5e5be5c Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jun 2020 11:43:48 +0300 Subject: [PATCH 11/14] web: common: bump version --- web/ASC.Web.Common/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ASC.Web.Common/package.json b/web/ASC.Web.Common/package.json index 23b7d1e365..d4f38ca8cd 100644 --- a/web/ASC.Web.Common/package.json +++ b/web/ASC.Web.Common/package.json @@ -1,6 +1,6 @@ { "name": "asc-web-common", - "version": "1.0.167", + "version": "1.0.168", "description": "Ascensio System SIA common components and solutions library", "license": "AGPL-3.0", "files": [ From d52c0a67b7cdfeb8fd4e910dcfc7ba38d8560094 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jun 2020 11:58:23 +0300 Subject: [PATCH 12/14] Web: Files: Home: Filter: Fixed init, added translation keys --- .../src/components/pages/Home/Section/Filter/index.js | 10 +++++----- .../components/pages/Home/locales/en/translation.json | 4 +++- .../components/pages/Home/locales/ru/translation.json | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js index f701d71487..83ab010646 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js +++ b/products/ASC.Files/Client/src/components/pages/Home/Section/Filter/index.js @@ -209,7 +209,7 @@ class SectionFilterContent extends React.Component { getSortData = () => { const { t } = this.props; - let commonOptions = [ + const commonOptions = [ { key: "lastModifiedDate", label: t("ByLastModifiedDate"), default: true }, { key: "creationDate", label: t("ByCreationDate"), default: true }, { key: "title", label: t("ByTitle"), default: true }, @@ -218,10 +218,10 @@ class SectionFilterContent extends React.Component { { key: "author", label: t("ByAuthor"), default: true } ]; - let viewSettings = [ - { key: "row", label: "Row", isSetting: true, default: true }, - { key: "tile", label: "Tile", isSetting: true, default: true } - ] + const viewSettings = [ + { key: "row", label: t("ViewList"), isSetting: true, default: true }, + { key: "tile", label: t("ViewTiles"), isSetting: true, default: true } + ]; //TODO: Need use mobile detect for better result return window.innerWidth < 460 ? [...commonOptions,...viewSettings] : commonOptions; }; diff --git a/products/ASC.Files/Client/src/components/pages/Home/locales/en/translation.json b/products/ASC.Files/Client/src/components/pages/Home/locales/en/translation.json index 9830c54451..9c21f7981a 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/locales/en/translation.json +++ b/products/ASC.Files/Client/src/components/pages/Home/locales/en/translation.json @@ -82,5 +82,7 @@ "TooltipElementMoveMessage": "Move {{element}}", "TooltipElementsMoveMessage": "Move {{element}} elements", "TooltipElementCopyMessage": "Copy {{element}}", - "TooltipElementsCopyMessage": "Copy {{element}} elements" + "TooltipElementsCopyMessage": "Copy {{element}} elements", + "ViewList": "List", + "ViewTiles": "Tiles" } \ No newline at end of file diff --git a/products/ASC.Files/Client/src/components/pages/Home/locales/ru/translation.json b/products/ASC.Files/Client/src/components/pages/Home/locales/ru/translation.json index e1f9fffc44..7cd85341b4 100644 --- a/products/ASC.Files/Client/src/components/pages/Home/locales/ru/translation.json +++ b/products/ASC.Files/Client/src/components/pages/Home/locales/ru/translation.json @@ -82,5 +82,7 @@ "TooltipElementMoveMessage": "Переместить {{element}}", "TooltipElementsMoveMessage": "Переместить {{element}} элемента(ов)", "TooltipElementCopyMessage": "Скопировать {{element}}", - "TooltipElementsCopyMessage": "Скопировать {{element}} элемента(ов)" + "TooltipElementsCopyMessage": "Скопировать {{element}} элемента(ов)", + "ViewList": "Список", + "ViewTiles": "Плитки" } \ No newline at end of file From 00d9c26640130ba2e51c42b52499d841083f9458 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jun 2020 12:26:14 +0300 Subject: [PATCH 13/14] Web: Common: Fixed itemId check for filter change view --- web/ASC.Web.Common/src/components/FilterInput/FilterInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js index 3ae07424d4..f893273f09 100644 --- a/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js +++ b/web/ASC.Web.Common/src/components/FilterInput/FilterInput.js @@ -238,7 +238,7 @@ class FilterInput extends React.Component { this.setState({ sortDirection: !!key }); } onClickViewSelector(item) { - const itemId = item || (item.target.dataset && item.target.dataset.for); + const itemId = (item.target && item.target.dataset.for) || item; const viewAs = itemId.indexOf("row") === -1 ? "tile" : "row" this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "desc" : "asc", viewAs); this.setState({ viewAs: viewAs }); From 6c07204658bd94bb75fbede8397eebbb9a1e65d6 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jun 2020 12:26:21 +0300 Subject: [PATCH 14/14] web: common: bump version --- web/ASC.Web.Common/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ASC.Web.Common/package.json b/web/ASC.Web.Common/package.json index d4f38ca8cd..3ad37f63dc 100644 --- a/web/ASC.Web.Common/package.json +++ b/web/ASC.Web.Common/package.json @@ -1,6 +1,6 @@ { "name": "asc-web-common", - "version": "1.0.168", + "version": "1.0.169", "description": "Ascensio System SIA common components and solutions library", "license": "AGPL-3.0", "files": [