Merge branch 'develop' into feature/create-room
This commit is contained in:
commit
8f5f597c5f
@ -42,6 +42,9 @@ KAFKA_HOST = os.environ["KAFKA_HOST"] if environ.get("KAFKA_HOST") else "kafka:9
|
||||
RUN_FILE = sys.argv[1] if sys.argv[1] else "none"
|
||||
LOG_FILE = sys.argv[2] if sys.argv[2] else "none"
|
||||
|
||||
REDIS_HOST=os.environ["REDIS_HOST"] if environ.get("REDIS_HOST") else "onlyoffice-redis"
|
||||
RABBIT_HOST=os.environ["RABBIT_HOST"] if environ.get("RABBIT_HOST") else "onlyoffice-rabbitmq"
|
||||
|
||||
class RunServices:
|
||||
def __init__(self, SERVICE_PORT, PATH_TO_CONF):
|
||||
self.SERVICE_PORT = SERVICE_PORT
|
||||
@ -68,7 +71,7 @@ class RunServices:
|
||||
self.RunService(RUN_FILE, ENV_EXTENSION)
|
||||
elif ENV_EXTENSION == "none":
|
||||
os.system("dotnet " + RUN_FILE + " --urls=" + URLS + self.SERVICE_PORT +\
|
||||
" --$STORAGE_ROOT=" + APP_STORAGE_ROOT +\
|
||||
" --\'$STORAGE_ROOT\'=" + APP_STORAGE_ROOT +\
|
||||
" --pathToConf=" + self.PATH_TO_CONF +\
|
||||
" --log:dir=" + LOG_DIR +\
|
||||
" --log:name=" + LOG_FILE +\
|
||||
@ -76,7 +79,7 @@ class RunServices:
|
||||
" core:products:subfolder=server")
|
||||
else:
|
||||
os.system("dotnet " + RUN_FILE + " --urls=" + URLS + self.SERVICE_PORT +\
|
||||
" --$STORAGE_ROOT=" + APP_STORAGE_ROOT +\
|
||||
" --\'$STORAGE_ROOT\'=" + APP_STORAGE_ROOT +\
|
||||
" --pathToConf=" + self.PATH_TO_CONF +\
|
||||
" --log:dir=" + LOG_DIR +\
|
||||
" --log:name=" + LOG_FILE +\
|
||||
@ -159,12 +162,12 @@ writeJsonFile(filePath, jsonData)
|
||||
|
||||
filePath = "/app/onlyoffice/config/rabbitmq.json"
|
||||
jsonData = openJsonFile(filePath)
|
||||
updateJsonData(jsonData,"$.RabbitMQ.Hostname", "onlyoffice-rebbitmq")
|
||||
updateJsonData(jsonData,"$.RabbitMQ.Hostname", RABBIT_HOST)
|
||||
writeJsonFile(filePath, jsonData)
|
||||
|
||||
filePath = "/app/onlyoffice/config/redis.json"
|
||||
jsonData = openJsonFile(filePath)
|
||||
updateJsonData(jsonData,"$.Redis.Hosts.[0].Host", "onlyoffice-redis")
|
||||
updateJsonData(jsonData,"$.Redis.Hosts.[0].Host", REDIS_HOST)
|
||||
writeJsonFile(filePath, jsonData)
|
||||
|
||||
run = RunServices(SERVICE_PORT, PATH_TO_CONF)
|
||||
|
13
build/install/docker/rabbitmq.yml
Normal file
13
build/install/docker/rabbitmq.yml
Normal file
@ -0,0 +1,13 @@
|
||||
version: '3'
|
||||
services:
|
||||
onlyoffice-rabbitmq:
|
||||
image: rabbitmq:3
|
||||
container_name: onlyoffice-rabbitmq
|
||||
restart: always
|
||||
expose:
|
||||
- "5672"
|
||||
- "80"
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
@ -6,15 +6,6 @@ services:
|
||||
restart: always
|
||||
expose:
|
||||
- "6379"
|
||||
|
||||
onlyoffice-rebbitmq:
|
||||
image: rabbitmq:3
|
||||
container_name: onlyoffice-rebbitmq
|
||||
restart: always
|
||||
expose:
|
||||
- "5672"
|
||||
- "80"
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
@ -34,10 +34,10 @@
|
||||
<ROW Property="Manufacturer" Value="Ascensio System SIA"/>
|
||||
<ROW Property="MsiLogging" MultiBuildValue="DefaultBuild:vp"/>
|
||||
<ROW Property="MySQLConnector" Value="MySQL Connector/ODBC 8.0.21 x86"/>
|
||||
<ROW Property="PACKAGE_NAME" Value="ONLYOFFICE_AppServer_Win-install.v[|ProductVersion]"/>
|
||||
<ROW Property="PACKAGE_NAME" Value="ONLYOFFICE_DocSpace_Win-install.v[|ProductVersion]"/>
|
||||
<ROW Property="PASSWORD_PROP" Value="root"/>
|
||||
<ROW Property="PORT_PROP" Value="3306"/>
|
||||
<ROW Property="PRODUCT_NAME" Value="ONLYOFFICE AppServer"/>
|
||||
<ROW Property="PRODUCT_NAME" Value="ONLYOFFICE DocSpace"/>
|
||||
<ROW Property="ProductCode" Value="1033:{3FABEB4A-D27F-4BA6-A40E-16BE47540727} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="[|PRODUCT_NAME] [|ProductVersion]"/>
|
||||
@ -196,7 +196,7 @@
|
||||
<ROW Action="AI_DetectSoftware" Sequence="151"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="ONLYOFFICE_EXE" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|PACKAGE_NAME]" Languages="en" InstallationType="4" CabsLocation="1" PackageType="1" FilesInsideExe="true" ExeIconPath="Resources\icon.ico" ExtractionFolder="[AppDataFolder][|INSTALL_ROOT_FOLDER_NAME]\AppServer\install" ExtUI="true" UseLargeSchema="true" Unicode="true" ExeName="[|PACKAGE_NAME]" UACExecutionLevel="2"/>
|
||||
<ROW BuildKey="DefaultBuild" BuildName="ONLYOFFICE_EXE" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|PACKAGE_NAME]" Languages="en" InstallationType="4" CabsLocation="1" PackageType="1" FilesInsideExe="true" ExeIconPath="Resources\icon.ico" ExtractionFolder="[AppDataFolder][|INSTALL_ROOT_FOLDER_NAME]\DocSpace\install" ExtUI="true" UseLargeSchema="true" Unicode="true" ExeName="[|PACKAGE_NAME]" UACExecutionLevel="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
@ -636,12 +636,12 @@
|
||||
<ROW Action="ElasticSearchSetup" Type="6" Source="utils.vbs" Target="ElasticSearchSetup"/>
|
||||
<ROW Action="MySQLConfigure" Type="70" Source="utils.vbs" Target="MySQLConfigure"/>
|
||||
<ROW Action="MySQLConfigureGUI" Type="6" Source="utils.vbs" Target="MySQLConfigure"/>
|
||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[ProgramFilesFolder][INSTALL_ROOT_FOLDER_NAME]\AppServer"/>
|
||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]" MultiBuildTarget="DefaultBuild:[ProgramMenuFolder][INSTALL_ROOT_FOLDER_NAME]\AppServer"/>
|
||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[ProgramFilesFolder][INSTALL_ROOT_FOLDER_NAME]\DocSpace"/>
|
||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]" MultiBuildTarget="DefaultBuild:[ProgramMenuFolder][INSTALL_ROOT_FOLDER_NAME]\DocSpace"/>
|
||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||
<ROW Action="Set_APPDIR_FORWARD_SLASH" Type="38" Target="Script Text" TargetUnformatted="Session.Property("APPDIR_FORWARD_SLASH") = Replace(Session.Property("APPDIR"), "\", "/") " AdditionalSeq="AI_DATA_SETTER_6"/>
|
||||
<ROW Action="StartElasticSearchService" Type="3073" Source="aicustact.dll" Target="StartWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_13"/>
|
||||
<ROW Action="StartMigrationRunner" Type="3090" Source="ASC.Migration.Runner.exe"/>
|
||||
<ROW Action="StartMigrationRunner" Type="3106" Source="service_6_Dir" Target=""[APPDIR]services\ASC.Migration.Runner\service\ASC.Migration.Runner.exe""/>
|
||||
<ROW Action="StartMySQLService" Type="1" Source="aicustact.dll" Target="StartWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_11"/>
|
||||
<ROW Action="StopElasticSearchService" Type="1" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_12"/>
|
||||
<ROW Action="StopMySQLService" Type="1" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_10"/>
|
||||
@ -740,7 +740,7 @@
|
||||
<ROW Action="StartElasticSearchService" Condition="( NOT Installed )" Sequence="1613"/>
|
||||
<ROW Action="AI_DATA_SETTER_13" Condition="( NOT Installed )" Sequence="1612"/>
|
||||
<ROW Action="AI_GetArpIconPath" Sequence="1401"/>
|
||||
<ROW Action="StartMigrationRunner" Condition="( NOT Installed )" Sequence="6401"/>
|
||||
<ROW Action="StartMigrationRunner" Condition="( NOT Installed )" Sequence="5826"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
@ -57,6 +57,6 @@ del /f /q build\install\win\*.back.*
|
||||
REM echo ######## Build MySQL Server Installer ########
|
||||
iscc /Qp /S"byparam="signtool" sign /a /n "%publisher%" /t http://timestamp.digicert.com $f" "build\install\win\MySQL Server Installer Runner.iss"
|
||||
|
||||
REM echo ######## Build AppServer package ########
|
||||
%AdvancedInstaller% /edit build\install\win\AppServer.aip /SetVersion %BUILD_VERSION%.%BUILD_NUMBER%
|
||||
%AdvancedInstaller% /rebuild build\install\win\AppServer.aip
|
||||
REM echo ######## Build DocSpace package ########
|
||||
%AdvancedInstaller% /edit build\install\win\DocSpace.aip /SetVersion %BUILD_VERSION%.%BUILD_NUMBER%
|
||||
%AdvancedInstaller% /rebuild build\install\win\DocSpace.aip
|
||||
|
@ -25,6 +25,7 @@
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using JsonConverter = System.Text.Json.Serialization.JsonConverter;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace ASC.Api.Core;
|
||||
|
||||
@ -156,6 +157,12 @@ public abstract class BaseStartup
|
||||
}
|
||||
|
||||
services.AddAutoMapper(typeof(MappingProfile));
|
||||
|
||||
if (!_hostEnvironment.IsDevelopment())
|
||||
{
|
||||
services.AddStartupTask<WarmupServicesStartupTask>()
|
||||
.TryAddSingleton(services);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
|
92
common/ASC.Api.Core/Core/WarmupServicesStartupTask.cs
Normal file
92
common/ASC.Api.Core/Core/WarmupServicesStartupTask.cs
Normal file
@ -0,0 +1,92 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Api.Core.Core;
|
||||
|
||||
/// <summary>
|
||||
/// https://andrewlock.net/reducing-latency-by-pre-building-singletons-in-asp-net-core/
|
||||
/// </summary>
|
||||
public class WarmupServicesStartupTask : IStartupTask
|
||||
{
|
||||
private readonly IServiceCollection _services;
|
||||
private readonly IServiceProvider _provider;
|
||||
public WarmupServicesStartupTask(IServiceCollection services, IServiceProvider provider)
|
||||
{
|
||||
_services = services;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var processedFailed = 0;
|
||||
var processedSuccessed = 0;
|
||||
var startTime = DateTime.UtcNow;
|
||||
|
||||
using (var scope = _provider.CreateScope())
|
||||
{
|
||||
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
|
||||
var logger = scope.ServiceProvider.GetService<ILogger<WarmupServicesStartupTask>>();
|
||||
|
||||
logger.TraceWarmupStarted();
|
||||
|
||||
tenantManager.SetCurrentTenant("localhost");
|
||||
|
||||
foreach (var service in GetServices(_services))
|
||||
{
|
||||
try
|
||||
{
|
||||
scope.ServiceProvider.GetServices(service);
|
||||
|
||||
processedSuccessed++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
processedFailed++;
|
||||
|
||||
logger.DebugWarmupFailed(processedFailed, service.FullName, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
var processed = processedSuccessed + processedFailed;
|
||||
|
||||
logger.TraceWarmupFinished(processed,
|
||||
processedSuccessed,
|
||||
processedFailed,
|
||||
(DateTime.UtcNow - startTime).TotalMilliseconds);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
static IEnumerable<Type> GetServices(IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.Where(descriptor => descriptor.ImplementationType != typeof(WarmupServicesStartupTask))
|
||||
.Where(descriptor => descriptor.ServiceType.ContainsGenericParameters == false)
|
||||
.Select(descriptor => descriptor.ServiceType)
|
||||
.Distinct();
|
||||
}
|
||||
}
|
50
common/ASC.Api.Core/Extensions/HostExtension.cs
Normal file
50
common/ASC.Api.Core/Extensions/HostExtension.cs
Normal file
@ -0,0 +1,50 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Api.Core.Extensions;
|
||||
|
||||
public interface IStartupTask
|
||||
{
|
||||
Task ExecuteAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public static class HostExtension
|
||||
{
|
||||
public static async Task RunWithTasksAsync(this WebApplication webHost, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Load all tasks from DI
|
||||
var startupTasks = webHost.Services.GetServices<IStartupTask>();
|
||||
|
||||
// Execute all the tasks
|
||||
foreach (var startupTask in startupTasks)
|
||||
{
|
||||
await startupTask.ExecuteAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// Start the tasks as normal
|
||||
await webHost.RunAsync(cancellationToken);
|
||||
}
|
||||
}
|
@ -169,4 +169,12 @@ public static class ServiceCollectionExtension
|
||||
|
||||
services.AddSingleton<IDistributedTaskQueueFactory, DefaultDistributedTaskQueueFactory>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddStartupTask<T>(this IServiceCollection services)
|
||||
where T : class, IStartupTask
|
||||
{
|
||||
services.AddTransient<IStartupTask, T>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
45
common/ASC.Api.Core/Log/WarmupServicesStartupTaskLogger.cs
Normal file
45
common/ASC.Api.Core/Log/WarmupServicesStartupTaskLogger.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ASC.Api.Core.Log;
|
||||
|
||||
internal static partial class WarmupServicesStartupTaskLogger
|
||||
{
|
||||
[LoggerMessage(Level = LogLevel.Trace, Message = "Warm up services is starting...")]
|
||||
public static partial void TraceWarmupStarted(this ILogger<WarmupServicesStartupTask> logger);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Trace, Message = "Warm up services finished. Processed: {processed}, Successed: {successed}, Failed: {failed}, Time: {processedTime} ms")]
|
||||
public static partial void TraceWarmupFinished(this ILogger<WarmupServicesStartupTask> logger, int processed, int successed, int failed, double processedTime);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "#{index} Failed proccessed {serviceTitle} service with exception {errorMessage}")]
|
||||
public static partial void DebugWarmupFailed(this ILogger<WarmupServicesStartupTask> logger, int index, String serviceTitle, String errorMessage);
|
||||
}
|
@ -41,7 +41,15 @@ public class MappingProfile : Profile
|
||||
return;
|
||||
}
|
||||
|
||||
var types = assembly.GetExportedTypes().Where(t => t.IsClosedTypeOf(typeof(IMapFrom<>)) || (t.IsGenericType && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))));
|
||||
var mapFromType = typeof(IMapFrom<>);
|
||||
|
||||
var mappingMethodName = nameof(IMapFrom<object>.Mapping);
|
||||
|
||||
bool HasInterface(Type t) => t.IsGenericType && t.GetGenericTypeDefinition() == mapFromType;
|
||||
|
||||
var types = assembly.GetExportedTypes().Where(t => t.GetInterfaces().Any(HasInterface)).ToList();
|
||||
|
||||
var argumentTypes = new Type[] { typeof(Profile) };
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
@ -49,10 +57,26 @@ public class MappingProfile : Profile
|
||||
|
||||
var instance = Activator.CreateInstance(resolvedType);
|
||||
|
||||
var methodInfo = resolvedType.GetMethod("Mapping")
|
||||
?? resolvedType.GetInterface("IMapFrom`1").GetMethod("Mapping");
|
||||
var methodInfo = resolvedType.GetMethod(mappingMethodName);
|
||||
|
||||
methodInfo?.Invoke(instance, new object[] { this });
|
||||
if (methodInfo != null)
|
||||
{
|
||||
methodInfo.Invoke(instance, new object[] { this });
|
||||
}
|
||||
else
|
||||
{
|
||||
var interfaces = resolvedType.GetInterfaces().Where(HasInterface).ToList();
|
||||
|
||||
if (interfaces.Count > 0)
|
||||
{
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceMethodInfo = @interface.GetMethod(mappingMethodName, argumentTypes);
|
||||
|
||||
interfaceMethodInfo?.Invoke(instance, new object[] { this });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,4 +48,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
@ -45,4 +45,5 @@ builder.Host.ConfigureContainer<ContainerBuilder>((context, builder) =>
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
await app.RunAsync();
|
||||
|
||||
await app.RunWithTasksAsync();
|
@ -63,7 +63,7 @@ eventBus.Subscribe<BackupRequestIntegrationEvent, BackupRequestedIntegrationEven
|
||||
eventBus.Subscribe<BackupRestoreRequestIntegrationEvent, BackupRestoreRequestedIntegrationEventHandler>();
|
||||
eventBus.Subscribe<IntegrationEvent, BackupDeleteScheldureRequestedIntegrationEventHandler>();
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
||||
|
||||
|
||||
public partial class Program
|
||||
|
@ -56,4 +56,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
@ -82,7 +82,7 @@ var eventBus = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService
|
||||
eventBus.Subscribe<NotifyInvokeSendMethodRequestedIntegrationEvent, NotifyInvokeSendMethodRequestedIntegrationEventHandler>();
|
||||
eventBus.Subscribe<NotifySendMessageRequestedIntegrationEvent, NotifySendMessageRequestedIntegrationEventHandler>();
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
|
@ -65,4 +65,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app);
|
||||
|
||||
await app.RunAsync();
|
||||
await app.RunWithTasksAsync();
|
@ -57,7 +57,7 @@ var eventBus = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService
|
||||
|
||||
eventBus.Subscribe<ASC.Core.Common.Notify.IntegrationEvents.Events.NotifySendTelegramMessageRequestedIntegrationEvent, TelegramSendMessageRequestedIntegrationEventHandler>();
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
|
@ -58,4 +58,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app);
|
||||
|
||||
await app.RunAsync();
|
||||
await app.RunWithTasksAsync();
|
@ -248,8 +248,8 @@ const withHotkeys = (Component) => {
|
||||
deleteOperation: t("Translations:DeleteOperation"),
|
||||
deleteFromTrash: t("Translations:DeleteFromTrash"),
|
||||
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||
FileRemoved: t("Home:FileRemoved"),
|
||||
FolderRemoved: t("Home:FolderRemoved"),
|
||||
FileRemoved: t("Files:FileRemoved"),
|
||||
FolderRemoved: t("Files:FolderRemoved"),
|
||||
};
|
||||
deleteAction(translations).catch((err) => toastr.error(err));
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ import { combineUrl, updateTempContent } from "@docspace/common/utils";
|
||||
import { Provider as MobxProvider } from "mobx-react";
|
||||
import ThemeProvider from "@docspace/components/theme-provider";
|
||||
|
||||
import store from "client/store";
|
||||
import filesStores from "./store/index.Files";
|
||||
import store from "SRC_DIR/store";
|
||||
|
||||
import config from "PACKAGE_FILE";
|
||||
import { I18nextProvider, useTranslation } from "react-i18next";
|
||||
@ -600,7 +599,7 @@ const ThemeProviderWrapper = inject(({ auth }) => {
|
||||
})(observer(ThemeProvider));
|
||||
|
||||
export default () => (
|
||||
<MobxProvider {...store} {...filesStores}>
|
||||
<MobxProvider {...store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<ThemeProviderWrapper>
|
||||
<ShellWrapper />
|
||||
|
@ -170,7 +170,7 @@ const ArticleMainButtonContent = (props) => {
|
||||
id: "main-button_new-room",
|
||||
className: "main-button_drop-down",
|
||||
icon: "images/folder.locked.react.svg",
|
||||
label: t("Home:NewRoom"),
|
||||
label: t("Files:NewRoom"),
|
||||
onClick: onCreateRoom,
|
||||
action: "room",
|
||||
key: "room",
|
||||
|
@ -113,7 +113,7 @@ const RenameEvent = ({
|
||||
<Dialog
|
||||
t={t}
|
||||
visible={visible}
|
||||
title={t("Home: Rename")}
|
||||
title={t("Files:Rename")}
|
||||
startValue={startValue}
|
||||
onSave={onUpdate}
|
||||
onCancel={onCancel}
|
||||
|
@ -140,11 +140,12 @@ class NavMenu extends React.Component {
|
||||
history,
|
||||
isDesktop,
|
||||
preparationPortalDialogVisible,
|
||||
isFrame,
|
||||
showHeader,
|
||||
} = this.props;
|
||||
|
||||
const isAsideAvailable = !!asideContent;
|
||||
const hideHeader =
|
||||
isDesktop || history.location.pathname === "/products/files/private";
|
||||
const hideHeader = isDesktop || (!showHeader && isFrame);
|
||||
//console.log("NavMenu render", this.state, this.props);
|
||||
const isPreparationPortal =
|
||||
history.location.pathname === "/preparation-portal";
|
||||
@ -221,7 +222,7 @@ NavMenu.defaultProps = {
|
||||
|
||||
const NavMenuWrapper = inject(({ auth, backup }) => {
|
||||
const { settingsStore, isAuthenticated, isLoaded, language } = auth;
|
||||
const { isDesktopClient: isDesktop } = settingsStore;
|
||||
const { isDesktopClient: isDesktop, frameConfig, isFrame } = settingsStore;
|
||||
const { preparationPortalDialogVisible } = backup;
|
||||
return {
|
||||
isAuthenticated,
|
||||
@ -229,6 +230,8 @@ const NavMenuWrapper = inject(({ auth, backup }) => {
|
||||
isDesktop,
|
||||
language,
|
||||
preparationPortalDialogVisible,
|
||||
showHeader: frameConfig?.showHeader,
|
||||
isFrame,
|
||||
};
|
||||
})(observer(withTranslation(["NavMenu", "Common"])(withRouter(NavMenu))));
|
||||
|
||||
|
@ -83,7 +83,7 @@ const PureConnectDialogContainer = (props) => {
|
||||
//const chars = '*+:"<>?|/'; TODO: think how to solve problem with interpolation escape values in i18n translate
|
||||
|
||||
if (title.match(folderFormValidation)) {
|
||||
toastr.warning(t("Home:ContainsSpecCharacter"));
|
||||
toastr.warning(t("Files:ContainsSpecCharacter"));
|
||||
}
|
||||
title = title.replace(folderFormValidation, "_");
|
||||
|
||||
|
@ -59,8 +59,8 @@ const DeleteDialogComponent = (props) => {
|
||||
deleteOperation: t("Translations:DeleteOperation"),
|
||||
deleteFromTrash: t("Translations:DeleteFromTrash"),
|
||||
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||
FileRemoved: t("Home:FileRemoved"),
|
||||
FolderRemoved: t("Home:FolderRemoved"),
|
||||
FileRemoved: t("Files:FileRemoved"),
|
||||
FolderRemoved: t("Files:FolderRemoved"),
|
||||
};
|
||||
|
||||
if (!selection.length) return;
|
||||
@ -156,6 +156,7 @@ const DeleteDialog = withTranslation([
|
||||
"DeleteDialog",
|
||||
"Common",
|
||||
"Translations",
|
||||
"Files",
|
||||
])(DeleteDialogComponent);
|
||||
|
||||
export default inject(
|
||||
|
@ -161,7 +161,7 @@ const OperationsPanelComponent = (props) => {
|
||||
? t("Common:Restore")
|
||||
: isCopy
|
||||
? t("Translations:Copy")
|
||||
: t("Home:MoveTo")
|
||||
: t("Files:MoveTo")
|
||||
}
|
||||
buttonName={
|
||||
isRecycleBin
|
||||
|
@ -2,8 +2,7 @@ import React from "react";
|
||||
import { Provider as MobxProvider, inject, observer } from "mobx-react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import SelectFileDialog from "./index";
|
||||
import stores from "../../../store/index.Files";
|
||||
import store from "client/store";
|
||||
import store from "SRC_DIR/store";
|
||||
import i18n from "./i18n";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
@ -32,7 +31,7 @@ class SelectFileDialogWrapper extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider auth={authStore} {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<SelectFileWrapper {...this.props} />
|
||||
</I18nextProvider>
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from "react";
|
||||
import { Provider as MobxProvider } from "mobx-react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import stores from "../../../store/index.Files";
|
||||
import store from "client/store";
|
||||
import store from "SRC_DIR/store";
|
||||
import SelectFileInput from "./index";
|
||||
import i18n from "./i18n";
|
||||
const { auth: authStore } = store;
|
||||
@ -16,7 +15,7 @@ class SelectFileInputWrapper extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider auth={authStore} {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<SelectFileModalWrapper {...this.props} />
|
||||
</I18nextProvider>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import { Provider as MobxProvider, inject, observer } from "mobx-react";
|
||||
import PropTypes from "prop-types";
|
||||
import stores from "../../../store/index.Files";
|
||||
import SelectFileDialog from "../SelectFileDialog";
|
||||
import StyledComponent from "./StyledSelectFileInput";
|
||||
import SimpleFileInput from "../../SimpleFileInput";
|
||||
import store from "SRC_DIR/store";
|
||||
|
||||
class SelectFileInputBody extends React.PureComponent {
|
||||
constructor(props) {
|
||||
@ -88,7 +88,7 @@ const SelectFileInputBodyWrapper = inject(({ filesStore }) => {
|
||||
class SelectFileInput extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<SelectFileInputBodyWrapper {...this.props} />
|
||||
</MobxProvider>
|
||||
);
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from "react";
|
||||
import { Provider as MobxProvider, inject, observer } from "mobx-react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import stores from "../../../store/index.Files";
|
||||
import store from "client/store";
|
||||
import store from "SRC_DIR/store";
|
||||
import SelectFolderDialog from "./index";
|
||||
import i18n from "./i18n";
|
||||
import { getFolder } from "@docspace/common/api/files";
|
||||
@ -76,7 +75,7 @@ class SelectFolderModal extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider auth={authStore} {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<SelectFolderModalWrapper {...this.props} />
|
||||
</I18nextProvider>
|
||||
|
@ -1,10 +1,9 @@
|
||||
import React from "react";
|
||||
import { Provider as MobxProvider } from "mobx-react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import stores from "../../../store/index.Files";
|
||||
import store from "client/store";
|
||||
import SelectFolderInput from "./index";
|
||||
import i18n from "./i18n";
|
||||
import store from "SRC_DIR/store";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
const SelectFolderModalWrapper = (props) => <SelectFolderInput {...props} />;
|
||||
@ -16,7 +15,7 @@ class SelectFolderInputWrapper extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider auth={authStore} {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<SelectFolderModalWrapper {...this.props} />
|
||||
</I18nextProvider>
|
||||
|
@ -196,7 +196,7 @@ const FilesListBody = ({
|
||||
<div className="select-file-dialog_empty-container">
|
||||
<EmptyContainer
|
||||
theme={theme}
|
||||
headerText={t("Home:EmptyFolderHeader")}
|
||||
headerText={t("Files:EmptyFolderHeader")}
|
||||
imageSrc="/static/images/empty.screen.react.svg"
|
||||
/>
|
||||
</div>
|
||||
|
@ -2,10 +2,7 @@ import React, { useEffect } from "react";
|
||||
import { Provider as MobxProvider, inject, observer } from "mobx-react";
|
||||
import { getShareFiles } from "@docspace/common/api/files";
|
||||
import SharingPanel from "../SharingPanel";
|
||||
|
||||
import stores from "../../../store/index.Files";
|
||||
import store from "client/store";
|
||||
|
||||
import store from "SRC_DIR/store";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
const SharingDialog = ({
|
||||
@ -69,7 +66,7 @@ class SharingModal extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MobxProvider auth={authStore} {...stores}>
|
||||
<MobxProvider {...store}>
|
||||
<SharingDialogWrapper {...this.props} />
|
||||
</MobxProvider>
|
||||
);
|
||||
|
@ -86,7 +86,7 @@ class UploadPanelComponent extends React.Component {
|
||||
? t("Uploads")
|
||||
: isUploadingAndConversion
|
||||
? t("UploadAndConvert")
|
||||
: t("Home:Convert");
|
||||
: t("Files:Convert");
|
||||
|
||||
return (
|
||||
<StyledAsidePanel visible={visible}>
|
||||
|
@ -1,9 +1,8 @@
|
||||
import filesStore from "../store";
|
||||
import store from "client/store";
|
||||
import store from "SRC_DIR/store";
|
||||
import { desktopConstants } from "@docspace/common/desktop";
|
||||
|
||||
export function encryptionUploadDialog(callback) {
|
||||
const filter = filesStore.settingsStore.extsWebEncrypt
|
||||
const filter = store.filesStore.settingsStore.extsWebEncrypt
|
||||
.map((f) => "*" + f)
|
||||
.join(" ");
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import authStore from "SRC_DIR/store/AuthStore";
|
||||
import { AppServerConfig, RoomsType } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
import { combineUrl, toUrlParams } from "@docspace/common/utils";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import authStore from "SRC_DIR/store/AuthStore";
|
||||
import { toCommunityHostname } from "@docspace/common/utils";
|
||||
import history from "@docspace/common/history";
|
||||
import { useEffect, useState } from "react";
|
||||
|
@ -203,13 +203,17 @@ class FilesContent extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
//const { /*, isDesktop*/ } = this.props;
|
||||
const { showArticle, isFrame } = this.props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<GlobalEvents />
|
||||
<Panels />
|
||||
{isFrame ? (
|
||||
showArticle && <FilesArticle history={this.props.history} />
|
||||
) : (
|
||||
<FilesArticle history={this.props.history} />
|
||||
)}
|
||||
<FilesSection />
|
||||
</>
|
||||
);
|
||||
@ -217,16 +221,26 @@ class FilesContent extends React.Component {
|
||||
}
|
||||
|
||||
const Files = inject(({ auth, filesStore }) => {
|
||||
const {
|
||||
frameConfig,
|
||||
isFrame,
|
||||
isDesktopClient,
|
||||
encryptionKeys,
|
||||
setEncryptionKeys,
|
||||
isEncryptionSupport,
|
||||
} = auth.settingsStore;
|
||||
return {
|
||||
isDesktop: auth.settingsStore.isDesktopClient,
|
||||
isDesktop: isDesktopClient,
|
||||
isFrame,
|
||||
showArticle: frameConfig?.showArticle,
|
||||
user: auth.userStore.user,
|
||||
isAuthenticated: auth.isAuthenticated,
|
||||
encryptionKeys: auth.settingsStore.encryptionKeys,
|
||||
isEncryption: auth.settingsStore.isEncryptionSupport,
|
||||
encryptionKeys: encryptionKeys,
|
||||
isEncryption: isEncryptionSupport,
|
||||
isLoaded: auth.isLoaded && filesStore.isLoaded,
|
||||
setIsLoaded: filesStore.setIsLoaded,
|
||||
|
||||
setEncryptionKeys: auth.settingsStore.setEncryptionKeys,
|
||||
setEncryptionKeys: setEncryptionKeys,
|
||||
loadFilesInfo: async () => {
|
||||
await filesStore.initFiles();
|
||||
//auth.setProductVersion(config.version);
|
||||
|
@ -55,7 +55,9 @@ const SingleItem = (props) => {
|
||||
|
||||
<StyledProperties>
|
||||
<div className="property">
|
||||
<Text className="property-title">{t("Home:ByLastModifiedDate")}</Text>
|
||||
<Text className="property-title">
|
||||
{t("Files:ByLastModifiedDate")}
|
||||
</Text>
|
||||
<Text className="property-content">
|
||||
{parseAndFormatDate(selectedItem.attributes.updatedAt)}
|
||||
</Text>
|
||||
|
@ -101,13 +101,13 @@ const SingleItem = (props) => {
|
||||
case FileType.Image:
|
||||
return t("Common:Image");
|
||||
case FileType.Spreadsheet:
|
||||
return t("Home:Spreadsheet");
|
||||
return t("Files:Spreadsheet");
|
||||
case FileType.Presentation:
|
||||
return t("Home:Presentation");
|
||||
return t("Files:Presentation");
|
||||
case FileType.Document:
|
||||
return t("Home:Document");
|
||||
return t("Files:Document");
|
||||
default:
|
||||
return t("Home:Folder");
|
||||
return t("Files:Folder");
|
||||
}
|
||||
};
|
||||
|
||||
@ -147,7 +147,7 @@ const SingleItem = (props) => {
|
||||
},
|
||||
{
|
||||
id: "ByLastModifiedDate",
|
||||
title: t("Home:ByLastModifiedDate"),
|
||||
title: t("Files:ByLastModifiedDate"),
|
||||
content: styledText(parseAndFormatDate(item.updated)),
|
||||
},
|
||||
{
|
||||
@ -162,7 +162,7 @@ const SingleItem = (props) => {
|
||||
},
|
||||
{
|
||||
id: "ByCreationDate",
|
||||
title: t("Home:ByCreationDate"),
|
||||
title: t("Files:ByCreationDate"),
|
||||
content: styledText(parseAndFormatDate(item.created)),
|
||||
},
|
||||
];
|
||||
|
@ -7,140 +7,6 @@ class FilesTableHeader extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// const defaultColumns = [];
|
||||
// if (isRooms) {
|
||||
// const columns = [
|
||||
// {
|
||||
// key: "Name",
|
||||
// title: t("Common:Name"),
|
||||
// resizable: true,
|
||||
// enable: true,
|
||||
// default: true,
|
||||
// sortBy: "AZ",
|
||||
// minWidth: 210,
|
||||
// onClick: this.onRoomsFilter,
|
||||
// },
|
||||
// {
|
||||
// key: "Type",
|
||||
// title: t("Common:Type"),
|
||||
// enable: false,
|
||||
// resizable: true,
|
||||
// sortBy: "roomType",
|
||||
// onChange: this.onColumnChange,
|
||||
// onClick: this.onRoomsFilter,
|
||||
// },
|
||||
// {
|
||||
// key: "Tags",
|
||||
// title: t("Tags"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "Tags",
|
||||
// onChange: this.onColumnChange,
|
||||
// onClick: this.onRoomsFilter,
|
||||
// },
|
||||
// {
|
||||
// key: "Owner",
|
||||
// title: t("ByOwner"),
|
||||
// enable: false,
|
||||
// resizable: true,
|
||||
// sortBy: "Author",
|
||||
// onChange: this.onColumnChange,
|
||||
// onClick: this.onRoomsFilter,
|
||||
// },
|
||||
// {
|
||||
// key: "Activity",
|
||||
// title: t("ByLastModifiedDate"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "DateAndTime",
|
||||
// onChange: this.onColumnChange,
|
||||
// onClick: this.onRoomsFilter,
|
||||
// },
|
||||
// ];
|
||||
|
||||
// defaultColumns.push(...columns);
|
||||
// } else {
|
||||
// const columns = [
|
||||
// {
|
||||
// key: "Name",
|
||||
// title: t("Common:Name"),
|
||||
// resizable: true,
|
||||
// enable: true,
|
||||
// default: true,
|
||||
// sortBy: "AZ",
|
||||
// minWidth: 210,
|
||||
// onClick: this.onFilter,
|
||||
// },
|
||||
// {
|
||||
// key: "Author",
|
||||
// title: t("ByAuthor"),
|
||||
// enable: false,
|
||||
// resizable: true,
|
||||
// sortBy: "Author",
|
||||
// onClick: this.onFilter,
|
||||
// onChange: this.onColumnChange,
|
||||
// },
|
||||
// {
|
||||
// key: "Created",
|
||||
// title: t("ByCreationDate"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "DateAndTimeCreation",
|
||||
// onClick: this.onFilter,
|
||||
// onChange: this.onColumnChange,
|
||||
// },
|
||||
// {
|
||||
// key: "Modified",
|
||||
// title: t("ByLastModifiedDate"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "DateAndTime",
|
||||
// onClick: this.onFilter,
|
||||
// onChange: this.onColumnChange,
|
||||
// },
|
||||
// {
|
||||
// key: "Size",
|
||||
// title: t("Common:Size"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "Size",
|
||||
// onClick: this.onFilter,
|
||||
// onChange: this.onColumnChange,
|
||||
// },
|
||||
// {
|
||||
// key: "Type",
|
||||
// title: t("Common:Type"),
|
||||
// enable: true,
|
||||
// resizable: true,
|
||||
// sortBy: "Type",
|
||||
// onClick: this.onFilter,
|
||||
// onChange: this.onColumnChange,
|
||||
// },
|
||||
// {
|
||||
// key: "QuickButtons",
|
||||
// title: "",
|
||||
// enable: true,
|
||||
// defaultSize: 75,
|
||||
// resizable: false,
|
||||
// },
|
||||
// ];
|
||||
|
||||
// personal && columns.splice(1, 1);
|
||||
|
||||
// defaultColumns.push(...columns);
|
||||
// }
|
||||
|
||||
// const storageColumns = localStorage.getItem(tableStorageName);
|
||||
// const splitColumns = storageColumns && storageColumns.split(",");
|
||||
// const columns = this.getColumns(defaultColumns, splitColumns);
|
||||
// const resetColumnsSize =
|
||||
// (splitColumns && splitColumns.length !== columns.length) ||
|
||||
// !splitColumns ||
|
||||
// isRooms;
|
||||
|
||||
// const tableColumns = columns.map((c) => c.enable && c.key);
|
||||
// this.setTableColumns(tableColumns);
|
||||
|
||||
this.getTableColumns();
|
||||
|
||||
this.isBeginScrolling = false;
|
||||
|
@ -9,7 +9,12 @@ import {
|
||||
import axios from "axios";
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import { showLoader, hideLoader } from "@docspace/common/utils";
|
||||
import {
|
||||
showLoader,
|
||||
hideLoader,
|
||||
frameCallbackData,
|
||||
frameCallCommand,
|
||||
} from "@docspace/common/utils";
|
||||
import FilesFilter from "@docspace/common/api/files/filter";
|
||||
import { getGroup } from "@docspace/common/api/groups";
|
||||
import { getUserById } from "@docspace/common/api/people";
|
||||
@ -242,6 +247,8 @@ class PureHome extends React.Component {
|
||||
setFirstLoad(false);
|
||||
setAlreadyFetchingRooms(false);
|
||||
});
|
||||
|
||||
window.addEventListener("message", this.handleMessage, false);
|
||||
}
|
||||
|
||||
fetchDefaultFiles = () => {
|
||||
@ -355,6 +362,115 @@ class PureHome extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("message", this.handleMessage, false);
|
||||
}
|
||||
|
||||
handleMessage = async (e) => {
|
||||
const {
|
||||
setFrameConfig,
|
||||
user,
|
||||
folders,
|
||||
files,
|
||||
selection,
|
||||
filesList,
|
||||
selectedFolderStore,
|
||||
createFile,
|
||||
createFolder,
|
||||
createRoom,
|
||||
refreshFiles,
|
||||
setViewAs,
|
||||
} = this.props;
|
||||
|
||||
const eventData = typeof e.data === "string" ? JSON.parse(e.data) : e.data;
|
||||
|
||||
if (eventData.data) {
|
||||
const { data, methodName } = eventData.data;
|
||||
|
||||
let res;
|
||||
|
||||
switch (methodName) {
|
||||
case "setConfig":
|
||||
res = await setFrameConfig(data);
|
||||
break;
|
||||
case "getFolderInfo":
|
||||
res = selectedFolderStore;
|
||||
break;
|
||||
case "getFolders":
|
||||
res = folders;
|
||||
break;
|
||||
case "getFiles":
|
||||
res = files;
|
||||
break;
|
||||
case "getList":
|
||||
res = filesList;
|
||||
break;
|
||||
case "getSelection":
|
||||
res = selection;
|
||||
break;
|
||||
case "getUserInfo":
|
||||
res = user;
|
||||
break;
|
||||
case "openModal": {
|
||||
const { type, options } = data;
|
||||
|
||||
if (type === "CreateFile" || type === "CreateFolder") {
|
||||
const item = new Event(Events.CREATE);
|
||||
|
||||
const payload = {
|
||||
extension: options,
|
||||
id: -1,
|
||||
};
|
||||
|
||||
item.payload = payload;
|
||||
|
||||
window.dispatchEvent(item);
|
||||
}
|
||||
|
||||
if (type === "CreateRoom") {
|
||||
const room = new Event(Events.ROOM_CREATE);
|
||||
|
||||
window.dispatchEvent(room);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "createFile":
|
||||
{
|
||||
const { folderId, title, templateId, formId } = data;
|
||||
res = await createFile(folderId, title, templateId, formId);
|
||||
|
||||
refreshFiles();
|
||||
}
|
||||
break;
|
||||
case "createFolder":
|
||||
{
|
||||
const { parentFolderId, title } = data;
|
||||
res = await createFolder(parentFolderId, title);
|
||||
|
||||
refreshFiles();
|
||||
}
|
||||
break;
|
||||
case "createRoom":
|
||||
{
|
||||
const { title, type } = data;
|
||||
res = await createRoom(title, type);
|
||||
|
||||
refreshFiles();
|
||||
}
|
||||
break;
|
||||
case "setListView":
|
||||
{
|
||||
setViewAs(data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = "Wrong method";
|
||||
}
|
||||
|
||||
frameCallbackData(res);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
//console.log("Home render");
|
||||
const {
|
||||
@ -382,8 +498,16 @@ class PureHome extends React.Component {
|
||||
checkedMaintenance,
|
||||
setMaintenanceExist,
|
||||
snackbarExist,
|
||||
isFrame,
|
||||
showTitle,
|
||||
showFilter,
|
||||
frameConfig,
|
||||
} = this.props;
|
||||
|
||||
if (window.parent && !frameConfig) {
|
||||
frameCallCommand("setConfig");
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MediaViewer />
|
||||
@ -414,7 +538,11 @@ class PureHome extends React.Component {
|
||||
firstLoad={firstLoad}
|
||||
>
|
||||
<Section.SectionHeader>
|
||||
{isFrame ? (
|
||||
showTitle && <SectionHeaderContent />
|
||||
) : (
|
||||
<SectionHeaderContent />
|
||||
)}
|
||||
</Section.SectionHeader>
|
||||
|
||||
<Section.SectionBar>
|
||||
@ -428,7 +556,11 @@ class PureHome extends React.Component {
|
||||
</Section.SectionBar>
|
||||
|
||||
<Section.SectionFilter>
|
||||
{isFrame ? (
|
||||
showFilter && <SectionFilterContent />
|
||||
) : (
|
||||
<SectionFilterContent />
|
||||
)}
|
||||
</Section.SectionFilter>
|
||||
|
||||
<Section.SectionBody>
|
||||
@ -492,6 +624,16 @@ export default inject(
|
||||
getFileInfo,
|
||||
gallerySelected,
|
||||
setIsUpdatingRowItem,
|
||||
|
||||
folders,
|
||||
files,
|
||||
filesList,
|
||||
selectedFolderStore,
|
||||
createFile,
|
||||
createFolder,
|
||||
createRoom,
|
||||
refreshFiles,
|
||||
setViewAs,
|
||||
} = filesStore;
|
||||
|
||||
const {
|
||||
@ -534,6 +676,19 @@ export default inject(
|
||||
: null;
|
||||
|
||||
const { setToPreviewFile, playlist } = mediaViewerDataStore;
|
||||
|
||||
const {
|
||||
checkedMaintenance,
|
||||
setMaintenanceExist,
|
||||
snackbarExist,
|
||||
isHeaderVisible,
|
||||
setHeaderVisible,
|
||||
personal,
|
||||
setFrameConfig,
|
||||
frameConfig,
|
||||
isFrame,
|
||||
} = auth.settingsStore;
|
||||
|
||||
if (!firstLoad) {
|
||||
if (isLoading) {
|
||||
showLoader();
|
||||
@ -552,9 +707,9 @@ export default inject(
|
||||
isRecycleBinFolder,
|
||||
isPrivacyFolder,
|
||||
isVisitor: auth.userStore.user.isVisitor,
|
||||
checkedMaintenance: auth.settingsStore.checkedMaintenance,
|
||||
setMaintenanceExist: auth.settingsStore.setMaintenanceExist,
|
||||
snackbarExist: auth.settingsStore.snackbarExist,
|
||||
checkedMaintenance,
|
||||
setMaintenanceExist,
|
||||
snackbarExist,
|
||||
expandedKeys,
|
||||
|
||||
primaryProgressDataVisible,
|
||||
@ -589,15 +744,32 @@ export default inject(
|
||||
setSelections,
|
||||
startUpload,
|
||||
uploadEmptyFolders,
|
||||
isHeaderVisible: auth.settingsStore.isHeaderVisible,
|
||||
setHeaderVisible: auth.settingsStore.setHeaderVisible,
|
||||
personal: auth.settingsStore.personal,
|
||||
isHeaderVisible,
|
||||
setHeaderVisible,
|
||||
personal,
|
||||
setToPreviewFile,
|
||||
playlist,
|
||||
isMediaOrImage: settingsStore.isMediaOrImage,
|
||||
getFileInfo,
|
||||
gallerySelected,
|
||||
setIsUpdatingRowItem,
|
||||
|
||||
setFrameConfig,
|
||||
frameConfig,
|
||||
isFrame,
|
||||
showTitle: frameConfig?.showTitle,
|
||||
showFilter: frameConfig?.showFilter,
|
||||
user: auth.userStore.user,
|
||||
folders,
|
||||
files,
|
||||
selection,
|
||||
filesList,
|
||||
selectedFolderStore,
|
||||
createFile,
|
||||
createFolder,
|
||||
createRoom,
|
||||
refreshFiles,
|
||||
setViewAs,
|
||||
};
|
||||
}
|
||||
)(withRouter(observer(Home)));
|
||||
|
@ -1,35 +1,85 @@
|
||||
import React, { lazy, Suspense } from "react";
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withRouter } from "react-router";
|
||||
import Loader from "@docspace/components/loader";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
import { combineUrl } from "@docspace/common/utils";
|
||||
import AppServerConfig from "@docspace/common/constants/AppServerConfig";
|
||||
import AppLoader from "@docspace/common/components/AppLoader";
|
||||
|
||||
const ThirdPartyServices = lazy(() => import("./thirdPartyServicesSettings"));
|
||||
import Submenu from "@docspace/components/submenu";
|
||||
|
||||
const PROXY_BASE_URL = combineUrl(
|
||||
import ThirdPartyServices from "./thirdPartyServicesSettings";
|
||||
import PortalIntegration from "./portalIntegration";
|
||||
|
||||
import config from "PACKAGE_FILE";
|
||||
|
||||
const Integration = (props) => {
|
||||
const { t, history } = props;
|
||||
const [currentTab, setCurrentTab] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const integrationData = {
|
||||
id: "portal-integration",
|
||||
name: "Portal Integration",
|
||||
content: <PortalIntegration />,
|
||||
};
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: "third-party-services",
|
||||
name: t("ThirdPartyAuthorization"),
|
||||
content: <ThirdPartyServices />,
|
||||
},
|
||||
];
|
||||
|
||||
if (!isMobile) data.push(integrationData);
|
||||
|
||||
const load = async () => {
|
||||
const { loadBaseInfo } = props;
|
||||
|
||||
await loadBaseInfo();
|
||||
|
||||
const path = location.pathname;
|
||||
const currentTab = data.findIndex((item) => path.includes(item.id));
|
||||
|
||||
if (currentTab !== -1) setCurrentTab(currentTab);
|
||||
|
||||
setIsLoading(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, []);
|
||||
|
||||
const onSelect = (e) => {
|
||||
history.push(
|
||||
combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
"/portal-settings/integration"
|
||||
);
|
||||
config.homepage,
|
||||
`/portal-settings/integration/${e.id}`
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
if (!isLoading) return <AppLoader />;
|
||||
|
||||
const Integration = ({ match }) => {
|
||||
return (
|
||||
<Suspense
|
||||
fallback={<Loader className="pageLoader" type="rombs" size="40px" />}
|
||||
>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path={[
|
||||
combineUrl(PROXY_BASE_URL, "/third-party-services"),
|
||||
combineUrl(AppServerConfig.proxyURL, "/integration"),
|
||||
match.path,
|
||||
]}
|
||||
component={ThirdPartyServices}
|
||||
<Submenu
|
||||
data={data}
|
||||
startSelect={currentTab}
|
||||
onSelect={(e) => onSelect(e)}
|
||||
/>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default withRouter(Integration);
|
||||
export default inject(({ setup }) => {
|
||||
const { initSettings } = setup;
|
||||
|
||||
return {
|
||||
loadBaseInfo: async () => {
|
||||
await initSettings();
|
||||
},
|
||||
};
|
||||
})(withTranslation("Settings")(withRouter(observer(Integration))));
|
||||
|
@ -0,0 +1,456 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import Box from "@docspace/components/box";
|
||||
import TextInput from "@docspace/components/text-input";
|
||||
import Textarea from "@docspace/components/textarea";
|
||||
import Label from "@docspace/components/label";
|
||||
import Checkbox from "@docspace/components/checkbox";
|
||||
import Button from "@docspace/components/button";
|
||||
import ComboBox from "@docspace/components/combobox";
|
||||
import Heading from "@docspace/components/heading";
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
import { tablet } from "@docspace/components/utils/device";
|
||||
import { objectToGetParams, loadScript } from "@docspace/common/utils";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
const Controls = styled(Box)`
|
||||
width: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
@media ${tablet} {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.label {
|
||||
min-width: fit-content;
|
||||
}
|
||||
`;
|
||||
|
||||
const ControlsGroup = styled(Box)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
`;
|
||||
|
||||
const Frame = styled(Box)`
|
||||
margin-top: 16px;
|
||||
|
||||
> div {
|
||||
border: 1px dashed gray;
|
||||
border-radius: 3px;
|
||||
min-width: 100%;
|
||||
min-height: 400px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Buttons = styled(Box)`
|
||||
margin-top: 16px;
|
||||
button {
|
||||
margin-right: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Container = styled(Box)`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
`;
|
||||
|
||||
const Preview = styled(Box)`
|
||||
width: 50%;
|
||||
flex-direction: row;
|
||||
|
||||
.frameStyle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const PortalIntegration = (props) => {
|
||||
const { t, setDocumentTitle } = props;
|
||||
|
||||
setDocumentTitle(`Portal integration`);
|
||||
|
||||
const scriptUrl = `${window.location.origin}/static/scripts/api.js`;
|
||||
|
||||
const dataSortBy = [
|
||||
{ key: "DateAndTime", label: "Last modified date", default: true },
|
||||
{ key: "AZ", label: "Title" },
|
||||
{ key: "Type", label: "Type" },
|
||||
{ key: "Size", label: "Size" },
|
||||
{ key: "DateAndTimeCreation", label: "Creation date" },
|
||||
{ key: "Author", label: "Author" },
|
||||
];
|
||||
|
||||
const dataFilterType = [
|
||||
{ key: 0, label: "None", default: true },
|
||||
{ key: 1, label: "Files" },
|
||||
{ key: 2, label: "Folders" },
|
||||
{ key: 3, label: "Documents" },
|
||||
{ key: 4, label: "Presentations" },
|
||||
{ key: 5, label: "Spreadsheets" },
|
||||
{ key: 7, label: "Images" },
|
||||
{ key: 8, label: "By user" },
|
||||
{ key: 9, label: "By department" },
|
||||
{ key: 10, label: "Archive" },
|
||||
{ key: 11, label: "By Extension" },
|
||||
{ key: 12, label: "Media" },
|
||||
];
|
||||
|
||||
const dataSortOrder = [
|
||||
{ key: "descending", label: "Descending", default: true },
|
||||
{ key: "ascending", label: "Ascending" },
|
||||
];
|
||||
|
||||
const dataDisplayType = [
|
||||
{ key: "row", label: "Row", default: true },
|
||||
{ key: "table", label: "Table" },
|
||||
{ key: "tile", label: "Tile" },
|
||||
];
|
||||
|
||||
const [config, setConfig] = useState({
|
||||
width: "100%",
|
||||
height: "400px",
|
||||
frameId: "ds-frame",
|
||||
showHeader: false,
|
||||
showTitle: true,
|
||||
showArticle: false,
|
||||
showFilter: false,
|
||||
});
|
||||
|
||||
const [sortBy, setSortBy] = useState(dataSortBy[0]);
|
||||
const [sortOrder, setSortOrder] = useState(dataSortOrder[0]);
|
||||
const [filterType, setFilterType] = useState(dataFilterType[0]);
|
||||
const [displayType, setDisplayType] = useState(dataDisplayType[0]);
|
||||
const [withSubfolders, setWithSubfolders] = useState(false);
|
||||
|
||||
const params = objectToGetParams(config);
|
||||
|
||||
const frameId = config.frameId || "ds-frame";
|
||||
|
||||
const destroyFrame = () => {
|
||||
DocSpace.destroyFrame();
|
||||
};
|
||||
|
||||
const loadFrame = () => {
|
||||
const script = document.getElementById("integration");
|
||||
|
||||
if (script) {
|
||||
destroyFrame();
|
||||
script.remove();
|
||||
}
|
||||
|
||||
const params = objectToGetParams(config);
|
||||
|
||||
loadScript(`${scriptUrl}${params}`, "integration");
|
||||
};
|
||||
|
||||
const onChangeWidth = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, width: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeHeight = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, height: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeFolderId = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, folder: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeFrameId = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, frameId: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeWithSubfolders = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, withSubfolders: !withSubfolders };
|
||||
});
|
||||
|
||||
setWithSubfolders(!withSubfolders);
|
||||
};
|
||||
|
||||
const onChangeSortBy = (item) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, sortby: item.key };
|
||||
});
|
||||
|
||||
setSortBy(item);
|
||||
};
|
||||
|
||||
const onChangeSortOrder = (item) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, sortorder: item.key };
|
||||
});
|
||||
|
||||
setSortOrder(item);
|
||||
};
|
||||
|
||||
const onChangeFilterType = (item) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, filterType: item.key };
|
||||
});
|
||||
|
||||
setFilterType(item);
|
||||
};
|
||||
|
||||
const onChangeDisplayType = (item) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, viewAs: item.key };
|
||||
});
|
||||
|
||||
setDisplayType(item);
|
||||
};
|
||||
|
||||
const onChangeShowHeader = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, showHeader: !config.showHeader };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeShowTitle = () => {
|
||||
setConfig((config) => {
|
||||
return { ...config, showTitle: !config.showTitle };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeShowArticle = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, showArticle: !config.showArticle };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeShowFilter = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, showFilter: !config.showFilter };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeCount = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, count: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangePage = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, page: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeSearch = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, search: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeAuthor = (e) => {
|
||||
setConfig((config) => {
|
||||
return { ...config, authorType: e.target.value };
|
||||
});
|
||||
};
|
||||
|
||||
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Controls>
|
||||
<Heading level={1} size="small">
|
||||
Frame options
|
||||
</Heading>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Frame id" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeFrameId}
|
||||
placeholder="Frame id"
|
||||
value={config.frameId}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Frame width" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeWidth}
|
||||
placeholder="Frame width"
|
||||
value={config.width}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Frame height" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeHeight}
|
||||
placeholder="Frame height"
|
||||
value={config.height}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
{/* <ControlsGroup>
|
||||
<Label className="label" text="Display mode: " />
|
||||
<ComboBox
|
||||
scale={true}
|
||||
onSelect={onChangeDisplayType}
|
||||
options={dataDisplayType}
|
||||
scaled={true}
|
||||
selectedOption={displayType}
|
||||
displaySelectedOption
|
||||
/>
|
||||
</ControlsGroup> */}
|
||||
<Checkbox
|
||||
label="Show header"
|
||||
onChange={onChangeShowHeader}
|
||||
isChecked={config.showHeader}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Show title"
|
||||
onChange={onChangeShowTitle}
|
||||
isChecked={config.showTitle}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Show article"
|
||||
onChange={onChangeShowArticle}
|
||||
isChecked={config.showArticle}
|
||||
/>
|
||||
<Checkbox
|
||||
label="Show filter"
|
||||
onChange={onChangeShowFilter}
|
||||
isChecked={config.showFilter}
|
||||
/>
|
||||
<Heading level={1} size="small">
|
||||
Filter options
|
||||
</Heading>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Folder id" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeFolderId}
|
||||
placeholder="Folder id"
|
||||
value={config.folder}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Items count" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeCount}
|
||||
placeholder="Items count"
|
||||
value={config.count}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Page" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangePage}
|
||||
placeholder="Page"
|
||||
value={config.page}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Search term" />
|
||||
<Box style={{ flexDirection: "row", display: "flex", gap: "16px" }}>
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeSearch}
|
||||
placeholder="Search term"
|
||||
value={config.search}
|
||||
/>
|
||||
<Checkbox
|
||||
label="With subfolders"
|
||||
onChange={onChangeWithSubfolders}
|
||||
isChecked={withSubfolders}
|
||||
/>
|
||||
</Box>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Author" />
|
||||
<TextInput
|
||||
scale={true}
|
||||
onChange={onChangeAuthor}
|
||||
placeholder="Author"
|
||||
value={config.authorType}
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Filter type:" />
|
||||
<ComboBox
|
||||
onSelect={onChangeFilterType}
|
||||
options={dataFilterType}
|
||||
scaled={true}
|
||||
selectedOption={filterType}
|
||||
displaySelectedOption
|
||||
directionY="top"
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Sort by:" />
|
||||
<ComboBox
|
||||
onSelect={onChangeSortBy}
|
||||
options={dataSortBy}
|
||||
scaled={true}
|
||||
selectedOption={sortBy}
|
||||
displaySelectedOption
|
||||
directionY="top"
|
||||
/>
|
||||
</ControlsGroup>
|
||||
<ControlsGroup>
|
||||
<Label className="label" text="Sort order:" />
|
||||
<ComboBox
|
||||
onSelect={onChangeSortOrder}
|
||||
options={dataSortOrder}
|
||||
scaled={true}
|
||||
selectedOption={sortOrder}
|
||||
displaySelectedOption
|
||||
directionY="top"
|
||||
/>
|
||||
</ControlsGroup>
|
||||
</Controls>
|
||||
<Preview>
|
||||
<Frame>
|
||||
<Box id={frameId} className="frameStyle">
|
||||
Frame content
|
||||
</Box>
|
||||
</Frame>
|
||||
|
||||
<Buttons>
|
||||
<Button primary size="normal" label="Preview" onClick={loadFrame} />
|
||||
<Button
|
||||
primary
|
||||
size="normal"
|
||||
label="Destroy"
|
||||
onClick={destroyFrame}
|
||||
/>
|
||||
</Buttons>
|
||||
|
||||
<Heading level={1} size="xsmall">
|
||||
Paste this code block on page:
|
||||
</Heading>
|
||||
|
||||
<Textarea value={codeBlock} />
|
||||
</Preview>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ setup, auth }) => {
|
||||
const { settingsStore, setDocumentTitle } = auth;
|
||||
const { theme } = settingsStore;
|
||||
|
||||
return {
|
||||
theme,
|
||||
setDocumentTitle,
|
||||
};
|
||||
})(withTranslation(["Settings", "Common"])(observer(PortalIntegration)));
|
@ -61,6 +61,8 @@ const WhiteLabel = lazy(() =>
|
||||
|
||||
const Branding = lazy(() => import("./categories/common/branding"));
|
||||
|
||||
const Integration = lazy(() => import("./categories/integration"));
|
||||
|
||||
const PROXY_BASE_URL = combineUrl(AppServerConfig.proxyURL, "/portal-settings");
|
||||
|
||||
const COMMON_URLS = [
|
||||
@ -120,10 +122,12 @@ const SESSION_LIFETIME_PAGE_URL = combineUrl(
|
||||
);
|
||||
|
||||
const ADMINS_URL = combineUrl(PROXY_BASE_URL, "/security/access-rights/admins");
|
||||
const THIRD_PARTY_URL = combineUrl(
|
||||
PROXY_BASE_URL,
|
||||
"/integration/third-party-services"
|
||||
);
|
||||
|
||||
const INTEGRATION_URLS = [
|
||||
combineUrl(PROXY_BASE_URL, "/integration/third-party-services"),
|
||||
combineUrl(PROXY_BASE_URL, "/integration/portal-integration"),
|
||||
];
|
||||
|
||||
const DATA_MANAGEMENT_URL = combineUrl(
|
||||
PROXY_BASE_URL,
|
||||
"/datamanagement/backup"
|
||||
@ -184,7 +188,7 @@ const Settings = (props) => {
|
||||
component={SessionLifetimePage}
|
||||
/>
|
||||
|
||||
<Route exact path={THIRD_PARTY_URL} component={ThirdPartyServices} />
|
||||
<Route exact path={INTEGRATION_URLS} component={Integration} />
|
||||
<Route
|
||||
exact
|
||||
path={DATA_MANAGEMENT_URL}
|
||||
|
@ -128,6 +128,13 @@ export const settingsTree = [
|
||||
tKey: "ThirdPartyAuthorization",
|
||||
isCategory: true,
|
||||
},
|
||||
{
|
||||
key: "3-1",
|
||||
icon: "",
|
||||
link: "portal-integration",
|
||||
tKey: "PortalIntegration",
|
||||
isCategory: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -168,7 +168,7 @@ class ConnectClouds extends React.Component {
|
||||
"data-provider-id": item.provider_id,
|
||||
"data-provider-key": item.provider_key,
|
||||
icon: "images/folder.react.svg",
|
||||
label: t("Home:Open"),
|
||||
label: t("Files:Open"),
|
||||
onClick: this.openLocation,
|
||||
disabled: !isMobile,
|
||||
},
|
||||
|
@ -1,16 +1,22 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import api from "../api";
|
||||
import { setWithCredentialsStatus } from "../api/client";
|
||||
import history from "../history";
|
||||
import api from "@docspace/common/api";
|
||||
import { setWithCredentialsStatus } from "@docspace/common/api/client";
|
||||
//import history from "../history";
|
||||
|
||||
import SettingsStore from "./SettingsStore";
|
||||
import SettingsStore from "./PortalSettingsStore";
|
||||
import UserStore from "./UserStore";
|
||||
import TfaStore from "./TfaStore";
|
||||
import InfoPanelStore from "./InfoPanelStore";
|
||||
import { logout as logoutDesktop, desktopConstants } from "../desktop";
|
||||
import { combineUrl, isAdmin } from "../utils";
|
||||
import { AppServerConfig, LANGUAGE, TenantStatus } from "../constants";
|
||||
const { proxyURL } = AppServerConfig;
|
||||
import {
|
||||
logout as logoutDesktop,
|
||||
desktopConstants,
|
||||
} from "@docspace/common/desktop";
|
||||
import { /*combineUrl,*/ isAdmin } from "@docspace/common/utils";
|
||||
import {
|
||||
/*AppServerConfig,*/ LANGUAGE,
|
||||
TenantStatus,
|
||||
} from "@docspace/common/constants";
|
||||
//const { proxyURL } = AppServerConfig;
|
||||
|
||||
class AuthStore {
|
||||
userStore = null;
|
||||
@ -104,7 +110,7 @@ class AuthStore {
|
||||
|
||||
if (response.tfa && response.confirmUrl) {
|
||||
const url = response.confirmUrl.replace(window.location.origin, "");
|
||||
return Promise.resolve({ url, user, hash });
|
||||
return url;
|
||||
}
|
||||
|
||||
setWithCredentialsStatus(true);
|
||||
@ -113,7 +119,7 @@ class AuthStore {
|
||||
|
||||
this.init();
|
||||
|
||||
return Promise.resolve({ url: this.settingsStore.defaultPage });
|
||||
return this.settingsStore.defaultPage;
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
@ -158,33 +164,16 @@ class AuthStore {
|
||||
this.settingsStore = new SettingsStore();
|
||||
};
|
||||
|
||||
logout = async (redirectToLogin = true, redirectPath = null) => {
|
||||
logout = async () => {
|
||||
await api.user.logout();
|
||||
|
||||
//console.log("Logout response ", response);
|
||||
|
||||
setWithCredentialsStatus(false);
|
||||
|
||||
const { isDesktopClient: isDesktop, personal } = this.settingsStore;
|
||||
const { isDesktopClient: isDesktop } = this.settingsStore;
|
||||
|
||||
isDesktop && logoutDesktop();
|
||||
|
||||
if (redirectToLogin) {
|
||||
if (redirectPath) {
|
||||
return window.location.replace(redirectPath);
|
||||
}
|
||||
if (personal) {
|
||||
return window.location.replace("/");
|
||||
} else {
|
||||
this.reset(true);
|
||||
this.userStore.setUser(null);
|
||||
this.init();
|
||||
return history.push(combineUrl(proxyURL, "/login"));
|
||||
}
|
||||
} else {
|
||||
this.reset();
|
||||
this.init();
|
||||
}
|
||||
};
|
||||
|
||||
get isAuthenticated() {
|
@ -1,5 +1,5 @@
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import authStore from "SRC_DIR/store/AuthStore";
|
||||
import api from "@docspace/common/api";
|
||||
|
||||
class CommonStore {
|
||||
|
@ -931,8 +931,8 @@ class ContextOptionsStore {
|
||||
deleteOperation: t("Translations:DeleteOperation"),
|
||||
deleteFromTrash: t("Translations:DeleteFromTrash"),
|
||||
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||
FileRemoved: t("Home:FileRemoved"),
|
||||
FolderRemoved: t("Home:FolderRemoved"),
|
||||
FileRemoved: t("Files:FileRemoved"),
|
||||
FolderRemoved: t("Files:FolderRemoved"),
|
||||
};
|
||||
|
||||
this.filesActionsStore
|
||||
|
@ -1344,8 +1344,8 @@ class FilesActionStore {
|
||||
deleteOperation: t("Translations:DeleteOperation"),
|
||||
deleteFromTrash: t("Translations:DeleteFromTrash"),
|
||||
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||
FileRemoved: t("Home:FileRemoved"),
|
||||
FolderRemoved: t("Home:FolderRemoved"),
|
||||
FileRemoved: t("Files:FileRemoved"),
|
||||
FolderRemoved: t("Files:FolderRemoved"),
|
||||
};
|
||||
|
||||
this.deleteAction(translations).catch((err) =>
|
||||
|
@ -344,6 +344,13 @@ class FilesStore {
|
||||
};
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
this.isLoaded = false;
|
||||
this.isLoading = false;
|
||||
this.firstLoad = false;
|
||||
this.isInit = false;
|
||||
};
|
||||
|
||||
initFiles = () => {
|
||||
if (this.isInit) return;
|
||||
|
||||
|
@ -3,14 +3,14 @@ import {
|
||||
getInvitationLinks,
|
||||
getShortenedLink,
|
||||
} from "@docspace/common/api/portal";
|
||||
import store from "client/store";
|
||||
|
||||
const { auth: authStore } = store;
|
||||
class InviteLinksStore {
|
||||
userLink = null;
|
||||
guestLink = null;
|
||||
authStore = null;
|
||||
|
||||
constructor() {
|
||||
constructor(authStore) {
|
||||
this.authStore = authStore;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ class InviteLinksStore {
|
||||
};
|
||||
|
||||
getPortalInviteLinks = async () => {
|
||||
const isViewerAdmin = authStore.isAdmin;
|
||||
const isViewerAdmin = this.authStore.isAdmin;
|
||||
|
||||
if (!isViewerAdmin) return Promise.resolve();
|
||||
|
||||
|
@ -30,6 +30,14 @@ class LoadingStore {
|
||||
setLoadedProfile = (profileLoaded) => {
|
||||
this.profileLoaded = profileLoaded;
|
||||
};
|
||||
|
||||
reset = () => {
|
||||
this.isLoading = false;
|
||||
this.isLoaded = false;
|
||||
this.isRefresh = false;
|
||||
this.firstLoad = true;
|
||||
this.profileLoaded = true;
|
||||
};
|
||||
}
|
||||
|
||||
export default LoadingStore;
|
||||
|
@ -9,13 +9,12 @@ import SelectionStore from "./SelectionPeopleStore";
|
||||
import HeaderMenuStore from "./HeaderMenuStore";
|
||||
import AvatarEditorStore from "./AvatarEditorStore";
|
||||
import InviteLinksStore from "./InviteLinksStore";
|
||||
import store from "client/store";
|
||||
import DialogStore from "./DialogStore";
|
||||
import LoadingStore from "./LoadingStore";
|
||||
import { isMobile } from "react-device-detect";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
class PeopleStore {
|
||||
authStore = null;
|
||||
groupsStore = null;
|
||||
usersStore = null;
|
||||
targetUserStore = null;
|
||||
@ -31,7 +30,8 @@ class PeopleStore {
|
||||
isInit = false;
|
||||
viewAs = isMobile ? "row" : "table";
|
||||
|
||||
constructor() {
|
||||
constructor(authStore) {
|
||||
this.authStore = authStore;
|
||||
this.groupsStore = new GroupsStore(this);
|
||||
this.usersStore = new UsersStore(this);
|
||||
this.targetUserStore = new TargetUserStore(this);
|
||||
@ -41,7 +41,7 @@ class PeopleStore {
|
||||
this.selectionStore = new SelectionStore(this);
|
||||
this.headerMenuStore = new HeaderMenuStore(this);
|
||||
this.avatarEditorStore = new AvatarEditorStore(this);
|
||||
this.inviteLinksStore = new InviteLinksStore(this);
|
||||
this.inviteLinksStore = new InviteLinksStore(authStore);
|
||||
this.dialogStore = new DialogStore();
|
||||
this.loadingStore = new LoadingStore();
|
||||
|
||||
@ -49,16 +49,21 @@ class PeopleStore {
|
||||
}
|
||||
|
||||
get isPeoplesAdmin() {
|
||||
return authStore.isAdmin;
|
||||
return this.authStore.isAdmin;
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
this.loadingStore.reset();
|
||||
this.isInit = false;
|
||||
};
|
||||
|
||||
init = async () => {
|
||||
if (this.isInit) return;
|
||||
this.isInit = true;
|
||||
|
||||
//authStore.settingsStore.setModuleInfo(config.homepage, config.id);
|
||||
//this.authStore.settingsStore.setModuleInfo(config.homepage, config.id);
|
||||
|
||||
await authStore.settingsStore.getPortalPasswordSettings();
|
||||
await this.authStore.settingsStore.getPortalPasswordSettings();
|
||||
|
||||
this.loadingStore.setIsLoaded(true);
|
||||
};
|
||||
@ -79,7 +84,10 @@ class PeopleStore {
|
||||
};
|
||||
|
||||
getHeaderMenu = (t) => {
|
||||
const { userCaption, guestCaption } = authStore.settingsStore.customNames;
|
||||
const {
|
||||
userCaption,
|
||||
guestCaption,
|
||||
} = this.authStore.settingsStore.customNames;
|
||||
const {
|
||||
hasUsersToMakeEmployees,
|
||||
hasUsersToMakeGuests,
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import api from "../api";
|
||||
import { LANGUAGE, TenantStatus } from "../constants";
|
||||
import { combineUrl } from "../utils";
|
||||
import FirebaseHelper from "../utils/firebase";
|
||||
import { AppServerConfig, ThemeKeys } from "../constants";
|
||||
import { version } from "../package.json";
|
||||
import SocketIOHelper from "../utils/socket";
|
||||
import api from "@docspace/common/api";
|
||||
import { LANGUAGE, TenantStatus } from "@docspace/common/constants";
|
||||
import { combineUrl } from "@docspace/common/utils";
|
||||
import FirebaseHelper from "@docspace/common/utils/firebase";
|
||||
import { AppServerConfig, ThemeKeys } from "@docspace/common/constants";
|
||||
import { version } from "PACKAGE_FILE";
|
||||
import SocketIOHelper from "@docspace/common/utils/socket";
|
||||
|
||||
import { Dark, Base } from "@docspace/components/themes";
|
||||
|
||||
@ -127,6 +127,7 @@ class SettingsStore {
|
||||
tenantStatus = null;
|
||||
helpLink = null;
|
||||
hotkeyPanelVisible = false;
|
||||
frameConfig = null;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
@ -538,6 +539,15 @@ class SettingsStore {
|
||||
setHotkeyPanelVisible = (hotkeyPanelVisible) => {
|
||||
this.hotkeyPanelVisible = hotkeyPanelVisible;
|
||||
};
|
||||
|
||||
setFrameConfig = (frameConfig) => {
|
||||
this.frameConfig = frameConfig;
|
||||
return frameConfig;
|
||||
};
|
||||
|
||||
get isFrame() {
|
||||
return this.frameConfig?.name === window.name;
|
||||
}
|
||||
}
|
||||
|
||||
export default SettingsStore;
|
@ -2,14 +2,13 @@ import { makeAutoObservable } from "mobx";
|
||||
import { combineUrl } from "@docspace/common/utils";
|
||||
import { AppServerConfig } from "@docspace/common/constants";
|
||||
import history from "@docspace/common/history";
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import { isDesktop, isTablet, isMobile } from "react-device-detect";
|
||||
|
||||
const { proxyURL } = AppServerConfig;
|
||||
|
||||
const PROXY_HOMEPAGE_URL = combineUrl(proxyURL, "/");
|
||||
const PROFILE_SELF_URL = combineUrl(PROXY_HOMEPAGE_URL, "/accounts/view/@self");
|
||||
const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/my");
|
||||
//const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/my");
|
||||
const ABOUT_URL = combineUrl(PROXY_HOMEPAGE_URL, "/about");
|
||||
const PAYMENTS_URL = combineUrl(PROXY_HOMEPAGE_URL, "/payments");
|
||||
const HELP_URL = "https://onlyoffice.com/";
|
||||
@ -18,11 +17,16 @@ const VIDEO_GUIDES_URL = "https://onlyoffice.com/";
|
||||
|
||||
class ProfileActionsStore {
|
||||
authStore = null;
|
||||
filesStore = null;
|
||||
peopleStore = null;
|
||||
isAboutDialogVisible = false;
|
||||
isDebugDialogVisible = false;
|
||||
|
||||
constructor() {
|
||||
constructor(authStore, filesStore, peopleStore) {
|
||||
this.authStore = authStore;
|
||||
this.filesStore = filesStore;
|
||||
this.peopleStore = peopleStore;
|
||||
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
@ -80,8 +84,18 @@ class ProfileActionsStore {
|
||||
}
|
||||
};
|
||||
|
||||
onLogoutClick = () => {
|
||||
this.authStore.logout && this.authStore.logout();
|
||||
onLogoutClick = async () => {
|
||||
await this.authStore.logout();
|
||||
|
||||
this.authStore.reset();
|
||||
|
||||
this.filesStore.reset();
|
||||
|
||||
this.peopleStore.reset();
|
||||
|
||||
this.authStore.init();
|
||||
|
||||
history.push("/login");
|
||||
};
|
||||
|
||||
onDebugClick = () => {
|
||||
|
@ -4,8 +4,6 @@ import {
|
||||
EmployeeActivationStatus,
|
||||
} from "@docspace/common/constants";
|
||||
import { getUserStatus } from "../helpers/people-helpers";
|
||||
import store from "client/store";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
class SelectionStore {
|
||||
selection = [];
|
||||
@ -115,7 +113,7 @@ class SelectionStore {
|
||||
!x.isOwner &&
|
||||
x.isVisitor &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
});
|
||||
return !!users.length;
|
||||
@ -128,7 +126,7 @@ class SelectionStore {
|
||||
!x.isOwner &&
|
||||
x.isVisitor &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
});
|
||||
return users.map((u) => u.id);
|
||||
@ -141,7 +139,7 @@ class SelectionStore {
|
||||
!x.isOwner &&
|
||||
!x.isVisitor &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
});
|
||||
return !!users.length;
|
||||
@ -154,7 +152,7 @@ class SelectionStore {
|
||||
!x.isOwner &&
|
||||
!x.isVisitor &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
});
|
||||
return users.map((u) => u.id);
|
||||
@ -165,7 +163,7 @@ class SelectionStore {
|
||||
(x) =>
|
||||
!x.isOwner &&
|
||||
x.status !== EmployeeStatus.Active &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
return !!users.length;
|
||||
}
|
||||
@ -175,7 +173,7 @@ class SelectionStore {
|
||||
(x) =>
|
||||
!x.isOwner &&
|
||||
x.status !== EmployeeStatus.Active &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
return users.map((u) => u.id);
|
||||
}
|
||||
@ -185,7 +183,7 @@ class SelectionStore {
|
||||
(x) =>
|
||||
!x.isOwner &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
return !!users.length;
|
||||
}
|
||||
@ -195,7 +193,7 @@ class SelectionStore {
|
||||
(x) =>
|
||||
!x.isOwner &&
|
||||
x.status !== EmployeeStatus.Disabled &&
|
||||
x.id !== authStore.userStore.user.id
|
||||
x.id !== this.peopleStore.authStore.userStore.user.id
|
||||
);
|
||||
return users.map((u) => u.id);
|
||||
}
|
||||
|
@ -2,8 +2,6 @@ import api from "@docspace/common/api";
|
||||
import { makeAutoObservable } from "mobx";
|
||||
const { Filter } = api;
|
||||
import SelectionStore from "./SelectionStore";
|
||||
//import CommonStore from "./CommonStore";
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import { combineUrl } from "@docspace/common/utils";
|
||||
import { AppServerConfig } from "@docspace/common/constants";
|
||||
import config from "PACKAGE_FILE";
|
||||
@ -40,7 +38,7 @@ class SettingsSetupStore {
|
||||
commonThirdPartyList: [],
|
||||
};
|
||||
|
||||
constructor() {
|
||||
constructor(authStore) {
|
||||
this.selectionStore = new SelectionStore(this);
|
||||
this.authStore = authStore;
|
||||
makeAutoObservable(this);
|
||||
@ -50,12 +48,12 @@ class SettingsSetupStore {
|
||||
if (this.isInit) return;
|
||||
this.isInit = true;
|
||||
|
||||
if (authStore.isAuthenticated) {
|
||||
await authStore.settingsStore.getPortalPasswordSettings();
|
||||
await authStore.tfaStore.getTfaType();
|
||||
await authStore.settingsStore.getIpRestrictionsEnable();
|
||||
await authStore.settingsStore.getIpRestrictions();
|
||||
await authStore.settingsStore.getSessionLifetime();
|
||||
if (this.authStore.isAuthenticated) {
|
||||
await this.authStore.settingsStore.getPortalPasswordSettings();
|
||||
await this.authStore.tfaStore.getTfaType();
|
||||
await this.authStore.settingsStore.getIpRestrictionsEnable();
|
||||
await this.authStore.settingsStore.getIpRestrictions();
|
||||
await this.authStore.settingsStore.getSessionLifetime();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
import api from "@docspace/common/api";
|
||||
import { LANGUAGE } from "@docspace/common/constants";
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import store from "client/store";
|
||||
|
||||
const { auth: authStore } = store;
|
||||
|
||||
class TargetUserStore {
|
||||
targetUser = null;
|
||||
@ -17,8 +14,8 @@ class TargetUserStore {
|
||||
|
||||
get getDisableProfileType() {
|
||||
const res =
|
||||
authStore.userStore.user.id === this.targetUser.id ||
|
||||
!authStore.isAdmin ||
|
||||
this.peopleStore.authStore.userStore.user.id === this.targetUser.id ||
|
||||
!this.peopleStore.authStore.isAdmin ||
|
||||
this.peopleStore.isPeoplesAdmin
|
||||
? false
|
||||
: true;
|
||||
@ -29,22 +26,19 @@ class TargetUserStore {
|
||||
get isMe() {
|
||||
return (
|
||||
this.targetUser &&
|
||||
this.targetUser.userName === authStore.userStore.user.userName
|
||||
this.targetUser.userName ===
|
||||
this.peopleStore.authStore.userStore.user.userName
|
||||
);
|
||||
}
|
||||
|
||||
getTargetUser = async (userName) => {
|
||||
/*if (authStore.userStore.user.userName === userName) {
|
||||
return this.setTargetUser(authStore.userStore.user);
|
||||
} else {*/
|
||||
const user = await api.people.getUser(userName);
|
||||
if (user?.userName === authStore.userStore.user.userName) {
|
||||
if (user?.userName === this.peopleStore.authStore.userStore.user.userName) {
|
||||
const tipsSubscription = await api.settings.getTipsSubscription();
|
||||
this.tipsSubscription = tipsSubscription;
|
||||
}
|
||||
this.setTargetUser(user);
|
||||
return user;
|
||||
//}
|
||||
};
|
||||
|
||||
setTargetUser = (user) => {
|
||||
@ -63,7 +57,7 @@ class TargetUserStore {
|
||||
);
|
||||
|
||||
const res = await api.people.updateUser(member);
|
||||
if (!res.theme) res.theme = authStore.userStore.user.theme;
|
||||
if (!res.theme) res.theme = this.peopleStore.authStore.userStore.user.theme;
|
||||
|
||||
this.setTargetUser(res);
|
||||
return Promise.resolve(res);
|
||||
@ -80,11 +74,10 @@ class TargetUserStore {
|
||||
updateProfileCulture = async (id, culture) => {
|
||||
const res = await api.people.updateUserCulture(id, culture);
|
||||
|
||||
authStore.userStore.setUser(res);
|
||||
this.peopleStore.authStore.userStore.setUser(res);
|
||||
|
||||
this.setTargetUser(res);
|
||||
//caches.delete("api-cache");
|
||||
//await authStore.settingsStore.init();
|
||||
|
||||
localStorage.setItem(LANGUAGE, culture);
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import api from "../api";
|
||||
import history from "../history";
|
||||
import api from "@docspace/common/api";
|
||||
//import history from "../history";
|
||||
|
||||
class TfaStore {
|
||||
tfaSettings = null;
|
@ -1,5 +1,5 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import api from "../api";
|
||||
import api from "@docspace/common/api";
|
||||
|
||||
class UserStore {
|
||||
user = null;
|
@ -6,8 +6,7 @@ import {
|
||||
} from "@docspace/common/constants";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
const { Filter } = api;
|
||||
import store from "client/store";
|
||||
const { auth: authStore } = store;
|
||||
|
||||
class UsersStore {
|
||||
users = [];
|
||||
providers = [];
|
||||
@ -237,9 +236,9 @@ class UsersStore {
|
||||
const statusType = this.getStatusType(user);
|
||||
const role = this.getUserRole(user);
|
||||
const isMySelf =
|
||||
authStore.userStore.user &&
|
||||
user.userName === authStore.userStore.user.userName;
|
||||
const isViewerAdmin = authStore.isAdmin;
|
||||
this.peopleStore.authStore.userStore.user &&
|
||||
user.userName === this.peopleStore.authStore.userStore.user.userName;
|
||||
const isViewerAdmin = this.peopleStore.authStore.isAdmin;
|
||||
|
||||
const options = this.getUserContextOptions(
|
||||
isMySelf,
|
||||
|
@ -1,113 +0,0 @@
|
||||
import FilesStore from "./FilesStore";
|
||||
import SelectedFolderStore from "./SelectedFolderStore";
|
||||
import TreeFoldersStore from "./TreeFoldersStore";
|
||||
import thirdPartyStore from "./ThirdPartyStore";
|
||||
import SettingsStore from "./SettingsStore";
|
||||
import FilesActionsStore from "./FilesActionsStore";
|
||||
import MediaViewerDataStore from "./MediaViewerDataStore";
|
||||
import UploadDataStore from "./UploadDataStore";
|
||||
import SecondaryProgressDataStore from "./SecondaryProgressDataStore";
|
||||
import PrimaryProgressDataStore from "./PrimaryProgressDataStore";
|
||||
|
||||
import VersionHistoryStore from "./VersionHistoryStore";
|
||||
import DialogsStore from "./DialogsStore";
|
||||
import selectFolderDialogStore from "./SelectFolderDialogStore";
|
||||
import ContextOptionsStore from "./ContextOptionsStore";
|
||||
import HotkeyStore from "./HotkeyStore";
|
||||
import store from "client/store";
|
||||
import selectFileDialogStore from "./SelectFileDialogStore";
|
||||
import TagsStore from "./TagsStore";
|
||||
|
||||
const tagsStore = new TagsStore();
|
||||
|
||||
const selectedFolderStore = new SelectedFolderStore(store.auth.settingsStore);
|
||||
|
||||
const treeFoldersStore = new TreeFoldersStore(selectedFolderStore);
|
||||
const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore);
|
||||
const filesStore = new FilesStore(
|
||||
store.auth,
|
||||
store.auth.settingsStore,
|
||||
store.auth.userStore,
|
||||
selectedFolderStore,
|
||||
treeFoldersStore,
|
||||
settingsStore,
|
||||
selectFolderDialogStore,
|
||||
selectFileDialogStore
|
||||
);
|
||||
|
||||
const mediaViewerDataStore = new MediaViewerDataStore(
|
||||
filesStore,
|
||||
settingsStore
|
||||
);
|
||||
const secondaryProgressDataStore = new SecondaryProgressDataStore();
|
||||
const primaryProgressDataStore = new PrimaryProgressDataStore();
|
||||
const versionHistoryStore = new VersionHistoryStore(filesStore);
|
||||
const dialogsStore = new DialogsStore(
|
||||
store.auth,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
versionHistoryStore
|
||||
);
|
||||
const uploadDataStore = new UploadDataStore(
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesStore,
|
||||
secondaryProgressDataStore,
|
||||
primaryProgressDataStore,
|
||||
dialogsStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const filesActionsStore = new FilesActionsStore(
|
||||
store.auth,
|
||||
uploadDataStore,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
settingsStore,
|
||||
dialogsStore,
|
||||
mediaViewerDataStore
|
||||
);
|
||||
|
||||
const contextOptionsStore = new ContextOptionsStore(
|
||||
store.auth,
|
||||
dialogsStore,
|
||||
filesActionsStore,
|
||||
filesStore,
|
||||
mediaViewerDataStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore,
|
||||
versionHistoryStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const hotkeyStore = new HotkeyStore(
|
||||
filesStore,
|
||||
dialogsStore,
|
||||
settingsStore,
|
||||
filesActionsStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore
|
||||
);
|
||||
|
||||
const stores = {
|
||||
filesStore,
|
||||
|
||||
settingsStore,
|
||||
mediaViewerDataStore,
|
||||
versionHistoryStore,
|
||||
uploadDataStore,
|
||||
dialogsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesActionsStore,
|
||||
selectFolderDialogStore,
|
||||
contextOptionsStore,
|
||||
hotkeyStore,
|
||||
selectFileDialogStore,
|
||||
|
||||
tagsStore,
|
||||
};
|
||||
|
||||
export default stores;
|
@ -1,118 +0,0 @@
|
||||
import FilesStore from "./FilesStore";
|
||||
import SelectedFolderStore from "./SelectedFolderStore";
|
||||
import TreeFoldersStore from "./TreeFoldersStore";
|
||||
import thirdPartyStore from "./ThirdPartyStore";
|
||||
import SettingsStore from "./SettingsStore";
|
||||
import FilesActionsStore from "./FilesActionsStore";
|
||||
import MediaViewerDataStore from "./MediaViewerDataStore";
|
||||
import UploadDataStore from "./UploadDataStore";
|
||||
import SecondaryProgressDataStore from "./SecondaryProgressDataStore";
|
||||
import PrimaryProgressDataStore from "./PrimaryProgressDataStore";
|
||||
|
||||
import VersionHistoryStore from "./VersionHistoryStore";
|
||||
import DialogsStore from "./DialogsStore";
|
||||
import selectFolderDialogStore from "./SelectFolderDialogStore";
|
||||
import ContextOptionsStore from "./ContextOptionsStore";
|
||||
import HotkeyStore from "./HotkeyStore";
|
||||
import store from "client/store";
|
||||
import selectFileDialogStore from "./SelectFileDialogStore";
|
||||
import TagsStore from "./TagsStore";
|
||||
import PeopleStore from "./PeopleStore";
|
||||
|
||||
const peopleStore = new PeopleStore();
|
||||
|
||||
const tagsStore = new TagsStore();
|
||||
|
||||
const selectedFolderStore = new SelectedFolderStore(store.auth.settingsStore);
|
||||
|
||||
const treeFoldersStore = new TreeFoldersStore(selectedFolderStore);
|
||||
const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore);
|
||||
const filesStore = new FilesStore(
|
||||
store.auth,
|
||||
store.auth.settingsStore,
|
||||
store.auth.userStore,
|
||||
selectedFolderStore,
|
||||
treeFoldersStore,
|
||||
settingsStore,
|
||||
selectFolderDialogStore,
|
||||
selectFileDialogStore
|
||||
);
|
||||
|
||||
const mediaViewerDataStore = new MediaViewerDataStore(
|
||||
filesStore,
|
||||
settingsStore
|
||||
);
|
||||
const secondaryProgressDataStore = new SecondaryProgressDataStore();
|
||||
const primaryProgressDataStore = new PrimaryProgressDataStore();
|
||||
const versionHistoryStore = new VersionHistoryStore(filesStore);
|
||||
const dialogsStore = new DialogsStore(
|
||||
store.auth,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
versionHistoryStore
|
||||
);
|
||||
const uploadDataStore = new UploadDataStore(
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesStore,
|
||||
secondaryProgressDataStore,
|
||||
primaryProgressDataStore,
|
||||
dialogsStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const filesActionsStore = new FilesActionsStore(
|
||||
store.auth,
|
||||
uploadDataStore,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
settingsStore,
|
||||
dialogsStore,
|
||||
mediaViewerDataStore
|
||||
);
|
||||
|
||||
const contextOptionsStore = new ContextOptionsStore(
|
||||
store.auth,
|
||||
dialogsStore,
|
||||
filesActionsStore,
|
||||
filesStore,
|
||||
mediaViewerDataStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore,
|
||||
versionHistoryStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const hotkeyStore = new HotkeyStore(
|
||||
filesStore,
|
||||
dialogsStore,
|
||||
settingsStore,
|
||||
filesActionsStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore
|
||||
);
|
||||
|
||||
const stores = {
|
||||
filesStore,
|
||||
|
||||
settingsStore,
|
||||
mediaViewerDataStore,
|
||||
versionHistoryStore,
|
||||
uploadDataStore,
|
||||
dialogsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesActionsStore,
|
||||
selectFolderDialogStore,
|
||||
contextOptionsStore,
|
||||
hotkeyStore,
|
||||
selectFileDialogStore,
|
||||
|
||||
tagsStore,
|
||||
|
||||
peopleStore,
|
||||
};
|
||||
|
||||
export default stores;
|
@ -1,4 +1,4 @@
|
||||
import authStore from "@docspace/common/store/AuthStore";
|
||||
import authStore from "./AuthStore";
|
||||
import PaymentStore from "./PaymentStore";
|
||||
import WizardStore from "./WizardStore";
|
||||
import SettingsSetupStore from "./SettingsSetupStore";
|
||||
@ -7,15 +7,114 @@ import BackupStore from "./BackupStore";
|
||||
import CommonStore from "./CommonStore";
|
||||
import BannerStore from "./BannerStore";
|
||||
import ProfileActionsStore from "./ProfileActionsStore";
|
||||
import FilesStore from "./FilesStore";
|
||||
import SelectedFolderStore from "./SelectedFolderStore";
|
||||
import TreeFoldersStore from "./TreeFoldersStore";
|
||||
import thirdPartyStore from "./ThirdPartyStore";
|
||||
import SettingsStore from "./SettingsStore";
|
||||
import FilesActionsStore from "./FilesActionsStore";
|
||||
import MediaViewerDataStore from "./MediaViewerDataStore";
|
||||
import UploadDataStore from "./UploadDataStore";
|
||||
import SecondaryProgressDataStore from "./SecondaryProgressDataStore";
|
||||
import PrimaryProgressDataStore from "./PrimaryProgressDataStore";
|
||||
|
||||
import VersionHistoryStore from "./VersionHistoryStore";
|
||||
import DialogsStore from "./DialogsStore";
|
||||
import selectFolderDialogStore from "./SelectFolderDialogStore";
|
||||
import ContextOptionsStore from "./ContextOptionsStore";
|
||||
import HotkeyStore from "./HotkeyStore";
|
||||
import selectFileDialogStore from "./SelectFileDialogStore";
|
||||
import TagsStore from "./TagsStore";
|
||||
import PeopleStore from "./PeopleStore";
|
||||
|
||||
const paymentStore = new PaymentStore();
|
||||
const wizardStore = new WizardStore();
|
||||
const setupStore = new SettingsSetupStore();
|
||||
const setupStore = new SettingsSetupStore(authStore);
|
||||
const confirmStore = new ConfirmStore();
|
||||
const backupStore = new BackupStore();
|
||||
const commonStore = new CommonStore();
|
||||
const bannerStore = new BannerStore();
|
||||
const profileActionsStore = new ProfileActionsStore();
|
||||
|
||||
const peopleStore = new PeopleStore(authStore);
|
||||
|
||||
const tagsStore = new TagsStore();
|
||||
|
||||
const selectedFolderStore = new SelectedFolderStore(authStore.settingsStore);
|
||||
|
||||
const treeFoldersStore = new TreeFoldersStore(selectedFolderStore);
|
||||
const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore);
|
||||
const filesStore = new FilesStore(
|
||||
authStore,
|
||||
authStore.settingsStore,
|
||||
authStore.userStore,
|
||||
selectedFolderStore,
|
||||
treeFoldersStore,
|
||||
settingsStore,
|
||||
selectFolderDialogStore,
|
||||
selectFileDialogStore
|
||||
);
|
||||
|
||||
const mediaViewerDataStore = new MediaViewerDataStore(
|
||||
filesStore,
|
||||
settingsStore
|
||||
);
|
||||
const secondaryProgressDataStore = new SecondaryProgressDataStore();
|
||||
const primaryProgressDataStore = new PrimaryProgressDataStore();
|
||||
const versionHistoryStore = new VersionHistoryStore(filesStore);
|
||||
const dialogsStore = new DialogsStore(
|
||||
authStore,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
versionHistoryStore
|
||||
);
|
||||
const uploadDataStore = new UploadDataStore(
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesStore,
|
||||
secondaryProgressDataStore,
|
||||
primaryProgressDataStore,
|
||||
dialogsStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const filesActionsStore = new FilesActionsStore(
|
||||
authStore,
|
||||
uploadDataStore,
|
||||
treeFoldersStore,
|
||||
filesStore,
|
||||
selectedFolderStore,
|
||||
settingsStore,
|
||||
dialogsStore,
|
||||
mediaViewerDataStore
|
||||
);
|
||||
|
||||
const contextOptionsStore = new ContextOptionsStore(
|
||||
authStore,
|
||||
dialogsStore,
|
||||
filesActionsStore,
|
||||
filesStore,
|
||||
mediaViewerDataStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore,
|
||||
versionHistoryStore,
|
||||
settingsStore
|
||||
);
|
||||
|
||||
const hotkeyStore = new HotkeyStore(
|
||||
filesStore,
|
||||
dialogsStore,
|
||||
settingsStore,
|
||||
filesActionsStore,
|
||||
treeFoldersStore,
|
||||
uploadDataStore
|
||||
);
|
||||
|
||||
const profileActionsStore = new ProfileActionsStore(
|
||||
authStore,
|
||||
filesStore,
|
||||
peopleStore
|
||||
);
|
||||
|
||||
const store = {
|
||||
auth: authStore,
|
||||
@ -27,6 +126,25 @@ const store = {
|
||||
common: commonStore,
|
||||
bannerStore: bannerStore,
|
||||
profileActionsStore: profileActionsStore,
|
||||
|
||||
filesStore,
|
||||
|
||||
settingsStore,
|
||||
mediaViewerDataStore,
|
||||
versionHistoryStore,
|
||||
uploadDataStore,
|
||||
dialogsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
filesActionsStore,
|
||||
selectFolderDialogStore,
|
||||
contextOptionsStore,
|
||||
hotkeyStore,
|
||||
selectFileDialogStore,
|
||||
|
||||
tagsStore,
|
||||
|
||||
peopleStore,
|
||||
};
|
||||
|
||||
export default store;
|
||||
|
@ -1,2 +0,0 @@
|
||||
import authStore from "./AuthStore";
|
||||
export default { authStore };
|
@ -151,7 +151,6 @@ export function isMe(user, userName) {
|
||||
}
|
||||
|
||||
export function isAdmin(currentUser, currentProductId) {
|
||||
|
||||
return (
|
||||
currentUser.isAdmin ||
|
||||
currentUser.isOwner ||
|
||||
@ -378,3 +377,23 @@ export function assign(obj, keyPath, value) {
|
||||
}
|
||||
obj[keyPath[lastKeyIndex]] = value;
|
||||
}
|
||||
|
||||
export const frameCallbackData = (data) => {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify({
|
||||
type: "onMethodReturn",
|
||||
methodReturnData: data,
|
||||
}),
|
||||
"*"
|
||||
);
|
||||
};
|
||||
|
||||
export const frameCallCommand = (command) => {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify({
|
||||
type: "onCallCommand",
|
||||
commandName: command,
|
||||
}),
|
||||
"*"
|
||||
);
|
||||
};
|
||||
|
@ -224,6 +224,7 @@ class TableHeader extends React.Component {
|
||||
resetColumnsSize,
|
||||
sectionWidth,
|
||||
infoPanelVisible,
|
||||
columns,
|
||||
} = this.props;
|
||||
|
||||
if (!infoPanelVisible && this.state.hideColumns) {
|
||||
@ -273,6 +274,11 @@ class TableHeader extends React.Component {
|
||||
? storageSize.split(" ")
|
||||
: container.style.gridTemplateColumns.split(" ");
|
||||
|
||||
// columns.length + 1 - its settings column
|
||||
if (tableContainer.length !== columns.length + 1) {
|
||||
return this.resetColumns(true);
|
||||
}
|
||||
|
||||
const containerWidth = +container.clientWidth;
|
||||
|
||||
const oldWidth =
|
||||
|
@ -2,6 +2,7 @@ import styled, { css } from "styled-components";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
import Text from "../text";
|
||||
import Base from "../themes/base";
|
||||
|
||||
const StyledTag = styled.div`
|
||||
width: fit-content;
|
||||
@ -17,7 +18,11 @@ const StyledTag = styled.div`
|
||||
margin-right: 4px;
|
||||
|
||||
background: ${(props) =>
|
||||
props.isDisabled ? "#F8F9F9" : props.isNewTag ? "#ECEEF1" : "#F3F4F4"};
|
||||
props.isDisabled
|
||||
? props.theme.tag.disabledBackground
|
||||
: props.isNewTag
|
||||
? props.theme.tag.newTagBackground
|
||||
: props.theme.tag.background};
|
||||
|
||||
border-radius: 6px;
|
||||
|
||||
@ -38,11 +43,13 @@ const StyledTag = styled.div`
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #eceef1;
|
||||
background: ${(props) => props.theme.tag.hoverBackground};
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
StyledTag.defaultProps = { theme: Base };
|
||||
|
||||
const StyledDropdownIcon = styled(ReactSVG)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -2739,6 +2739,13 @@ const Base = {
|
||||
color: grayMain,
|
||||
},
|
||||
},
|
||||
|
||||
tag: {
|
||||
background: "#f3f4f4",
|
||||
hoverBackground: "#eceef1",
|
||||
disabledBackground: "#f8f9f9",
|
||||
newTagBackground: "#eceef1",
|
||||
},
|
||||
};
|
||||
|
||||
export default Base;
|
||||
|
@ -2749,6 +2749,13 @@ const Dark = {
|
||||
color: "#C4C4C4",
|
||||
},
|
||||
},
|
||||
|
||||
tag: {
|
||||
background: "#3D3D3D",
|
||||
hoverBackground: "#333333",
|
||||
disabledBackground: "#858585",
|
||||
newTagBackground: "#333333",
|
||||
},
|
||||
};
|
||||
|
||||
export default Dark;
|
||||
|
@ -41,7 +41,7 @@ export const getFavicon = (documentType) => {
|
||||
export const initDocEditor = async (req) => {
|
||||
if (!req) return false;
|
||||
let personal = IS_PERSONAL || null;
|
||||
const { headers, url, query } = req;
|
||||
const { headers, url, query, type } = req;
|
||||
const { version, desktop: isDesktop } = query;
|
||||
let error = null;
|
||||
initSSR(headers);
|
||||
@ -101,6 +101,10 @@ export const initDocEditor = async (req) => {
|
||||
config.editorConfig.mode = "view";
|
||||
}
|
||||
|
||||
if (type) {
|
||||
config.type = type;
|
||||
}
|
||||
|
||||
const actionLink = config?.editorConfig?.actionLink || null;
|
||||
|
||||
return {
|
||||
|
@ -219,9 +219,9 @@ const Form = (props) => {
|
||||
//errorText && setErrorText("");
|
||||
let hasError = false;
|
||||
|
||||
const userName = identifier.trim();
|
||||
const user = identifier.trim();
|
||||
|
||||
if (!userName) {
|
||||
if (!user) {
|
||||
hasError = true;
|
||||
setIdentifierValid(false);
|
||||
setIsEmailErrorShow(true);
|
||||
@ -243,15 +243,18 @@ const Form = (props) => {
|
||||
|
||||
isDesktop && checkPwd();
|
||||
const session = !isChecked;
|
||||
login(userName, hash, session)
|
||||
.then((res) => {
|
||||
const { url, user, hash } = res;
|
||||
login(user, hash, session)
|
||||
.then((url) => {
|
||||
const redirectPath = localStorage.getItem("redirectPath");
|
||||
|
||||
if (redirectPath) {
|
||||
localStorage.removeItem("redirectPath");
|
||||
window.location.href = redirectPath;
|
||||
} else history.push(url, { user, hash });
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.replace(url); //TODO: save { user, hash } for tfa
|
||||
//history.push(url, { user, hash });
|
||||
})
|
||||
.catch((error) => {
|
||||
setIsEmailErrorShow(true);
|
||||
|
@ -638,9 +638,12 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_clientContext != null)
|
||||
{
|
||||
_clientContext.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFolderType(Folder<string> folder, bool isRoot)
|
||||
{
|
||||
|
@ -63,4 +63,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
@ -115,7 +115,7 @@ var eventBus = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService
|
||||
|
||||
eventBus.Subscribe<ThumbnailRequestedIntegrationEvent, ThumbnailRequestedIntegrationEventHandler>();
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
|
@ -54,4 +54,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
await app.RunAsync();
|
||||
await app.RunWithTasksAsync();
|
317
public/scripts/api.js
Normal file
317
public/scripts/api.js
Normal file
@ -0,0 +1,317 @@
|
||||
(function () {
|
||||
const defaultConfig = {
|
||||
src: `${window.location.protocol}//${window.location.hostname}:8092`,
|
||||
rootPath: "/rooms/personal/",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
name: "frameDocSpace",
|
||||
type: "desktop", // TODO: ["desktop", "mobile"]
|
||||
frameId: "ds-frame",
|
||||
mode: "manager", //TODO: ["manager", "editor", "viewer", "file selector", "folder selector", "user picker"]
|
||||
fileId: null,
|
||||
editorType: "embedded", //TODO: ["desktop", "embedded"]
|
||||
showHeader: false,
|
||||
showArticle: false,
|
||||
showTitle: true,
|
||||
showFilter: false,
|
||||
destroyText: "Frame container",
|
||||
viewAs: "row", //TODO: ["row", "table", "tile"]
|
||||
filter: {
|
||||
folder: "@my",
|
||||
count: 25,
|
||||
page: 0,
|
||||
sortorder: "descending", //TODO: ["descending", "ascending"]
|
||||
sortby: "DateAndTime", //TODO: ["DateAndTime", "AZ", "Type", "Size", "DateAndTimeCreation", "Author"]
|
||||
search: "",
|
||||
filterType: null,
|
||||
authorType: null,
|
||||
withSubfolders: true,
|
||||
},
|
||||
keysForReload: [
|
||||
"src",
|
||||
"rootPath",
|
||||
"width",
|
||||
"height",
|
||||
"name",
|
||||
"frameId",
|
||||
"fileId",
|
||||
"type",
|
||||
"editorType",
|
||||
],
|
||||
};
|
||||
|
||||
const getConfigFromParams = () => {
|
||||
const src = document.currentScript.src;
|
||||
|
||||
if (!src || !src.length) return null;
|
||||
|
||||
const searchUrl = src.split("?")[1];
|
||||
let object = {};
|
||||
|
||||
if (searchUrl && searchUrl.length) {
|
||||
object = JSON.parse(
|
||||
`{"${searchUrl.replace(/&/g, '","').replace(/=/g, '":"')}"}`,
|
||||
(k, v) => (v === "true" ? true : v === "false" ? false : v)
|
||||
);
|
||||
|
||||
object.filter = defaultConfig.filter;
|
||||
|
||||
for (prop in object) {
|
||||
if (prop in defaultConfig.filter) {
|
||||
object.filter[prop] = object[prop];
|
||||
delete object[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { ...defaultConfig, ...object };
|
||||
};
|
||||
|
||||
class DocSpace {
|
||||
#iframe;
|
||||
#isConnected = false;
|
||||
#callbacks = [];
|
||||
#tasks = [];
|
||||
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
#oneOfExistInObject = (array, object) => {
|
||||
return Object.keys(object).some((k) => array.includes(k));
|
||||
};
|
||||
|
||||
#createIframe = (config) => {
|
||||
const iframe = document.createElement("iframe");
|
||||
|
||||
let path = "";
|
||||
|
||||
switch (config.mode) {
|
||||
case "manager": {
|
||||
if (config.filter) {
|
||||
const filterString = new URLSearchParams(config.filter).toString();
|
||||
path = `${config.rootPath}filter?${filterString}`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "editor": {
|
||||
path = `/doceditor/?fileId=${config.fileId}&type=${config.editorType}`;
|
||||
break;
|
||||
}
|
||||
|
||||
case "viewer": {
|
||||
path = `/doceditor/?fileId=${config.fileId}&type=${config.editorType}&action=view`;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
path = config.rootPath;
|
||||
}
|
||||
|
||||
iframe.src = config.src + path;
|
||||
iframe.width = config.width;
|
||||
iframe.height = config.height;
|
||||
iframe.name = config.name;
|
||||
iframe.id = config.frameId;
|
||||
|
||||
iframe.align = "top";
|
||||
iframe.frameBorder = 0;
|
||||
iframe.allowFullscreen = true;
|
||||
iframe.setAttribute("allowfullscreen", "");
|
||||
iframe.setAttribute("onmousewheel", "");
|
||||
iframe.setAttribute("allow", "autoplay");
|
||||
|
||||
if (config.type == "mobile") {
|
||||
iframe.style.position = "fixed";
|
||||
iframe.style.overflow = "hidden";
|
||||
document.body.style.overscrollBehaviorY = "contain";
|
||||
}
|
||||
|
||||
return iframe;
|
||||
};
|
||||
|
||||
#sendMessage = (message) => {
|
||||
let mes = {
|
||||
frameId: this.config.frameId,
|
||||
type: "",
|
||||
data: message,
|
||||
};
|
||||
|
||||
if (this.#iframe)
|
||||
this.#iframe.contentWindow.postMessage(
|
||||
JSON.stringify(mes),
|
||||
this.config.src
|
||||
);
|
||||
};
|
||||
|
||||
#onMessage = (e) => {
|
||||
if (typeof e.data == "string") {
|
||||
let frameData = {};
|
||||
|
||||
try {
|
||||
frameData = JSON.parse(e.data);
|
||||
} catch (err) {
|
||||
frameData = {};
|
||||
}
|
||||
|
||||
switch (frameData.type) {
|
||||
case "onMethodReturn": {
|
||||
if (this.#callbacks.length > 0) {
|
||||
const callback = this.#callbacks.shift();
|
||||
callback && callback(frameData.methodReturnData);
|
||||
}
|
||||
|
||||
if (this.#tasks.length > 0) {
|
||||
this.#sendMessage(this.#tasks.shift());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "onCallCommand": {
|
||||
this[frameData.commandName].call(this);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
#executeMethod = (methodName, params, callback) => {
|
||||
if (!this.#isConnected) {
|
||||
console.log("Message bus is not connected with frame");
|
||||
return;
|
||||
}
|
||||
|
||||
this.#callbacks.push(callback);
|
||||
|
||||
const message = {
|
||||
type: "method",
|
||||
methodName,
|
||||
data: params,
|
||||
};
|
||||
|
||||
if (this.#callbacks.length !== 1) {
|
||||
this.#tasks.push(message);
|
||||
return;
|
||||
}
|
||||
|
||||
this.#sendMessage(message);
|
||||
};
|
||||
|
||||
initFrame(frameConfig) {
|
||||
this.config = { ...this.config, ...frameConfig };
|
||||
|
||||
const target = document.getElementById(this.config.frameId);
|
||||
|
||||
if (target) {
|
||||
this.#iframe = this.#createIframe(this.config);
|
||||
|
||||
target.parentNode &&
|
||||
target.parentNode.replaceChild(this.#iframe, target);
|
||||
|
||||
window.addEventListener("message", this.#onMessage, false);
|
||||
this.#isConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
destroyFrame() {
|
||||
const target = document.createElement("div");
|
||||
|
||||
target.setAttribute("id", this.config.frameId);
|
||||
target.innerHTML = this.config.destroyText;
|
||||
|
||||
if (this.#iframe) {
|
||||
window.removeEventListener("message", this.#onMessage, false);
|
||||
this.#isConnected = false;
|
||||
|
||||
this.#iframe.parentNode &&
|
||||
this.#iframe.parentNode.replaceChild(target, this.#iframe);
|
||||
}
|
||||
}
|
||||
|
||||
#getMethodPromise = (methodName, params = null, withReload = false) => {
|
||||
return new Promise((resolve) => {
|
||||
if (withReload) {
|
||||
this.initFrame(this.config);
|
||||
resolve(this.config);
|
||||
} else {
|
||||
this.#executeMethod(methodName, params, (data) => resolve(data));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
getFolderInfo() {
|
||||
return this.#getMethodPromise("getFolderInfo");
|
||||
}
|
||||
|
||||
getSelection() {
|
||||
return this.#getMethodPromise("getSelection");
|
||||
}
|
||||
|
||||
getFiles() {
|
||||
return this.#getMethodPromise("getFiles");
|
||||
}
|
||||
|
||||
getFolders() {
|
||||
return this.#getMethodPromise("getFolders");
|
||||
}
|
||||
|
||||
getList() {
|
||||
return this.#getMethodPromise("getList");
|
||||
}
|
||||
|
||||
getUserInfo() {
|
||||
return this.#getMethodPromise("getUserInfo");
|
||||
}
|
||||
|
||||
getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
setConfig(newConfig = {}, reload = false) {
|
||||
if (this.#oneOfExistInObject(this.config.keysForReload, newConfig))
|
||||
reload = true;
|
||||
|
||||
this.config = { ...this.config, ...newConfig };
|
||||
|
||||
return this.#getMethodPromise("setConfig", this.config, reload);
|
||||
}
|
||||
|
||||
openModal(type, options) {
|
||||
return this.#getMethodPromise("openModal", { type, options });
|
||||
}
|
||||
|
||||
createFile(folderId, title, templateId, formId) {
|
||||
return this.#getMethodPromise("createFile", {
|
||||
folderId,
|
||||
title,
|
||||
templateId,
|
||||
formId,
|
||||
});
|
||||
}
|
||||
|
||||
createFolder(parentFolderId, title) {
|
||||
return this.#getMethodPromise("createFolder", {
|
||||
parentFolderId,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
createRoom(title, type) {
|
||||
return this.#getMethodPromise("createRoom", {
|
||||
title,
|
||||
type,
|
||||
});
|
||||
}
|
||||
|
||||
setListView(type) {
|
||||
return this.#getMethodPromise("setItemsView", type);
|
||||
}
|
||||
}
|
||||
|
||||
const config = getConfigFromParams();
|
||||
|
||||
window.DocSpace = new DocSpace(config);
|
||||
|
||||
window.DocSpace.initFrame();
|
||||
})();
|
@ -56,4 +56,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
await app.RunAsync();
|
||||
await app.RunWithTasksAsync();
|
@ -25,7 +25,7 @@
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
global using ASC.Web.HealthChecks.UI;
|
||||
|
||||
global using ASC.Api.Core.Extensions;
|
||||
|
||||
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
global using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
@ -24,6 +24,7 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
|
||||
var options = new WebApplicationOptions
|
||||
{
|
||||
Args = args,
|
||||
@ -43,4 +44,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
||||
|
@ -55,4 +55,4 @@ var app = builder.Build();
|
||||
|
||||
startup.Configure(app, app.Environment);
|
||||
|
||||
app.Run();
|
||||
await app.RunWithTasksAsync();
|
Loading…
Reference in New Issue
Block a user