Merge branch 'feature/admin-messages' of github.com:ONLYOFFICE/AppServer into feature/session-lifetime
This commit is contained in:
commit
fe4b4d3c2d
@ -6,6 +6,7 @@
|
||||
"common\\ASC.Common\\ASC.Common.csproj",
|
||||
"common\\ASC.Core.Common\\ASC.Core.Common.csproj",
|
||||
"common\\ASC.Data.Backup.Core\\ASC.Data.Backup.Core.csproj",
|
||||
"common\\ASC.Data.Encryption\\ASC.Data.Encryption.csproj",
|
||||
"common\\ASC.Data.Reassigns\\ASC.Data.Reassigns.csproj",
|
||||
"common\\ASC.Data.Storage\\ASC.Data.Storage.csproj",
|
||||
"common\\ASC.FederatedLogin\\ASC.FederatedLogin.csproj",
|
||||
|
@ -1,3 +1,5 @@
|
||||
@echo off
|
||||
|
||||
echo "##########################################################"
|
||||
echo "######### Start build and deploy Personal ##############"
|
||||
echo "##########################################################"
|
||||
@ -6,6 +8,7 @@ echo.
|
||||
|
||||
PUSHD %~dp0
|
||||
call runasadmin.bat "%~dpnx0"
|
||||
|
||||
if %errorlevel% == 0 (
|
||||
|
||||
call start\stop.bat nopause
|
||||
@ -18,7 +21,11 @@ call build\build.static.bat nopause personal
|
||||
echo "BACK-END"
|
||||
call build\build.backend.bat nopause
|
||||
|
||||
start /b call build\start\start.bat nopause
|
||||
PUSHD %~dp0
|
||||
|
||||
call start\start.bat nopause
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
||||
)
|
@ -74,4 +74,6 @@ sed -i "s!\"Threads\".*!\"Threads\": \"${ELK_THREADS}\"!g" ${PATH_TO_CONF}/elast
|
||||
sed -i "s!\"subfolder\".*!\"subfolder\": \"server\",!g" ${PATH_TO_CONF}/appsettings.services.json
|
||||
sed -i "s!\"BootstrapServers\".*!\"BootstrapServers\": \"${KAFKA_HOST}\"!g" ${PATH_TO_CONF}/kafka.${APP_DOTNET_ENV}.json
|
||||
|
||||
sed -i "s!\"path\".*!\"path\": \"../../ASC.Socket.IO\"!g" ${PATH_TO_CONF}/socket.${APP_DOTNET_ENV}.json
|
||||
|
||||
dotnet ${DOTNET_RUN} --urls=${URLS} --ENVIRONMENT=${APP_DOTNET_ENV} --'$STORAGE_ROOT'=${APP_STORAGE_ROOT} --pathToConf=${PATH_TO_CONF} --log:dir=${LOG_DIR} --log:name=${DOTNET_LOG_NAME} ${PARAMETERS}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="18.6" version="18.7" Modules="enterprise" RootPath="." Language="ru" Id="{2D2C7C0E-FA78-4158-A222-DA463E882AAC}">
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="18.6" version="18.7" Modules="enterprise" RootPath="." Language="en" Id="{2D2C7C0E-FA78-4158-A222-DA463E882AAC}">
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="AI_CURRENT_YEAR" Value="2022" ValueLocId="-"/>
|
||||
@ -11,7 +11,7 @@
|
||||
<ROW Property="ARPNOREPAIR" Value="1"/>
|
||||
<ROW Property="ARPSYSTEMCOMPONENT" Value="1"/>
|
||||
<ROW Property="Manufacturer" Value="Apache"/>
|
||||
<ROW Property="ProductCode" Value="1049:{79F55836-69B9-46CE-B03D-7679D38C0AD4} " Type="16"/>
|
||||
<ROW Property="ProductCode" Value="1033:{79F55836-69B9-46CE-B03D-7679D38C0AD4} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="Apache Kafka"/>
|
||||
<ROW Property="ProductVersion" Value="1.0.0"/>
|
||||
@ -63,11 +63,11 @@
|
||||
<ROW Action="AI_DetectSoftware" Sequence="151"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|ProductName]" Languages="ru" InstallationType="4" UseLargeSchema="true" Unicode="true" UACExecutionLevel="2"/>
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|ProductName]" Languages="en" InstallationType="4" UseLargeSchema="true" Unicode="true" UACExecutionLevel="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_ru.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_en.ail"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
|
||||
<ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/>
|
||||
@ -84,12 +84,12 @@
|
||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
||||
<ROW Action="AI_ConfigFailActions" Description="Настройка действия при сбое службы" DescriptionLocId="ActionText.Description.AI_ConfigFailActions" Template="Служба: [1]" TemplateLocId="ActionText.Template.AI_ConfigFailActions"/>
|
||||
<ROW Action="AI_ProcessFailActions" Description="Создание действия для настройки действия при сбое службы" DescriptionLocId="ActionText.Description.AI_ProcessFailActions" Template="Служба: [1]" TemplateLocId="ActionText.Template.AI_ProcessFailActions"/>
|
||||
<ROW Action="AI_TxtUpdaterCommit" Description="Фиксация изменений текстового файла." DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" Template="Фиксация изменений текстового файла." TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
|
||||
<ROW Action="AI_TxtUpdaterConfig" Description="Выполнение обновления текстового файла" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" Template="Обновление текстового файла: "[1]"" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
|
||||
<ROW Action="AI_TxtUpdaterInstall" Description="Создание действий для настройки текстовых файлов обновлений" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
|
||||
<ROW Action="AI_TxtUpdaterRollback" Description="Откат изменений текстового файла." DescriptionLocId="ActionText.Description.AI_TxtUpdaterRollback" Template="Откат изменений текстового файла." TemplateLocId="ActionText.Template.AI_TxtUpdaterRollback"/>
|
||||
<ROW Action="AI_ConfigFailActions" Description="Configure service failure actions" DescriptionLocId="ActionText.Description.AI_ConfigFailActions" Template="Service: [1]" TemplateLocId="ActionText.Template.AI_ConfigFailActions"/>
|
||||
<ROW Action="AI_ProcessFailActions" Description="Generating actions to configure service failure actions" DescriptionLocId="ActionText.Description.AI_ProcessFailActions" Template="Service: [1]" TemplateLocId="ActionText.Template.AI_ProcessFailActions"/>
|
||||
<ROW Action="AI_TxtUpdaterCommit" Description="Commit text file changes." DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" Template="Commit text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
|
||||
<ROW Action="AI_TxtUpdaterConfig" Description="Executing text file updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" Template="Updating text file: "[1]"" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
|
||||
<ROW Action="AI_TxtUpdaterInstall" Description="Generating actions to configure text files updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
|
||||
<ROW Action="AI_TxtUpdaterRollback" Description="Rolling back text file changes." DescriptionLocId="ActionText.Description.AI_TxtUpdaterRollback" Template="Rolling back text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterRollback"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||
<ROW Name="PowerShellScriptLauncher.dll" SourcePath="<AI_CUSTACTS>PowerShellScriptLauncher.dll"/>
|
||||
@ -193,11 +193,11 @@
|
||||
<ROW Action="AI_RestartElevated" Sequence="51" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="Нельзя установить [ProductName] на [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="Нельзя установить [ProductName] на [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="Нельзя установить [ProductName] на [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="AI_DETECTED_INTERNET_CONNECTION" Description="Для установки [ProductName] требуется активное подключение к Интернету. Пожалуйста, проверьте настройки прокси-сервера и конфигурации сети." DescriptionLocId="AI.LaunchCondition.Internet" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] не может быть установлен на [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="[ProductName] cannot be installed on [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="[ProductName] cannot be installed on [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="[ProductName] cannot be installed on [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="AI_DETECTED_INTERNET_CONNECTION" Description="[ProductName] requires an active Internet connection for installation. Please check your network configuration and proxy settings." DescriptionLocId="AI.LaunchCondition.Internet" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
|
||||
<ROW Registry="Comments" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Comments" Value="[ARPCOMMENTS]" Component_="AI_CustomARPName"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="18.6.1" version="18.7" Modules="enterprise" RootPath="." Language="ru" Id="{93F1E21E-F074-444A-9756-659088E0DA02}">
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="18.6.1" version="18.7" Modules="enterprise" RootPath="." Language="en" Id="{93F1E21E-F074-444A-9756-659088E0DA02}">
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="AI_CURRENT_YEAR" Value="2022" ValueLocId="-"/>
|
||||
@ -10,7 +10,7 @@
|
||||
<ROW Property="ARPNOREPAIR" Value="1"/>
|
||||
<ROW Property="ARPSYSTEMCOMPONENT" Value="1"/>
|
||||
<ROW Property="Manufacturer" Value="Apache"/>
|
||||
<ROW Property="ProductCode" Value="1049:{DA471CF9-78DC-4D13-AB18-87B4604538FA} " Type="16"/>
|
||||
<ROW Property="ProductCode" Value="1033:{DA471CF9-78DC-4D13-AB18-87B4604538FA} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="Apache ZooKeeper"/>
|
||||
<ROW Property="ProductVersion" Value="1.0.0" Type="32"/>
|
||||
@ -47,11 +47,11 @@
|
||||
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|ProductName]" Languages="ru" InstallationType="4" UseLargeSchema="true" Unicode="true" UACExecutionLevel="2"/>
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="publish" PackageFileName="[|ProductName]" Languages="en" InstallationType="4" UseLargeSchema="true" Unicode="true" UACExecutionLevel="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_ru.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_en.ail"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
|
||||
<ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/>
|
||||
@ -147,10 +147,10 @@
|
||||
<ROW Action="AI_RestartElevated" Sequence="51" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="Нельзя установить [ProductName] на [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="Нельзя установить [ProductName] на [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="Нельзя установить [ProductName] на [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] не может быть установлен на [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="[ProductName] cannot be installed on [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="[ProductName] cannot be installed on [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="[ProductName] cannot be installed on [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
|
||||
<ROW Registry="Comments" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Comments" Value="[ARPCOMMENTS]" Component_="AI_CustomARPName"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
REM echo ######## Set variables ########
|
||||
set "msbuild4="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe""
|
||||
set "publisher="Ascensio System SIA""
|
||||
|
||||
REM echo ######## Extracting and preparing files to build ########
|
||||
%sevenzip% x build\install\win\nginx-1.21.1.zip -o"build\install\win\Files" -y
|
||||
@ -29,7 +29,7 @@ del /f /q "build\install\win\kafka-zookeeper\zookeeper\conf\zoo_sample.cfg"
|
||||
rmdir build\install\win\publish /s /q
|
||||
|
||||
REM echo ######## Build Utils ########
|
||||
%msbuild4% build\install\win\CustomActions\C#\Utils\Utils.csproj
|
||||
%msbuild% build\install\win\CustomActions\C#\Utils\Utils.csproj
|
||||
copy build\install\win\CustomActions\C#\Utils\bin\Debug\Utils.CA.dll build\install\win\Utils.CA.dll /y
|
||||
rmdir build\install\win\CustomActions\C#\Utils\bin /s /q
|
||||
rmdir build\install\win\CustomActions\C#\Utils\obj /s /q
|
||||
@ -80,7 +80,7 @@ copy "build\install\win\publish\Apache ZooKeeper.msi" "build\install\win\Apache
|
||||
copy "build\install\win\publish\Apache Kafka.msi" "build\install\win\Apache Kafka.msi" /y
|
||||
|
||||
REM echo ######## Build MySQL Server Installer ########
|
||||
iscc "build\install\win\MySQL Server Installer Runner.iss"
|
||||
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%
|
||||
|
@ -11,7 +11,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Elasticsearch" Version="6.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Elasticsearch" Version="5.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Kafka" Version="6.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="6.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="6.0.1" />
|
||||
|
@ -50,24 +50,24 @@ namespace ASC.Api.Core.Core
|
||||
name: "kafka",
|
||||
tags: new string[] { "kafka" });
|
||||
|
||||
}
|
||||
|
||||
|
||||
var elasticSettings = configuration.GetSection("elastic");
|
||||
|
||||
if (elasticSettings != null && elasticSettings.GetChildren().Any())
|
||||
{
|
||||
var host = elasticSettings.GetSection("Host").Value ?? "localhost";
|
||||
var scheme = elasticSettings.GetSection("Scheme").Value ?? "http";
|
||||
var port = elasticSettings.GetSection("Port").Value ?? "9200";
|
||||
var elasticSearchUri = $"{scheme}://{host}:{port}";
|
||||
|
||||
if (Uri.IsWellFormedUriString(elasticSearchUri, UriKind.Absolute))
|
||||
{
|
||||
hcBuilder.AddElasticsearch(elasticSearchUri,
|
||||
name: "elasticsearch",
|
||||
tags: new string[] { "elasticsearch" });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var elasticSettings = configuration.GetSection("elastic");
|
||||
|
||||
if (elasticSettings != null && elasticSettings.GetChildren().Any())
|
||||
{
|
||||
var host = elasticSettings.GetSection("Host").Value ?? "localhost";
|
||||
var scheme = elasticSettings.GetSection("Scheme").Value ?? "http";
|
||||
var port = elasticSettings.GetSection("Port").Value ?? "9200";
|
||||
var elasticSearchUri = $"{scheme}://{host}:{port}";
|
||||
|
||||
if (Uri.IsWellFormedUriString(elasticSearchUri, UriKind.Absolute))
|
||||
{
|
||||
hcBuilder.AddElasticsearch(elasticSearchUri,
|
||||
name: "elasticsearch",
|
||||
tags: new string[] { "elasticsearch" });
|
||||
}
|
||||
}
|
||||
|
||||
return services;
|
||||
|
@ -98,7 +98,9 @@ namespace ASC.Web.Api.Models
|
||||
|
||||
public bool IsSSO { get; set; }
|
||||
|
||||
public new static EmployeeWraperFull GetSample()
|
||||
public DarkThemeSettingsEnum? Theme { get; set; }
|
||||
|
||||
public static new EmployeeWraperFull GetSample()
|
||||
{
|
||||
return new EmployeeWraperFull
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ namespace ASC.Core
|
||||
public UserInfo GetUserBySid(string sid)
|
||||
{
|
||||
return GetUsersInternal()
|
||||
.FirstOrDefault(u => u.Sid != null && string.Equals(u.Sid , sid, StringComparison.CurrentCultureIgnoreCase)) ?? Constants.LostUser;
|
||||
.FirstOrDefault(u => u.Sid != null && string.Equals(u.Sid, sid, StringComparison.CurrentCultureIgnoreCase)) ?? Constants.LostUser;
|
||||
}
|
||||
|
||||
public UserInfo GetSsoUserByNameId(string nameId)
|
||||
@ -518,6 +518,11 @@ namespace ASC.Core
|
||||
{
|
||||
var group = UserService.GetGroup(Tenant.TenantId, groupID);
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
group = ToGroup(Constants.BuildinGroups.FirstOrDefault(r => r.ID == groupID));
|
||||
}
|
||||
|
||||
return new GroupInfo
|
||||
{
|
||||
ID = group.Id,
|
||||
|
@ -321,11 +321,11 @@ namespace ASC.Core.Notify.Signalr
|
||||
}
|
||||
}
|
||||
|
||||
public void StopEdit<T>(T fileId, string room, string data)
|
||||
public void StopEdit<T>(T fileId, string room)
|
||||
{
|
||||
try
|
||||
{
|
||||
MakeRequest("stop-edit", new { room, fileId, data });
|
||||
MakeRequest("stop-edit", new { room, fileId });
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
|
@ -275,9 +275,14 @@ namespace ASC.Security.Cryptography
|
||||
case ConfirmType.PhoneAuth:
|
||||
case ConfirmType.TfaActivation:
|
||||
case ConfirmType.TfaAuth:
|
||||
case ConfirmType.Auth:
|
||||
checkKeyResult = Provider.ValidateEmailKey(email + type, key, Provider.ValidAuthKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PortalContinue:
|
||||
checkKeyResult = Provider.ValidateEmailKey(email + type, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
checkKeyResult = Provider.ValidateEmailKey(email + type, key, Provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
61
common/ASC.Core.Common/Users/DarkThemeSettings.cs
Normal file
61
common/ASC.Core.Common/Users/DarkThemeSettings.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// (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.Text.Json.Serialization;
|
||||
|
||||
using ASC.Core.Common.Settings;
|
||||
|
||||
namespace ASC.Web.Core.Users;
|
||||
|
||||
[Serializable]
|
||||
public class DarkThemeSettings : ISettings
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Guid ID
|
||||
{
|
||||
get { return new Guid("{38362061-066D-4C57-A23E-8953CF34EFC3}"); }
|
||||
}
|
||||
|
||||
public DarkThemeSettingsEnum Theme { get; set; }
|
||||
|
||||
public ISettings GetDefault(IServiceProvider serviceProvider)
|
||||
{
|
||||
return new DarkThemeSettings
|
||||
{
|
||||
Theme = DarkThemeSettingsEnum.Base,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum DarkThemeSettingsEnum
|
||||
{
|
||||
Base,
|
||||
Dark,
|
||||
System
|
||||
}
|
@ -43,7 +43,7 @@ namespace ASC.IPSecurity
|
||||
public IPRestrictionsServiceCache(ICacheNotify<IPRestrictionItem> notify, ICache cache)
|
||||
{
|
||||
Cache = cache;
|
||||
notify.Subscribe((r) => Cache.Remove(GetCacheKey(r.TenantId)), CacheNotifyAction.Any);
|
||||
notify.Subscribe((r) => Cache.Remove(GetCacheKey(r.TenantId)), CacheNotifyAction.InsertOrUpdate);
|
||||
Notify = notify;
|
||||
}
|
||||
|
||||
|
@ -101,9 +101,9 @@
|
||||
filesIO.to(room).emit("s:start-edit-file", fileId);
|
||||
}
|
||||
|
||||
function stopEdit({ fileId, room, data } = {}) {
|
||||
function stopEdit({ fileId, room } = {}) {
|
||||
logger.info(`stop edit file ${fileId} in room ${room}`);
|
||||
filesIO.to(room).emit("s:stop-edit-file", fileId, data);
|
||||
filesIO.to(room).emit("s:stop-edit-file", fileId);
|
||||
}
|
||||
|
||||
function modifyFolder(room, cmd, id, type, data) {
|
||||
|
@ -554,7 +554,8 @@ namespace ASC.ElasticSearch
|
||||
|
||||
while (!string.IsNullOrEmpty(name = TryGetName(expression, out var member)))
|
||||
{
|
||||
sourceExprText = "." + name + sourceExprText;
|
||||
sourceExprText = "." + name + sourceExprText;
|
||||
expression = member.Expression;
|
||||
}
|
||||
|
||||
if (isList)
|
||||
|
@ -53,18 +53,18 @@
|
||||
},
|
||||
"files": {
|
||||
"thirdparty": {
|
||||
"enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ]
|
||||
"enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ]
|
||||
},
|
||||
"docservice": {
|
||||
"coauthor-docs": [ ".pptx", ".ppsx", ".xlsx", ".csv", ".docx", ".docxf", ".oform", ".txt" ],
|
||||
"commented-docs": [ ".docx", ".docxf", ".xlsx", ".pptx" ],
|
||||
"convert-docs": [ ".pptm", ".ppt", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".rtf" ],
|
||||
"edited-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".txt", ".rtf", ".mht", ".html", ".htm" ],
|
||||
"encrypted-docs": [ ".docx", ".docxf", ".xlsx", ".pptx", ".oform" ],
|
||||
"formfilling-docs": [ ".oform" ],
|
||||
"customfilter-docs": [ ".xlsx" ],
|
||||
"reviewed-docs": [ ".docx", ".docxf" ],
|
||||
"viewed-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ],
|
||||
"coauthor-docs": [ ".pptx", ".ppsx", ".xlsx", ".csv", ".docx", ".docxf", ".oform", ".txt" ],
|
||||
"commented-docs": [ ".docx", ".docxf", ".xlsx", ".pptx" ],
|
||||
"convert-docs": [ ".pptm", ".ppt", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".rtf" ],
|
||||
"edited-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".txt", ".rtf", ".mht", ".html", ".htm" ],
|
||||
"encrypted-docs": [ ".docx", ".docxf", ".xlsx", ".pptx", ".oform" ],
|
||||
"formfilling-docs": [ ".oform" ],
|
||||
"customfilter-docs": [ ".xlsx" ],
|
||||
"reviewed-docs": [ ".docx", ".docxf" ],
|
||||
"viewed-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ],
|
||||
"secret": {
|
||||
"value": "",
|
||||
"header": ""
|
||||
@ -77,15 +77,20 @@
|
||||
},
|
||||
"ffmpeg": {
|
||||
"value": "",
|
||||
"exts": [ "avi", "mpeg", "mpg", "wmv" ]
|
||||
"exts": [ "avi", "mpeg", "mpg", "wmv" ]
|
||||
},
|
||||
"uploader": {
|
||||
"chunk-size": 10485760,
|
||||
"url": "products/files/"
|
||||
},
|
||||
"viewed-images": [ ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ico", ".tif", ".tiff", ".webp" ],
|
||||
"viewed-media": [ ".aac", ".flac", ".m4a", ".mp3", ".oga", ".ogg", ".wav", ".f4v", ".m4v", ".mov", ".mp4", ".ogv", ".webm" ],
|
||||
"index": [ ".pptx", ".xlsx", ".docx" ]
|
||||
"viewed-images": [ ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ico", ".tif", ".tiff", ".webp" ],
|
||||
"viewed-media": [ ".aac", ".flac", ".m4a", ".mp3", ".oga", ".ogg", ".wav", ".f4v", ".m4v", ".mov", ".mp4", ".ogv", ".webm" ],
|
||||
"index": [ ".pptx", ".xlsx", ".docx" ],
|
||||
"oform": {
|
||||
"url": "https://oforms.onlyoffice.com/data/reqdata.json",
|
||||
"period": 60,
|
||||
"ext": ".oform"
|
||||
}
|
||||
},
|
||||
"web": {
|
||||
"api": "api/2.0",
|
||||
|
@ -1,5 +1,4 @@
|
||||
{
|
||||
"kafka": {
|
||||
"BootstrapServers": "localhost:9092"
|
||||
}
|
||||
"kafka": {
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.0",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/asc-web-components",
|
||||
|
@ -14,7 +14,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "lerna run build --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
|
||||
"build:personal": "lerna run build --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",
|
||||
"build:personal": "lerna run build:personal --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",
|
||||
"build:test": "lerna run build:test --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
|
||||
"build:test.translation": "lerna run build:test.translation --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
|
||||
"bump": "lerna version --no-push --no-git-tag-version",
|
||||
@ -23,7 +23,7 @@
|
||||
"deploy:personal": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor} && shx cp -r public build/deploy",
|
||||
"serve": "lerna run serve --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
|
||||
"start": "lerna run start --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
|
||||
"start:personal": "lerna run start --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",
|
||||
"start:personal": "lerna run start:personal --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",
|
||||
"start-prod": "lerna run start-prod --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
|
||||
"storybook": "yarn workspace @appserver/components storybook",
|
||||
"storybook-build": "yarn workspace @appserver/components run storybook-build",
|
||||
|
@ -3,6 +3,7 @@ import axios from "axios";
|
||||
import FilesFilter from "./filter";
|
||||
import { FolderType } from "../../constants";
|
||||
import find from "lodash/find";
|
||||
import { getFolderOptions } from "../../utils";
|
||||
|
||||
export function openEdit(fileId, version, doc, view) {
|
||||
const params = []; // doc ? `?doc=${doc}` : "";
|
||||
@ -48,19 +49,7 @@ export function getFolderPath(folderId) {
|
||||
}
|
||||
|
||||
export function getFolder(folderId, filter) {
|
||||
if (folderId && typeof folderId === "string") {
|
||||
folderId = encodeURIComponent(folderId.replace(/\\\\/g, "\\"));
|
||||
}
|
||||
|
||||
const params =
|
||||
filter && filter instanceof FilesFilter
|
||||
? `${folderId}?${filter.toApiUrlParams()}`
|
||||
: folderId;
|
||||
const options = {
|
||||
method: "get",
|
||||
url: `/files/${params}`,
|
||||
};
|
||||
|
||||
const options = getFolderOptions(folderId, filter);
|
||||
return request(options);
|
||||
}
|
||||
|
||||
@ -181,6 +170,38 @@ export function getFoldersTree() {
|
||||
);
|
||||
}
|
||||
|
||||
export function getCommonFoldersTree() {
|
||||
const index = 1;
|
||||
return request({ method: "get", url: "/files/@common" }).then(
|
||||
(commonFolders) => {
|
||||
return [
|
||||
{
|
||||
id: commonFolders.current.id,
|
||||
key: `0-${index}`,
|
||||
parentId: commonFolders.current.parentId,
|
||||
title: commonFolders.current.title,
|
||||
rootFolderType: +commonFolders.current.rootFolderType,
|
||||
rootFolderName: "@common",
|
||||
pathParts: commonFolders.pathParts,
|
||||
foldersCount: commonFolders.current.foldersCount,
|
||||
newItems: commonFolders.new,
|
||||
},
|
||||
];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function getThirdPartyCommonFolderTree() {
|
||||
return request({ method: "get", url: "/files/thirdparty/common" }).then(
|
||||
(commonThirdPartyArray) => {
|
||||
commonThirdPartyArray.map((currentValue, index) => {
|
||||
commonThirdPartyArray[index].key = `0-${index}`;
|
||||
});
|
||||
return commonThirdPartyArray;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function getMyFolderList(filter = FilesFilter.getDefault()) {
|
||||
const options = {
|
||||
method: "get",
|
||||
@ -277,8 +298,8 @@ export function deleteFolder(folderId, deleteAfter, immediately) {
|
||||
return request(options);
|
||||
}
|
||||
|
||||
export function createFile(folderId, title, templateId) {
|
||||
const data = { title, templateId };
|
||||
export function createFile(folderId, title, templateId, formId) {
|
||||
const data = { title, templateId, formId };
|
||||
const options = {
|
||||
method: "post",
|
||||
url: `/files/${folderId}/file`,
|
||||
|
@ -303,3 +303,13 @@ export function getSelectorUserList() {
|
||||
url: "/people/filter.json?fields=id,displayName,groups",
|
||||
});
|
||||
}
|
||||
|
||||
export function changeTheme(key) {
|
||||
const data = { Theme: key };
|
||||
|
||||
return request({
|
||||
method: "put",
|
||||
url: `/people/theme.json`,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { request } from "../client";
|
||||
import axios from "axios";
|
||||
|
||||
export function getSettings() {
|
||||
return request({
|
||||
@ -436,13 +437,6 @@ export function validateTfaCode(code) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getCommonThirdPartyList() {
|
||||
const options = {
|
||||
method: "get",
|
||||
url: "/files/thirdparty/common",
|
||||
};
|
||||
return request(options);
|
||||
}
|
||||
export function getBackupStorage() {
|
||||
const options = {
|
||||
method: "get",
|
||||
@ -482,3 +476,7 @@ export function toggleTipsSubscription() {
|
||||
};
|
||||
return request(options);
|
||||
}
|
||||
|
||||
export function getOforms(url) {
|
||||
return axios.get(url);
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import Backdrop from "@appserver/components/backdrop";
|
||||
const mobileView = css`
|
||||
top: 64px;
|
||||
|
||||
width: 100vw !important;
|
||||
height: calc(100vh - 64px) !important;
|
||||
width: 100% !important;
|
||||
height: calc(100% - 64px) !important;
|
||||
`;
|
||||
|
||||
const StyledBlock = styled.div`
|
||||
@ -22,8 +22,8 @@ const StyledBlock = styled.div`
|
||||
right: 0;
|
||||
|
||||
width: 480px;
|
||||
max-width: 100vw;
|
||||
height: 100vh;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
|
||||
z-index: 400;
|
||||
|
||||
|
@ -136,7 +136,11 @@ const Selector = (props) => {
|
||||
|
||||
const newGroupList = groupList;
|
||||
|
||||
newGroupList.find((group) => group.key === groupHeader.key).total = total;
|
||||
if (newGroupList.length > 0) {
|
||||
newGroupList.find(
|
||||
(group) => group.key === groupHeader.key
|
||||
).total = total;
|
||||
}
|
||||
|
||||
setGroupList(newGroupList);
|
||||
}
|
||||
@ -334,7 +338,7 @@ const Selector = (props) => {
|
||||
isDisabled={isDisabled}
|
||||
placeholder={searchPlaceHolderLabel}
|
||||
value={searchValue}
|
||||
onChange={onSearchChange}
|
||||
onSearchChange={onSearchChange}
|
||||
onClearSearch={onSearchReset}
|
||||
/>
|
||||
<div style={{ width: "100%", height: "100%" }} className="body-options">
|
||||
|
@ -7,6 +7,9 @@ const StyledFooter = styled.div`
|
||||
padding: 16px;
|
||||
height: 69px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
${(props) =>
|
||||
props.withEmbeddedComponent &&
|
||||
css`
|
||||
@ -18,6 +21,16 @@ const StyledFooter = styled.div`
|
||||
css`
|
||||
display: none;
|
||||
`}
|
||||
|
||||
button {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.embedded_combo-box {
|
||||
.combo-button {
|
||||
min-height: 42px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledFooter.defaultProps = { theme: Base };
|
||||
|
@ -31,7 +31,7 @@ const Article = ({
|
||||
toggleShowText,
|
||||
toggleArticleOpen,
|
||||
setIsMobileArticle,
|
||||
isLoading,
|
||||
isLoadedPage,
|
||||
children,
|
||||
...rest
|
||||
}) => {
|
||||
@ -107,7 +107,12 @@ const Article = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledArticle showText={showText} articleOpen={articleOpen} {...rest}>
|
||||
<StyledArticle
|
||||
id={"article-container"}
|
||||
showText={showText}
|
||||
articleOpen={articleOpen}
|
||||
{...rest}
|
||||
>
|
||||
<Resizable
|
||||
defaultSize={{
|
||||
width: 256,
|
||||
@ -117,7 +122,7 @@ const Article = ({
|
||||
handleWrapperClass="resizable-border not-selectable"
|
||||
>
|
||||
<SubArticleHeader
|
||||
isLoading={isLoading}
|
||||
isLoadedPage={isLoadedPage}
|
||||
showText={showText}
|
||||
onClick={toggleShowText}
|
||||
>
|
||||
@ -128,7 +133,7 @@ const Article = ({
|
||||
{articleMainButtonContent.props.children}
|
||||
</SubArticleMainButton>
|
||||
) : null}
|
||||
<SubArticleBody isLoading={isLoading} showText={showText}>
|
||||
<SubArticleBody showText={showText}>
|
||||
{articleBodyContent ? articleBodyContent.props.children : null}
|
||||
</SubArticleBody>
|
||||
</Resizable>
|
||||
|
@ -36,36 +36,31 @@ const StyledArticle = styled.article`
|
||||
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (props.articleOpen ? "flex" : "none")};
|
||||
min-width: 100vw;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 64px) !important;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
|
||||
height: calc(100% - 64px) !important;
|
||||
margin: 0;
|
||||
margin-top: 16px;
|
||||
padding: 0;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
display: ${(props) => (props.articleOpen ? "flex" : "none")} !important;
|
||||
min-width: 100vw !important;
|
||||
width: 100vw;
|
||||
min-width: 100% !important;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
|
||||
margin-top: 64px !important;
|
||||
height: calc(100vh - 64px) !important;
|
||||
height: calc(100% - 64px) !important;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 0px;
|
||||
`}
|
||||
|
||||
@media ${mobile} {
|
||||
position: fixed;
|
||||
margin-top: 16px;
|
||||
height: calc(100vh - 64px) !important;
|
||||
z-index: 400;
|
||||
}
|
||||
|
||||
z-index: ${(props) =>
|
||||
props.showText && (isMobileOnly || isMobileUtils()) ? "205" : "100"};
|
||||
props.showText && (isMobileOnly || isMobileUtils()) ? "230" : "100"};
|
||||
|
||||
.resizable-block {
|
||||
overflow: hidden;
|
||||
@ -97,12 +92,11 @@ const StyledArticle = styled.article`
|
||||
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (props.articleOpen ? "flex" : "none")};
|
||||
min-width: 100vw;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 64px) !important;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
@ -117,18 +111,25 @@ const StyledArticle = styled.article`
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
display: ${(props) => (props.articleOpen ? "flex" : "none")};
|
||||
min-width: 100vw !important;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 64px) !important;
|
||||
min-width: 100% !important;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 0px;
|
||||
`}
|
||||
}
|
||||
|
||||
.article-body__scrollbar {
|
||||
.scroll-body {
|
||||
padding-right: 0px !important;
|
||||
|
||||
@media ${mobile} {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
padding-bottom: 20px;
|
||||
`}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@ -11,7 +11,12 @@ const ArticleBackdrop = ({ onClick, ...rest }) => {
|
||||
<StyledControlContainer onClick={onClick} {...rest}>
|
||||
<StyledCrossIcon />
|
||||
</StyledControlContainer>
|
||||
<Backdrop visible={true} zIndex={201} withBackground={true} />
|
||||
<Backdrop
|
||||
onClick={onClick}
|
||||
visible={true}
|
||||
zIndex={210}
|
||||
withBackground={true}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,10 +1,8 @@
|
||||
import React from "react";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import LoaderArticleBody from "./article-body-loader";
|
||||
const ArticleBody = ({ children, isLoading = false }) => {
|
||||
return isLoading ? (
|
||||
<LoaderArticleBody />
|
||||
) : (
|
||||
|
||||
const ArticleBody = ({ children }) => {
|
||||
return (
|
||||
<Scrollbar className="article-body__scrollbar" stype="mediumBlack">
|
||||
{children}
|
||||
</Scrollbar>
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useLocation } from "react-router";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { isTablet as isTabletUtils } from "@appserver/components/utils/device";
|
||||
import { isTablet } from "react-device-detect";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
StyledArticleHeader,
|
||||
StyledHeading,
|
||||
@ -15,12 +16,29 @@ const ArticleHeader = ({
|
||||
showText,
|
||||
children,
|
||||
onClick,
|
||||
isLoading = false,
|
||||
isLoadedPage,
|
||||
isLoaded,
|
||||
tReady,
|
||||
setIsLoadedArticleHeader,
|
||||
...rest
|
||||
}) => {
|
||||
const location = useLocation();
|
||||
|
||||
const isLoadedSetting = isLoaded;
|
||||
|
||||
const commonSettings =
|
||||
location.pathname.includes("common/customization") ||
|
||||
location.pathname === "/settings";
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) setIsLoadedArticleHeader(isLoadedSetting);
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
const heightLoader = isTabletUtils() || isTablet ? "20px" : "32px";
|
||||
|
||||
return isLoading ? (
|
||||
const showLoader = commonSettings ? !isLoadedPage : false;
|
||||
|
||||
return showLoader ? (
|
||||
<StyledArticleHeader>
|
||||
<Loaders.ArticleHeader height={heightLoader} className="loader" />
|
||||
</StyledArticleHeader>
|
||||
@ -45,4 +63,11 @@ ArticleHeader.propTypes = {
|
||||
|
||||
ArticleHeader.displayName = "Header";
|
||||
|
||||
export default React.memo(ArticleHeader);
|
||||
export default inject(({ common }) => {
|
||||
const { isLoaded, setIsLoadedArticleHeader } = common;
|
||||
|
||||
return {
|
||||
isLoaded,
|
||||
setIsLoadedArticleHeader,
|
||||
};
|
||||
})(observer(ArticleHeader));
|
||||
|
@ -80,7 +80,8 @@ const FilterInput = React.memo(
|
||||
!isMobile &&
|
||||
viewSelectorVisible &&
|
||||
!isMobileUtils() &&
|
||||
!isTabletUtils() ? (
|
||||
!isTabletUtils() &&
|
||||
viewAs !== "row" ? (
|
||||
<ViewSelector
|
||||
style={{ marginLeft: "8px" }}
|
||||
onChangeView={onChangeViewAs}
|
||||
@ -89,7 +90,10 @@ const FilterInput = React.memo(
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{(isMobile || isTabletUtils() || isMobileUtils()) && (
|
||||
{(isMobile ||
|
||||
isTabletUtils() ||
|
||||
isMobileUtils() ||
|
||||
viewAs === "row") && (
|
||||
<SortButton
|
||||
t={t}
|
||||
selectedFilterData={selectedFilterData}
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
StyledCrossIcon,
|
||||
} from "./StyledFilterBlock";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
|
||||
//TODO: fix translate
|
||||
const FilterBlock = ({
|
||||
@ -213,21 +214,25 @@ const FilterBlock = ({
|
||||
size={17}
|
||||
/>
|
||||
</StyledFilterBlockHeader>
|
||||
{filterData.map((item) => {
|
||||
return (
|
||||
<FilterBlockItem
|
||||
key={item.key}
|
||||
label={item.label}
|
||||
keyProp={item.key}
|
||||
group={item.group}
|
||||
groupItem={item.groupItem}
|
||||
isLast={item.isLast}
|
||||
withoutHeader={item.withoutHeader}
|
||||
changeFilterValue={changeFilterValue}
|
||||
showSelector={changeShowSelector}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div className="filter-body">
|
||||
<Scrollbar className="filter-body__scrollbar" stype="mediumBlack">
|
||||
{filterData.map((item) => {
|
||||
return (
|
||||
<FilterBlockItem
|
||||
key={item.key}
|
||||
label={item.label}
|
||||
keyProp={item.key}
|
||||
group={item.group}
|
||||
groupItem={item.groupItem}
|
||||
isLast={item.isLast}
|
||||
withoutHeader={item.withoutHeader}
|
||||
changeFilterValue={changeFilterValue}
|
||||
showSelector={changeShowSelector}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Scrollbar>
|
||||
</div>
|
||||
<StyledFilterBlockFooter>
|
||||
<Button
|
||||
size="normal"
|
||||
|
@ -13,6 +13,7 @@ import { mobile } from "@appserver/components/utils/device";
|
||||
import { Base } from "@appserver/components/themes";
|
||||
|
||||
import SortDesc from "../../../../../public/images/sort.desc.react.svg";
|
||||
import Backdrop from "@appserver/components/backdrop";
|
||||
|
||||
const selectedViewIcon = css`
|
||||
svg {
|
||||
@ -31,13 +32,18 @@ const notSelectedViewIcon = css`
|
||||
`;
|
||||
|
||||
const mobileView = css`
|
||||
position: fixed;
|
||||
top: auto;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
${(props) =>
|
||||
!props.isRecentFolder &&
|
||||
!props.isFavoritesFolder &&
|
||||
css`
|
||||
position: fixed;
|
||||
top: auto;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
|
||||
z-index: 999;
|
||||
z-index: 999;
|
||||
`}
|
||||
`;
|
||||
|
||||
const StyledSortButton = styled.div`
|
||||
@ -62,12 +68,10 @@ const StyledSortButton = styled.div`
|
||||
min-width: 200px;
|
||||
margin-top: 3px;
|
||||
|
||||
@media ${mobile} {
|
||||
@media (max-width: 428px) {
|
||||
${mobileView}
|
||||
}
|
||||
|
||||
${isMobileOnly && mobileView}
|
||||
|
||||
.view-selector-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -203,14 +207,14 @@ const SortButton = ({
|
||||
|
||||
const onOptionClick = React.useCallback(
|
||||
(e) => {
|
||||
const sortDirection =
|
||||
currentSelectedFilterData.sortDirection === "desc" &&
|
||||
e.target.closest(".option-item__icon")
|
||||
? "asc"
|
||||
: "desc";
|
||||
|
||||
const key = e.target.closest(".option-item").dataset.value;
|
||||
|
||||
let sortDirection = currentSelectedFilterData.sortDirection;
|
||||
|
||||
if (key === currentSelectedFilterData.sortId) {
|
||||
sortDirection = sortDirection === "desc" ? "asc" : "desc";
|
||||
}
|
||||
|
||||
setCurrentSelectedFilterData({
|
||||
sortId: key,
|
||||
sortDirection: sortDirection,
|
||||
@ -287,30 +291,39 @@ const SortButton = ({
|
||||
]);
|
||||
|
||||
return (
|
||||
<StyledSortButton
|
||||
viewAs={viewAs}
|
||||
isDesc={currentSelectedFilterData.sortDirection === "desc"}
|
||||
onClick={toggleCombobox}
|
||||
>
|
||||
<ComboBox
|
||||
opened={isOpen}
|
||||
toggleAction={toggleCombobox}
|
||||
className={"sort-combo-box"}
|
||||
options={[]}
|
||||
selectedOption={{}}
|
||||
directionX={"right"}
|
||||
directionY={"both"}
|
||||
scaled={true}
|
||||
size={"content"}
|
||||
advancedOptions={getAdvancedOptions()}
|
||||
disableIconClick={false}
|
||||
disableItemClick={true}
|
||||
isDefaultMode={false}
|
||||
manualY={"102%"}
|
||||
<>
|
||||
<Backdrop
|
||||
visible={isOpen}
|
||||
withBackground={true}
|
||||
onClick={toggleCombobox}
|
||||
/>
|
||||
<StyledSortButton
|
||||
viewAs={viewAs}
|
||||
isDesc={currentSelectedFilterData.sortDirection === "desc"}
|
||||
onClick={toggleCombobox}
|
||||
isRecentFolder={isRecentFolder}
|
||||
isFavoritesFolder={isFavoritesFolder}
|
||||
>
|
||||
<IconButton iconName="/static/images/sort.react.svg" size={16} />
|
||||
</ComboBox>
|
||||
</StyledSortButton>
|
||||
<ComboBox
|
||||
opened={isOpen}
|
||||
toggleAction={toggleCombobox}
|
||||
className={"sort-combo-box"}
|
||||
options={[]}
|
||||
selectedOption={{}}
|
||||
directionX={"right"}
|
||||
directionY={"both"}
|
||||
scaled={true}
|
||||
size={"content"}
|
||||
advancedOptions={getAdvancedOptions()}
|
||||
disableIconClick={false}
|
||||
disableItemClick={true}
|
||||
isDefaultMode={false}
|
||||
manualY={"102%"}
|
||||
>
|
||||
<IconButton iconName="/static/images/sort.react.svg" size={16} />
|
||||
</ComboBox>
|
||||
</StyledSortButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -10,8 +10,8 @@ import CrossIcon from "@appserver/components/public/static/images/cross.react.sv
|
||||
const mobileView = css`
|
||||
top: 64px;
|
||||
|
||||
width: 100vw !important;
|
||||
height: calc(100vh - 64px) !important;
|
||||
width: 100% !important;
|
||||
height: calc(100% - 64px) !important;
|
||||
`;
|
||||
|
||||
const StyledFilterBlock = styled.div`
|
||||
@ -20,7 +20,7 @@ const StyledFilterBlock = styled.div`
|
||||
right: 0;
|
||||
|
||||
width: 480px;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
|
||||
z-index: 400;
|
||||
|
||||
@ -44,6 +44,10 @@ const StyledFilterBlock = styled.div`
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-body {
|
||||
height: calc(100% - 125px);
|
||||
}
|
||||
`;
|
||||
|
||||
StyledFilterBlock.defaultProps = { theme: Base };
|
||||
@ -210,7 +214,9 @@ const StyledFilterBlockItemToggleButton = styled(ToggleButton)`
|
||||
|
||||
const StyledFilterBlockItemSeparator = styled.div`
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
width: calc(100% + 16px);
|
||||
|
||||
margin-right: 16px;
|
||||
|
||||
background: ${(props) => props.theme.filterInput.filter.separatorColor};
|
||||
|
||||
@ -242,12 +248,12 @@ const StyledFilterBlockFooter = styled.div`
|
||||
justify-content: center;
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100vw;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
width: 100vw;
|
||||
width: 100%;
|
||||
`}
|
||||
`;
|
||||
|
||||
|
@ -2,6 +2,8 @@ import Base from "@appserver/components/themes/base";
|
||||
import styled, { keyframes, css } from "styled-components";
|
||||
|
||||
const StyledCircleWrap = styled.div`
|
||||
position: relative;
|
||||
z-index: 500;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: ${(props) =>
|
||||
|
@ -9,10 +9,10 @@ const StyledFilter = styled.div`
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 8px;
|
||||
|
||||
${isMobile &&
|
||||
/* ${isMobile &&
|
||||
css`
|
||||
margin-top: -22px;
|
||||
`}
|
||||
`} */
|
||||
|
||||
@media ${mobile} {
|
||||
grid-template-columns: 1fr 50px;
|
||||
|
@ -3,7 +3,14 @@ import PropTypes from "prop-types";
|
||||
import { StyledRow } from "./StyledListLoader";
|
||||
import RectangleLoader from "../RectangleLoader";
|
||||
|
||||
const ListItemLoader = ({ id, className, style, isRectangle, ...rest }) => {
|
||||
const ListItemLoader = ({
|
||||
id,
|
||||
className,
|
||||
style,
|
||||
withoutFirstRectangle,
|
||||
withoutLastRectangle,
|
||||
...rest
|
||||
}) => {
|
||||
const {
|
||||
title,
|
||||
borderRadius,
|
||||
@ -16,8 +23,14 @@ const ListItemLoader = ({ id, className, style, isRectangle, ...rest }) => {
|
||||
} = rest;
|
||||
|
||||
return (
|
||||
<StyledRow id={id} className={className} style={style}>
|
||||
{isRectangle && (
|
||||
<StyledRow
|
||||
id={id}
|
||||
className={className}
|
||||
style={style}
|
||||
withoutFirstRectangle={withoutFirstRectangle}
|
||||
withoutLastRectangle={withoutLastRectangle}
|
||||
>
|
||||
{!withoutFirstRectangle && (
|
||||
<RectangleLoader
|
||||
title={title}
|
||||
width="16"
|
||||
@ -60,18 +73,20 @@ const ListItemLoader = ({ id, className, style, isRectangle, ...rest }) => {
|
||||
animate={animate}
|
||||
/>
|
||||
|
||||
<RectangleLoader
|
||||
title={title}
|
||||
width="16"
|
||||
height="16"
|
||||
borderRadius={borderRadius}
|
||||
backgroundColor={backgroundColor}
|
||||
foregroundColor={foregroundColor}
|
||||
backgroundOpacity={backgroundOpacity}
|
||||
foregroundOpacity={foregroundOpacity}
|
||||
speed={speed}
|
||||
animate={animate}
|
||||
/>
|
||||
{!withoutLastRectangle && (
|
||||
<RectangleLoader
|
||||
title={title}
|
||||
width="16"
|
||||
height="16"
|
||||
borderRadius={borderRadius}
|
||||
backgroundColor={backgroundColor}
|
||||
foregroundColor={foregroundColor}
|
||||
backgroundOpacity={backgroundOpacity}
|
||||
foregroundOpacity={foregroundOpacity}
|
||||
speed={speed}
|
||||
animate={animate}
|
||||
/>
|
||||
)}
|
||||
</StyledRow>
|
||||
);
|
||||
};
|
||||
@ -80,14 +95,16 @@ ListItemLoader.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
isRectangle: PropTypes.bool,
|
||||
withoutFirstRectangle: PropTypes.bool,
|
||||
withoutLastRectangle: PropTypes.bool,
|
||||
};
|
||||
|
||||
ListItemLoader.defaultProps = {
|
||||
id: undefined,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
isRectangle: true,
|
||||
withoutFirstRectangle: false,
|
||||
withoutLastRectangle: false,
|
||||
};
|
||||
|
||||
export default ListItemLoader;
|
||||
|
@ -9,21 +9,26 @@ const StyledRow = styled.div`
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 16px 32px 1fr 16px;
|
||||
${(props) =>
|
||||
props.withoutFirstRectangle &&
|
||||
props.withoutLastRectangle &&
|
||||
"grid-template-columns: 32px 1fr"};
|
||||
${(props) =>
|
||||
props.withoutFirstRectangle &&
|
||||
!props.withoutLastRectangle &&
|
||||
"grid-template-columns: 32px 1fr 16px"};
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
|
||||
.list-loader_rectangle {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.list-loader_rectangle-content {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.list-loader_rectangle-row {
|
||||
margin-right: auto;
|
||||
max-width: 167px;
|
||||
|
@ -0,0 +1,24 @@
|
||||
import styled from "styled-components";
|
||||
import { desktop } from "@appserver/components/utils/device";
|
||||
|
||||
const StyledTreeFolder = styled.div`
|
||||
padding-right: 16px;
|
||||
`;
|
||||
|
||||
const StyledLoader = styled.div`
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 8px 16px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.tree-node-loader_additional-rectangle {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
${(props) => props.paddingLeft && `padding-left: ${props.paddingLeft}`};
|
||||
`;
|
||||
|
||||
export { StyledLoader, StyledTreeFolder };
|
@ -0,0 +1,51 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { StyledTreeFolder, StyledLoader } from "./StyledTreeFolder";
|
||||
import TreeNodeLoader from "../TreeNodeLoader";
|
||||
|
||||
const NewTreeFolderLoader = ({ id, className, style, ...rest }) => {
|
||||
return (
|
||||
<StyledTreeFolder id={id} className={className} style={style}>
|
||||
<StyledLoader>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
<StyledLoader paddingLeft={"16px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
|
||||
<StyledLoader paddingLeft={"32px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
<StyledLoader paddingLeft={"32px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
<StyledLoader paddingLeft={"32px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
|
||||
<StyledLoader>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
<StyledLoader paddingLeft={"16px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
<StyledLoader paddingLeft={"16px"}>
|
||||
<TreeNodeLoader {...rest} withRectangle />
|
||||
</StyledLoader>
|
||||
</StyledTreeFolder>
|
||||
);
|
||||
};
|
||||
|
||||
NewTreeFolderLoader.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
};
|
||||
|
||||
NewTreeFolderLoader.defaultProps = {
|
||||
id: undefined,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
};
|
||||
|
||||
export default NewTreeFolderLoader;
|
@ -0,0 +1,145 @@
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { Base } from "@appserver/components/themes";
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const StyledHeader = styled.div`
|
||||
width: 100%;
|
||||
padding: ${(props) => (props.isPersonal ? "0px 16px 12px" : "12px 16px")};
|
||||
${(props) =>
|
||||
props.isPersonal &&
|
||||
css`
|
||||
margin-left: -12px;
|
||||
margin-right: 12px;
|
||||
`}
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom};
|
||||
`;
|
||||
|
||||
StyledHeader.defaultProps = { theme: Base };
|
||||
|
||||
const StyledExternalLink = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
padding: ${(props) => (props.isPersonal ? "20px 4px" : "20px 16px")};
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
border-bottom: ${(props) =>
|
||||
props.isPersonal ? "none" : props.theme.filesPanels.sharing.borderBottom};
|
||||
|
||||
.rectangle-loader {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
StyledExternalLink.defaultProps = { theme: Base };
|
||||
|
||||
const StyledInternalLink = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
padding: 20px 16px;
|
||||
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
|
||||
const StyledOwner = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
padding: 8px 16px;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
margin-bottom: 16px;
|
||||
|
||||
.owner-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
svg:first-child {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledBody = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
div:nth-child(3) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledItem = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
padding: 8px 16px;
|
||||
|
||||
.item-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
svg:first-child {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButtons = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
padding: 4px;
|
||||
|
||||
svg:first-child {
|
||||
margin-right: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
export {
|
||||
StyledContainer,
|
||||
StyledHeader,
|
||||
StyledExternalLink,
|
||||
StyledInternalLink,
|
||||
StyledOwner,
|
||||
StyledBody,
|
||||
StyledItem,
|
||||
StyledButtons,
|
||||
};
|
@ -0,0 +1,138 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import {
|
||||
StyledContainer,
|
||||
StyledHeader,
|
||||
StyledExternalLink,
|
||||
StyledInternalLink,
|
||||
StyledOwner,
|
||||
StyledBody,
|
||||
StyledItem,
|
||||
} from "./StyledSharingPanel";
|
||||
import RectangleLoader from "../RectangleLoader/RectangleLoader";
|
||||
|
||||
const SharingPanelLoader = ({ id, className, style, ...rest }) => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledHeader>
|
||||
<RectangleLoader width={"283px"} height={"29px"} />
|
||||
<RectangleLoader width={"48px"} height={"29px"} />
|
||||
</StyledHeader>
|
||||
|
||||
<StyledExternalLink>
|
||||
<RectangleLoader
|
||||
className="rectangle-loader"
|
||||
width={"146px"}
|
||||
height={"22px"}
|
||||
/>
|
||||
<RectangleLoader
|
||||
className="rectangle-loader"
|
||||
width={"448px"}
|
||||
height={"32px"}
|
||||
/>
|
||||
<RectangleLoader width={"184px"} height={"20px"} />
|
||||
</StyledExternalLink>
|
||||
|
||||
<StyledInternalLink>
|
||||
<RectangleLoader width={"99px"} height={"22px"} />
|
||||
<RectangleLoader width={"30px"} height={"22px"} />
|
||||
</StyledInternalLink>
|
||||
|
||||
<StyledOwner>
|
||||
<div className="owner-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</StyledOwner>
|
||||
|
||||
<StyledBody>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
<StyledItem>
|
||||
<div className="item-info">
|
||||
<RectangleLoader
|
||||
width={"32px"}
|
||||
height={"32px"}
|
||||
borderRadius={"1000px"}
|
||||
/>
|
||||
<RectangleLoader width={"91px"} height={"16px"} />
|
||||
</div>
|
||||
<RectangleLoader width={"45px"} height={"32px"} />
|
||||
</StyledItem>
|
||||
</StyledBody>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
SharingPanelLoader.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
};
|
||||
|
||||
SharingPanelLoader.defaultProps = {
|
||||
id: undefined,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
};
|
||||
|
||||
export default SharingPanelLoader;
|
@ -0,0 +1,66 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import {
|
||||
StyledContainer,
|
||||
StyledHeader,
|
||||
StyledExternalLink,
|
||||
StyledInternalLink,
|
||||
StyledOwner,
|
||||
StyledBody,
|
||||
StyledItem,
|
||||
StyledButtons,
|
||||
} from "./StyledSharingPanel";
|
||||
import RectangleLoader from "../RectangleLoader/RectangleLoader";
|
||||
|
||||
const SharingPanelLoaderModal = ({
|
||||
id,
|
||||
className,
|
||||
style,
|
||||
isShared,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledHeader isPersonal={true}>
|
||||
<RectangleLoader width={"283px"} height={"16px"} />
|
||||
</StyledHeader>
|
||||
|
||||
<StyledExternalLink isPersonal={true}>
|
||||
<RectangleLoader
|
||||
className="rectangle-loader"
|
||||
width={"146px"}
|
||||
height={"22px"}
|
||||
/>
|
||||
{isShared && (
|
||||
<>
|
||||
<RectangleLoader
|
||||
className="rectangle-loader"
|
||||
width={"368px"}
|
||||
height={"32px"}
|
||||
/>
|
||||
<RectangleLoader width={"184px"} height={"20px"} />
|
||||
</>
|
||||
)}
|
||||
</StyledExternalLink>
|
||||
<StyledButtons>
|
||||
<RectangleLoader width={"100%"} height={"40px"} />
|
||||
<RectangleLoader width={"100%"} height={"40px"} />
|
||||
</StyledButtons>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
SharingPanelLoaderModal.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
};
|
||||
|
||||
SharingPanelLoaderModal.defaultProps = {
|
||||
id: undefined,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
};
|
||||
|
||||
export default SharingPanelLoaderModal;
|
@ -34,7 +34,13 @@ const StyledWrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const TilesLoader = ({ foldersCount, filesCount, sectionWidth, ...rest }) => {
|
||||
const TilesLoader = ({
|
||||
foldersCount,
|
||||
filesCount,
|
||||
sectionWidth,
|
||||
withTitle,
|
||||
...rest
|
||||
}) => {
|
||||
const folders = [];
|
||||
const files = [];
|
||||
|
||||
@ -59,15 +65,17 @@ const TilesLoader = ({ foldersCount, filesCount, sectionWidth, ...rest }) => {
|
||||
) : null}
|
||||
<StyledTilesLoader>{folders}</StyledTilesLoader>
|
||||
|
||||
{filesCount > 0 ? (
|
||||
<RectangleLoader
|
||||
height="22px"
|
||||
width="35px"
|
||||
className="files"
|
||||
animate
|
||||
{...rest}
|
||||
/>
|
||||
) : null}
|
||||
{filesCount > 0
|
||||
? withTitle && (
|
||||
<RectangleLoader
|
||||
height="22px"
|
||||
width="35px"
|
||||
className="files"
|
||||
animate
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
<StyledTilesLoader>{files}</StyledTilesLoader>
|
||||
</StyledWrapper>
|
||||
);
|
||||
@ -81,6 +89,7 @@ TilesLoader.propTypes = {
|
||||
TilesLoader.defaultProps = {
|
||||
foldersCount: 2,
|
||||
filesCount: 8,
|
||||
withTitle: true,
|
||||
};
|
||||
|
||||
export default TilesLoader;
|
||||
|
@ -11,6 +11,7 @@ const TreeNodeLoader = ({
|
||||
foregroundOpacity,
|
||||
speed,
|
||||
animate,
|
||||
withRectangle = false,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
@ -25,6 +26,23 @@ const TreeNodeLoader = ({
|
||||
speed={speed}
|
||||
animate={animate}
|
||||
/>
|
||||
|
||||
{withRectangle && (
|
||||
<RectangleLoader
|
||||
title={title}
|
||||
width="16"
|
||||
height="16"
|
||||
borderRadius={borderRadius}
|
||||
backgroundColor={backgroundColor}
|
||||
foregroundColor={foregroundColor}
|
||||
backgroundOpacity={backgroundOpacity}
|
||||
foregroundOpacity={foregroundOpacity}
|
||||
speed={speed}
|
||||
animate={animate}
|
||||
className="tree-node-loader_additional-rectangle"
|
||||
/>
|
||||
)}
|
||||
|
||||
<RectangleLoader
|
||||
title={title}
|
||||
width="100%"
|
||||
|
@ -7,6 +7,7 @@ import ArticleButton from "./ArticleButtonLoader";
|
||||
import ArticleFolder from "./ArticleFolderLoader";
|
||||
import ArticleGroup from "./ArticleGroupsLoader";
|
||||
import TreeFolders from "./TreeFolderLoader";
|
||||
import NewTreeFolders from "./NewTreeFolderLoader";
|
||||
import TreeSettingsLoader from "./TreeSettingsLoader";
|
||||
import Row from "./RowLoader";
|
||||
import Rows from "./RowsLoader";
|
||||
@ -21,6 +22,8 @@ import Tiles from "./TilesLoader";
|
||||
import DialogLoader from "./DialogLoader";
|
||||
import DialogAsideLoader from "./DialogAsideLoader";
|
||||
import ListLoader from "./ListLoader";
|
||||
import SharingPanelLoader from "./SharingPanelLoader";
|
||||
import SharingPanelLoaderModal from "./SharingPanelLoader/modal";
|
||||
|
||||
export default {
|
||||
Rectangle,
|
||||
@ -46,4 +49,7 @@ export default {
|
||||
ArticleFolder,
|
||||
ArticleGroup,
|
||||
ListLoader,
|
||||
NewTreeFolders,
|
||||
SharingPanelLoader,
|
||||
SharingPanelLoaderModal,
|
||||
};
|
||||
|
@ -9,9 +9,12 @@ import Text from "./sub-components/text";
|
||||
import ControlButtons from "./sub-components/control-btn";
|
||||
import DropBox from "./sub-components/drop-box";
|
||||
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
|
||||
import { Consumer } from "@appserver/components/utils/context";
|
||||
|
||||
import DomHelpers from "@appserver/components/utils/domHelpers";
|
||||
import Backdrop from "@appserver/components/backdrop";
|
||||
|
||||
const Navigation = ({
|
||||
tReady,
|
||||
@ -39,6 +42,7 @@ const Navigation = ({
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
const [firstClick, setFirstClick] = React.useState(true);
|
||||
const [dropBoxWidth, setDropBoxWidth] = React.useState(0);
|
||||
const [maxHeight, setMaxHeight] = React.useState(false);
|
||||
|
||||
const dropBoxRef = React.useRef(null);
|
||||
const containerRef = React.useRef(null);
|
||||
@ -64,21 +68,36 @@ const Navigation = ({
|
||||
|
||||
const toggleDropBox = () => {
|
||||
if (isRootFolder) return setIsOpen(false);
|
||||
setDropBoxWidth(DomHelpers.getOuterWidth(containerRef.current));
|
||||
setIsOpen((prev) => !prev);
|
||||
|
||||
setDropBoxWidth(DomHelpers.getOuterWidth(containerRef.current));
|
||||
|
||||
const { top } = DomHelpers.getOffset(containerRef.current);
|
||||
|
||||
setMaxHeight(`calc(100vh - ${top}px)`);
|
||||
|
||||
setFirstClick(true);
|
||||
};
|
||||
|
||||
const onResize = React.useCallback(() => {
|
||||
setDropBoxWidth(DomHelpers.getOuterWidth(containerRef.current));
|
||||
}, [containerRef.current]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isOpen) {
|
||||
window.addEventListener("click", onMissClick);
|
||||
window.addEventListener("resize", onResize);
|
||||
} else {
|
||||
window.removeEventListener("click", onMissClick);
|
||||
window.addEventListener("resize", onResize);
|
||||
setFirstClick(true);
|
||||
}
|
||||
|
||||
return () => window.removeEventListener("click", onMissClick);
|
||||
}, [isOpen, onMissClick]);
|
||||
return () => {
|
||||
window.removeEventListener("click", onMissClick);
|
||||
window.addEventListener("resize", onResize);
|
||||
};
|
||||
}, [isOpen, onResize, onMissClick]);
|
||||
|
||||
const onBackToParentFolderAction = React.useCallback(() => {
|
||||
setIsOpen((val) => !val);
|
||||
@ -90,25 +109,36 @@ const Navigation = ({
|
||||
{(context) => (
|
||||
<>
|
||||
{isOpen && (
|
||||
<DropBox
|
||||
{...rest}
|
||||
ref={dropBoxRef}
|
||||
dropBoxWidth={dropBoxWidth}
|
||||
sectionHeight={context.sectionHeight}
|
||||
showText={showText}
|
||||
isRootFolder={isRootFolder}
|
||||
onBackToParentFolder={onBackToParentFolderAction}
|
||||
title={title}
|
||||
personal={personal}
|
||||
canCreate={canCreate}
|
||||
navigationItems={navigationItems}
|
||||
getContextOptionsFolder={getContextOptionsFolder}
|
||||
getContextOptionsPlus={getContextOptionsPlus}
|
||||
toggleDropBox={toggleDropBox}
|
||||
toggleInfoPanel={toggleInfoPanel}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
onClickAvailable={onClickAvailable}
|
||||
/>
|
||||
<>
|
||||
{isMobileOnly && (
|
||||
<Backdrop
|
||||
isAside={true}
|
||||
visible={isOpen}
|
||||
withBackground={true}
|
||||
zIndex={400}
|
||||
/>
|
||||
)}
|
||||
<DropBox
|
||||
{...rest}
|
||||
ref={dropBoxRef}
|
||||
maxHeight={maxHeight}
|
||||
dropBoxWidth={dropBoxWidth}
|
||||
sectionHeight={context.sectionHeight}
|
||||
showText={showText}
|
||||
isRootFolder={isRootFolder}
|
||||
onBackToParentFolder={onBackToParentFolderAction}
|
||||
title={title}
|
||||
personal={personal}
|
||||
canCreate={canCreate}
|
||||
navigationItems={navigationItems}
|
||||
getContextOptionsFolder={getContextOptionsFolder}
|
||||
getContextOptionsPlus={getContextOptionsPlus}
|
||||
toggleDropBox={toggleDropBox}
|
||||
toggleInfoPanel={toggleInfoPanel}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
onClickAvailable={onClickAvailable}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<StyledContainer
|
||||
ref={containerRef}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
import { tablet, desktop, mobile } from "@appserver/components/utils/device";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import { tablet, mobile } from "@appserver/components/utils/device";
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
width: 100% !important;
|
||||
@ -16,28 +16,23 @@ const StyledContainer = styled.div`
|
||||
min-width: 17px;
|
||||
}
|
||||
|
||||
.headline-heading {
|
||||
display: flex;
|
||||
height: 32px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
width: 100%;
|
||||
grid-template-columns: ${(props) =>
|
||||
props.isRootFolder ? "auto 1fr" : "29px 1fr auto"};
|
||||
padding: ${(props) => (props.isDropBox ? "14px 0 5px" : "14px 0 15px")};
|
||||
}
|
||||
${isMobile &&
|
||||
css`
|
||||
width: 100%;
|
||||
padding: ${(props) =>
|
||||
props.isDropBox ? "12px 0 5px" : " 12px 0 13px"} !important;
|
||||
`}
|
||||
|
||||
@media ${mobile} {
|
||||
padding: ${(props) =>
|
||||
props.isDropBox ? "10px 0 5px" : "10px 0 11px"} !important;
|
||||
}
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
width: 100% !important;
|
||||
padding: ${(props) =>
|
||||
props.isDropBox ? "10px 0 5px" : "10px 0 11px"} !important;
|
||||
`}
|
||||
`;
|
||||
|
||||
export default StyledContainer;
|
||||
|
@ -13,8 +13,8 @@ const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
|
||||
.add-button {
|
||||
margin-right: 12px;
|
||||
min-width: 17px;
|
||||
margin-right: 16px;
|
||||
min-width: 15px;
|
||||
|
||||
${(props) =>
|
||||
!props.isDropBox &&
|
||||
@ -31,12 +31,13 @@ const StyledContainer = styled.div`
|
||||
}
|
||||
|
||||
.option-button {
|
||||
margin-right: 15px;
|
||||
min-width: 17px;
|
||||
margin-right: 16px;
|
||||
min-width: 15px;
|
||||
}
|
||||
|
||||
.trash-button {
|
||||
min-width: 17px;
|
||||
margin-right: 16px;
|
||||
min-width: 15px;
|
||||
}
|
||||
`;
|
||||
|
||||
@ -47,6 +48,15 @@ const StyledInfoPanelToggleWrapper = styled.div`
|
||||
justify-content: center;
|
||||
margin-left: auto;
|
||||
|
||||
@media ${tablet} {
|
||||
margin-left: ${(props) => (props.isRootFolder ? "auto" : "0")};
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
margin-left: ${(props) => (props.isRootFolder ? "auto" : "0")};
|
||||
`}
|
||||
|
||||
.info-panel-toggle-bg {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
@ -81,7 +91,14 @@ const ControlButtons = ({
|
||||
clearTrash,
|
||||
isInfoPanelVisible,
|
||||
toggleInfoPanel,
|
||||
toggleDropBox,
|
||||
isDesktop,
|
||||
}) => {
|
||||
const toggleInfoPanelAction = () => {
|
||||
toggleInfoPanel && toggleInfoPanel();
|
||||
toggleDropBox && toggleDropBox();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledContainer isDropBox={isDropBox}>
|
||||
{!isRootFolder && canCreate ? (
|
||||
@ -90,7 +107,7 @@ const ControlButtons = ({
|
||||
className="add-button"
|
||||
directionX="right"
|
||||
iconName="images/plus.svg"
|
||||
size={17}
|
||||
size={15}
|
||||
isFill
|
||||
getData={getContextOptionsPlus}
|
||||
isDisabled={false}
|
||||
@ -100,48 +117,97 @@ const ControlButtons = ({
|
||||
className="option-button"
|
||||
directionX="right"
|
||||
iconName="images/vertical-dots.react.svg"
|
||||
size={17}
|
||||
size={15}
|
||||
isFill
|
||||
getData={getContextOptionsFolder}
|
||||
isDisabled={false}
|
||||
/>
|
||||
)}
|
||||
{!isDesktop && (
|
||||
<StyledInfoPanelToggleWrapper
|
||||
isRootFolder={isRootFolder}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
>
|
||||
<div className="info-panel-toggle-bg">
|
||||
<IconButton
|
||||
className="info-panel-toggle"
|
||||
iconName="images/panel.react.svg"
|
||||
size="16"
|
||||
isFill={true}
|
||||
onClick={toggleInfoPanelAction}
|
||||
/>
|
||||
</div>
|
||||
</StyledInfoPanelToggleWrapper>
|
||||
)}
|
||||
</>
|
||||
) : canCreate ? (
|
||||
<ContextMenuButton
|
||||
className="add-button"
|
||||
directionX="right"
|
||||
iconName="images/plus.svg"
|
||||
size={17}
|
||||
isFill
|
||||
getData={getContextOptionsPlus}
|
||||
isDisabled={false}
|
||||
/>
|
||||
) : isRecycleBinFolder && !isEmptyFilesList ? (
|
||||
<IconButton
|
||||
iconName="images/clear.active.react.svg"
|
||||
size={17}
|
||||
isFill={true}
|
||||
onClick={clearTrash}
|
||||
className="trash-button"
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<StyledInfoPanelToggleWrapper
|
||||
isRootFolder={isRootFolder}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
>
|
||||
<div className="info-panel-toggle-bg">
|
||||
<IconButton
|
||||
className="info-panel-toggle"
|
||||
iconName="images/panel.react.svg"
|
||||
size="16"
|
||||
isFill={true}
|
||||
onClick={toggleInfoPanel}
|
||||
<>
|
||||
<ContextMenuButton
|
||||
className="add-button"
|
||||
directionX="right"
|
||||
iconName="images/plus.svg"
|
||||
size={15}
|
||||
isFill
|
||||
getData={getContextOptionsPlus}
|
||||
isDisabled={false}
|
||||
/>
|
||||
</div>
|
||||
</StyledInfoPanelToggleWrapper>
|
||||
<StyledInfoPanelToggleWrapper
|
||||
isRootFolder={isRootFolder}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
>
|
||||
<div className="info-panel-toggle-bg">
|
||||
<IconButton
|
||||
className="info-panel-toggle"
|
||||
iconName="images/panel.react.svg"
|
||||
size="16"
|
||||
isFill={true}
|
||||
onClick={toggleInfoPanelAction}
|
||||
/>
|
||||
</div>
|
||||
</StyledInfoPanelToggleWrapper>
|
||||
</>
|
||||
) : isRecycleBinFolder && !isEmptyFilesList ? (
|
||||
<>
|
||||
<IconButton
|
||||
iconName="images/clear.active.react.svg"
|
||||
size={15}
|
||||
isFill={true}
|
||||
onClick={clearTrash}
|
||||
className="trash-button"
|
||||
/>
|
||||
<StyledInfoPanelToggleWrapper
|
||||
isRootFolder={isRootFolder}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
>
|
||||
<div className="info-panel-toggle-bg">
|
||||
<IconButton
|
||||
className="info-panel-toggle"
|
||||
iconName="images/panel.react.svg"
|
||||
size="16"
|
||||
isFill={true}
|
||||
onClick={toggleInfoPanelAction}
|
||||
/>
|
||||
</div>
|
||||
</StyledInfoPanelToggleWrapper>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<StyledInfoPanelToggleWrapper
|
||||
isRootFolder={isRootFolder}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
>
|
||||
<div className="info-panel-toggle-bg">
|
||||
<IconButton
|
||||
className="info-panel-toggle"
|
||||
iconName="images/panel.react.svg"
|
||||
size="16"
|
||||
isFill={true}
|
||||
onClick={toggleInfoPanelAction}
|
||||
/>
|
||||
</div>
|
||||
</StyledInfoPanelToggleWrapper>
|
||||
</>
|
||||
)}
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
mobile,
|
||||
isMobile as isMobileUtils,
|
||||
isTablet as isTabletUtils,
|
||||
isDesktop as isDesktopUtils,
|
||||
} from "@appserver/components/utils/device";
|
||||
|
||||
import { Base } from "@appserver/components/themes";
|
||||
@ -28,12 +29,12 @@ const StyledBox = styled.div`
|
||||
|
||||
padding: ${isMobile ? "0 16px " : "0 20px"};
|
||||
|
||||
width: ${(props) => props.dropBoxWidth}px;
|
||||
${(props) => !props.isDesktop && `width: ${props.dropBoxWidth}px;`};
|
||||
|
||||
height: ${(props) => (props.height ? `${props.height}px` : "fit-content")};
|
||||
max-height: calc(100vh - 48px);
|
||||
|
||||
z-index: 399;
|
||||
z-index: 401;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -51,6 +52,7 @@ const StyledBox = styled.div`
|
||||
css`
|
||||
margin-left: 16px;
|
||||
padding: 0 16px !important;
|
||||
max-height: ${(props) => props.maxHeight};
|
||||
`}
|
||||
`;
|
||||
|
||||
@ -88,12 +90,16 @@ const DropBox = React.forwardRef(
|
||||
toggleInfoPanel,
|
||||
onClickAvailable,
|
||||
isInfoPanelVisible,
|
||||
maxHeight,
|
||||
isOpen,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const [dropBoxHeight, setDropBoxHeight] = React.useState(0);
|
||||
const countItems = navigationItems.length;
|
||||
|
||||
const isDesktop = !isMobile || isDesktopUtils();
|
||||
|
||||
const getItemSize = (index) => {
|
||||
if (index === countItems - 1) return 51;
|
||||
return isMobile || isMobileUtils() || isTabletUtils() ? 36 : 30;
|
||||
@ -124,41 +130,47 @@ const DropBox = React.forwardRef(
|
||||
}, [sectionHeight]);
|
||||
|
||||
return (
|
||||
<StyledBox
|
||||
ref={ref}
|
||||
height={sectionHeight < dropBoxHeight ? sectionHeight : null}
|
||||
showText={showText}
|
||||
dropBoxWidth={dropBoxWidth}
|
||||
>
|
||||
<StyledContainer canCreate={canCreate} isDropBox={true}>
|
||||
<ArrowButton
|
||||
isRootFolder={isRootFolder}
|
||||
onBackToParentFolder={onBackToParentFolder}
|
||||
/>
|
||||
<Text title={title} isOpen={true} onClick={toggleDropBox} />
|
||||
<ControlButtons
|
||||
personal={personal}
|
||||
isRootFolder={isRootFolder}
|
||||
isDropBox={true}
|
||||
canCreate={canCreate}
|
||||
getContextOptionsFolder={getContextOptionsFolder}
|
||||
getContextOptionsPlus={getContextOptionsPlus}
|
||||
toggleInfoPanel={toggleInfoPanel}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
/>
|
||||
</StyledContainer>
|
||||
|
||||
<VariableSizeList
|
||||
height={dropBoxHeight}
|
||||
width={"auto"}
|
||||
itemCount={countItems}
|
||||
itemSize={getItemSize}
|
||||
itemData={[navigationItems, onClickAvailable]}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
<>
|
||||
<StyledBox
|
||||
ref={ref}
|
||||
maxHeight={maxHeight}
|
||||
height={sectionHeight < dropBoxHeight ? sectionHeight : null}
|
||||
showText={showText}
|
||||
dropBoxWidth={dropBoxWidth}
|
||||
isDesktop={isDesktop}
|
||||
>
|
||||
{Row}
|
||||
</VariableSizeList>
|
||||
</StyledBox>
|
||||
<StyledContainer canCreate={canCreate} isDropBox={true}>
|
||||
<ArrowButton
|
||||
isRootFolder={isRootFolder}
|
||||
onBackToParentFolder={onBackToParentFolder}
|
||||
/>
|
||||
<Text title={title} isOpen={true} onClick={toggleDropBox} />
|
||||
<ControlButtons
|
||||
isDesktop={isDesktop}
|
||||
personal={personal}
|
||||
isRootFolder={isRootFolder}
|
||||
isDropBox={true}
|
||||
canCreate={canCreate}
|
||||
getContextOptionsFolder={getContextOptionsFolder}
|
||||
getContextOptionsPlus={getContextOptionsPlus}
|
||||
toggleInfoPanel={toggleInfoPanel}
|
||||
toggleDropBox={toggleDropBox}
|
||||
isInfoPanelVisible={isInfoPanelVisible}
|
||||
/>
|
||||
</StyledContainer>
|
||||
|
||||
<VariableSizeList
|
||||
height={dropBoxHeight}
|
||||
width={"auto"}
|
||||
itemCount={countItems}
|
||||
itemSize={getItemSize}
|
||||
itemData={[navigationItems, onClickAvailable]}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
>
|
||||
{Row}
|
||||
</VariableSizeList>
|
||||
</StyledBox>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -80,7 +80,6 @@ const Item = ({ id, title, isRoot, onClick, ...rest }) => {
|
||||
<StyledText
|
||||
isRoot={isRoot}
|
||||
fontWeight={isRoot ? "600" : "400"}
|
||||
isRoot={isRoot}
|
||||
fontSize={"15px"}
|
||||
truncate={true}
|
||||
>
|
||||
|
@ -26,7 +26,7 @@ const StyledTextContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledHeadline = styled(Headline)`
|
||||
width: calc(100% + 1px);
|
||||
width: 100%;
|
||||
font-weight: 700;
|
||||
font-size: ${isMobile ? "21px !important" : "18px"};
|
||||
line-height: ${isMobile ? "28px !important" : "24px"};
|
||||
|
@ -229,6 +229,8 @@ class Section extends React.Component {
|
||||
snackbarExist,
|
||||
showText,
|
||||
infoPanelIsVisible,
|
||||
isInfoPanelAvailable,
|
||||
settingsStudio,
|
||||
} = this.props;
|
||||
|
||||
let sectionHeaderContent = null;
|
||||
@ -365,6 +367,7 @@ class Section extends React.Component {
|
||||
autoFocus={isMobile || isTabletView ? false : true}
|
||||
viewAs={viewAs}
|
||||
isHomepage={isHomepage}
|
||||
settingsStudio={settingsStudio}
|
||||
>
|
||||
{isMobile && (
|
||||
<StyledMainBar
|
||||
@ -394,6 +397,7 @@ class Section extends React.Component {
|
||||
viewAs={viewAs}
|
||||
showText={showText}
|
||||
infoPanelIsVisible={infoPanelIsVisible}
|
||||
settingsStudio={settingsStudio}
|
||||
>
|
||||
{sectionHeaderContent
|
||||
? sectionHeaderContent.props.children
|
||||
@ -467,12 +471,16 @@ class Section extends React.Component {
|
||||
<></>
|
||||
)}
|
||||
</SectionContainer>
|
||||
<InfoPanel>
|
||||
<SubInfoPanelHeader>
|
||||
{infoPanelHeaderContent}
|
||||
</SubInfoPanelHeader>
|
||||
<SubInfoPanelBody>{infoPanelBodyContent}</SubInfoPanelBody>
|
||||
</InfoPanel>
|
||||
{isInfoPanelAvailable && (
|
||||
<InfoPanel>
|
||||
<SubInfoPanelHeader>
|
||||
{infoPanelHeaderContent}
|
||||
</SubInfoPanelHeader>
|
||||
<SubInfoPanelBody>
|
||||
{infoPanelBodyContent}
|
||||
</SubInfoPanelBody>
|
||||
</InfoPanel>
|
||||
)}
|
||||
</Provider>
|
||||
)}
|
||||
</ReactResizeDetector>
|
||||
@ -539,11 +547,15 @@ Section.propTypes = {
|
||||
isHeaderVisible: PropTypes.bool,
|
||||
firstLoad: PropTypes.bool,
|
||||
isHomepage: PropTypes.bool,
|
||||
isInfoPanelAvailable: PropTypes.bool,
|
||||
settingsStudio: PropTypes.bool,
|
||||
};
|
||||
|
||||
Section.defaultProps = {
|
||||
withBodyScroll: true,
|
||||
withBodyAutoFocus: false,
|
||||
isInfoPanelAvailable: true,
|
||||
settingsStudio: false,
|
||||
};
|
||||
|
||||
Section.InfoPanelHeader = InfoPanelHeader;
|
||||
|
@ -1,14 +1,21 @@
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import { Base } from "@appserver/components/themes";
|
||||
import { isTablet, mobile, tablet } from "@appserver/components/utils/device";
|
||||
import {
|
||||
isTablet,
|
||||
isMobile as isMobileUtils,
|
||||
tablet,
|
||||
} from "@appserver/components/utils/device";
|
||||
import { inject } from "mobx-react";
|
||||
import PropTypes from "prop-types";
|
||||
import React, { useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import CrossIcon from "@appserver/components/public/static/images/cross.react.svg";
|
||||
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({
|
||||
id: id,
|
||||
}))`
|
||||
user-select: none;
|
||||
height: auto;
|
||||
width: auto;
|
||||
background: rgba(6, 22, 38, 0.2);
|
||||
@ -16,12 +23,22 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({
|
||||
|
||||
@media ${tablet} {
|
||||
z-index: 309;
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
z-index: 309;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
`}
|
||||
`;
|
||||
|
||||
const StyledInfoPanel = styled.div`
|
||||
@ -32,6 +49,10 @@ const StyledInfoPanel = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.scroll-body {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
position: absolute;
|
||||
border: none;
|
||||
@ -40,46 +61,75 @@ const StyledInfoPanel = styled.div`
|
||||
max-width: calc(100vw - 69px);
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
${isMobile &&
|
||||
css`
|
||||
position: absolute;
|
||||
border: none;
|
||||
right: 0;
|
||||
width: 480px;
|
||||
max-width: calc(100vw - 69px);
|
||||
`}
|
||||
|
||||
@media (max-width: 428px) {
|
||||
bottom: 0;
|
||||
height: 80%;
|
||||
height: calc(100% - 64px);
|
||||
width: 100vw;
|
||||
max-width: 100vw;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledCloseButtonWrapper = styled.div`
|
||||
position: absolute;
|
||||
const StyledControlContainer = styled.div`
|
||||
display: none;
|
||||
background-color: ${(props) => props.theme.infoPanel.closeButtonBg};
|
||||
padding: ${(props) => props.theme.infoPanel.closeButtonWrapperPadding};
|
||||
border-radius: 50%;
|
||||
|
||||
.info-panel-button {
|
||||
svg {
|
||||
width: ${(props) => props.theme.infoPanel.closeButtonSize};
|
||||
height: ${(props) => props.theme.infoPanel.closeButtonSize};
|
||||
}
|
||||
path {
|
||||
fill: ${(props) => props.theme.infoPanel.closeButtonIcon};
|
||||
}
|
||||
}
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 450;
|
||||
/* background: ${(props) => props.theme.catalog.control.background}; */
|
||||
|
||||
@media ${tablet} {
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-top: 18px;
|
||||
margin-left: -34px;
|
||||
display: flex;
|
||||
|
||||
top: 16px;
|
||||
left: -34px;
|
||||
}
|
||||
@media ${mobile} {
|
||||
right: 0;
|
||||
left: auto;
|
||||
margin-top: -34px;
|
||||
margin-right: 10px;
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
display: flex !important;
|
||||
|
||||
top: 18px;
|
||||
left: -34px;
|
||||
`}
|
||||
|
||||
@media (max-width: 428px) {
|
||||
display: flex;
|
||||
|
||||
top: -34px;
|
||||
right: 10px;
|
||||
left: unset;
|
||||
}
|
||||
`;
|
||||
|
||||
StyledControlContainer.defaultProps = { theme: Base };
|
||||
|
||||
const StyledCrossIcon = styled(CrossIcon)`
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
z-index: 455;
|
||||
path {
|
||||
fill: ${(props) => props.theme.catalog.control.fill};
|
||||
}
|
||||
`;
|
||||
|
||||
StyledCrossIcon.defaultProps = { theme: Base };
|
||||
|
||||
const InfoPanel = ({ children, isVisible, setIsVisible }) => {
|
||||
if (!isVisible) return null;
|
||||
|
||||
@ -90,20 +140,19 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => {
|
||||
if (e.target.id === "InfoPanelWrapper") closeInfoPanel();
|
||||
};
|
||||
|
||||
if (isTablet()) document.addEventListener("mousedown", onMouseDown);
|
||||
if (isTablet() || isMobile || isMobileUtils()) {
|
||||
document.addEventListener("mousedown", onMouseDown);
|
||||
}
|
||||
return () => document.removeEventListener("mousedown", onMouseDown);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyledInfoPanelWrapper className="info-panel" id="InfoPanelWrapper">
|
||||
<StyledInfoPanel>
|
||||
<StyledCloseButtonWrapper>
|
||||
<IconButton
|
||||
onClick={closeInfoPanel}
|
||||
iconName="/static/images/cross.react.svg"
|
||||
className="info-panel-button"
|
||||
/>
|
||||
</StyledCloseButtonWrapper>
|
||||
<StyledControlContainer onClick={closeInfoPanel}>
|
||||
<StyledCrossIcon />
|
||||
</StyledControlContainer>
|
||||
|
||||
{children}
|
||||
</StyledInfoPanel>
|
||||
</StyledInfoPanelWrapper>
|
||||
@ -120,7 +169,6 @@ InfoPanel.propTypes = {
|
||||
};
|
||||
|
||||
StyledInfoPanelWrapper.defaultProps = { theme: Base };
|
||||
StyledCloseButtonWrapper.defaultProps = { theme: Base };
|
||||
StyledInfoPanel.defaultProps = { theme: Base };
|
||||
InfoPanel.defaultProps = { theme: Base };
|
||||
|
||||
|
@ -8,25 +8,43 @@ import { inject, observer } from "mobx-react";
|
||||
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import DragAndDrop from "@appserver/components/drag-and-drop";
|
||||
import { tablet, mobile, desktop } from "@appserver/components/utils/device";
|
||||
import {
|
||||
tablet,
|
||||
mobile,
|
||||
desktop,
|
||||
smallTablet,
|
||||
} from "@appserver/components/utils/device";
|
||||
|
||||
const paddingStyles = css`
|
||||
padding: 19px 7px 16px 20px;
|
||||
padding: ${(props) =>
|
||||
props.settingsStudio ? "0 7px 16px 24px" : "19px 7px 16px 20px"};
|
||||
|
||||
@media ${tablet} {
|
||||
padding: 19px 0 16px 24px;
|
||||
padding: ${(props) =>
|
||||
props.settingsStudio ? "0 0 16px 24px" : "19px 0 16px 24px"};
|
||||
}
|
||||
|
||||
@media ${smallTablet} {
|
||||
padding: ${(props) =>
|
||||
props.settingsStudio ? "8px 0 16px 24px" : "19px 0 16px 24px"};
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
padding: 19px 0 16px 24px;
|
||||
padding: ${(props) =>
|
||||
props.settingsStudio ? "8px 0 16px 24px" : "19px 0 16px 24px"};
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
padding: 0 0 16px 24px !important;
|
||||
`};
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
padding: 0px 0 16px 24px !important;
|
||||
`};
|
||||
`;
|
||||
|
||||
const commonStyles = css`
|
||||
flex-grow: 1;
|
||||
|
||||
@ -40,7 +58,7 @@ const commonStyles = css`
|
||||
.section-wrapper {
|
||||
${(props) =>
|
||||
!props.withScroll &&
|
||||
`display: flex; height: 100%; box-sizing:border-box`};
|
||||
`display: flex; flex-direction: column; height: 100%; box-sizing:border-box`};
|
||||
${(props) => !props.withScroll && paddingStyles}
|
||||
}
|
||||
|
||||
@ -169,6 +187,7 @@ class SectionBody extends React.Component {
|
||||
isLoaded,
|
||||
isDesktop,
|
||||
isHomepage,
|
||||
settingsStudio,
|
||||
} = this.props;
|
||||
|
||||
const focusProps = autoFocus
|
||||
@ -187,6 +206,7 @@ class SectionBody extends React.Component {
|
||||
pinned={pinned}
|
||||
isLoaded={isLoaded}
|
||||
isDesktop={isDesktop}
|
||||
settingsStudio={settingsStudio}
|
||||
className="section-body"
|
||||
>
|
||||
{withScroll ? (
|
||||
@ -221,6 +241,7 @@ class SectionBody extends React.Component {
|
||||
pinned={pinned}
|
||||
isLoaded={isLoaded}
|
||||
isDesktop={isDesktop}
|
||||
settingsStudio={settingsStudio}
|
||||
>
|
||||
{withScroll ? (
|
||||
!isMobileOnly ? (
|
||||
@ -268,6 +289,7 @@ SectionBody.propTypes = {
|
||||
viewAs: PropTypes.string,
|
||||
isLoaded: PropTypes.bool,
|
||||
isHomepage: PropTypes.bool,
|
||||
settingsStudio: PropTypes.bool,
|
||||
};
|
||||
|
||||
SectionBody.defaultProps = {
|
||||
@ -276,6 +298,7 @@ SectionBody.defaultProps = {
|
||||
uploadFiles: false,
|
||||
withScroll: true,
|
||||
isHomepage: false,
|
||||
settingsStudio: false,
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
|
@ -38,10 +38,8 @@ const StyledSectionContainer = styled.section`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: ${(props) =>
|
||||
props.infoPanelIsVisible ? "calc(100% - 677px)" : "100%"};
|
||||
max-width: ${(props) =>
|
||||
props.infoPanelIsVisible ? "calc(100vw - 677px)" : "100vw"};
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
@media ${tablet} {
|
||||
width: 100%;
|
||||
@ -52,7 +50,7 @@ const StyledSectionContainer = styled.section`
|
||||
${isMobile &&
|
||||
css`
|
||||
width: 100% !important;
|
||||
max-width: 100vw !important
|
||||
max-width: 100vw !important;
|
||||
padding: 0 0 0 16px;
|
||||
${tabletProps};
|
||||
min-width: 100px;
|
||||
|
@ -47,18 +47,22 @@ const StyledSectionHeader = styled.div`
|
||||
padding-right: 16px !important;
|
||||
|
||||
margin-top: -2px !important;
|
||||
|
||||
margin-bottom: ${(props) =>
|
||||
props.settingsStudio ? "8px !important" : "0"};
|
||||
`}
|
||||
`;
|
||||
|
||||
StyledSectionHeader.defaultProps = { theme: Base };
|
||||
|
||||
const SectionHeader = (props) => {
|
||||
const { viewAs, className, ...rest } = props;
|
||||
const { viewAs, settingsStudio = false, className, ...rest } = props;
|
||||
|
||||
return (
|
||||
<StyledSectionHeader
|
||||
className={`section-header ${className}`}
|
||||
viewAs={viewAs}
|
||||
settingsStudio={settingsStudio}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
@ -69,5 +73,6 @@ SectionHeader.displayName = "SectionHeader";
|
||||
SectionHeader.propTypes = {
|
||||
isArticlePinned: PropTypes.bool,
|
||||
isHeaderVisible: PropTypes.bool,
|
||||
settingsStudio: PropTypes.bool,
|
||||
};
|
||||
export default SectionHeader;
|
||||
|
@ -199,3 +199,16 @@ export const FileStatus = Object.freeze({
|
||||
export const TenantStatus = Object.freeze({
|
||||
PortalRestore: 4,
|
||||
});
|
||||
|
||||
/**
|
||||
* Enum for theme keys.
|
||||
* @readonly
|
||||
*/
|
||||
export const ThemeKeys = Object.freeze({
|
||||
Base: "0",
|
||||
BaseStr: "Base",
|
||||
Dark: "1",
|
||||
DarkStr: "Dark",
|
||||
System: "2",
|
||||
SystemStr: "System",
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/common",
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "echo 'skip it'",
|
||||
|
@ -323,6 +323,12 @@ class AuthStore {
|
||||
setProviders = (providers) => {
|
||||
this.providers = providers;
|
||||
};
|
||||
|
||||
getOforms = () => {
|
||||
const culture =
|
||||
this.userStore.user.cultureName || this.settingsStore.culture;
|
||||
return api.settings.getOforms(`${this.settingsStore.urlOforms}${culture}`);
|
||||
};
|
||||
}
|
||||
|
||||
export default new AuthStore();
|
||||
|
@ -3,7 +3,7 @@ import api from "../api";
|
||||
import { LANGUAGE, TenantStatus } from "../constants";
|
||||
import { combineUrl } from "../utils";
|
||||
import FirebaseHelper from "../utils/firebase";
|
||||
import { AppServerConfig } from "../constants";
|
||||
import { AppServerConfig, ThemeKeys } from "../constants";
|
||||
import { version } from "../package.json";
|
||||
import SocketIOHelper from "../utils/socket";
|
||||
|
||||
@ -26,9 +26,7 @@ class SettingsStore {
|
||||
currentProductId = "";
|
||||
culture = "en";
|
||||
cultures = [];
|
||||
theme = !!localStorage.getItem("theme")
|
||||
? themes[localStorage.getItem("theme")]
|
||||
: Base;
|
||||
theme = Base;
|
||||
trustedDomains = [];
|
||||
trustedDomainsType = 0;
|
||||
ipRestrictionEnable = false;
|
||||
@ -36,6 +34,7 @@ class SettingsStore {
|
||||
sessionLifetime = "1440";
|
||||
timezone = "UTC";
|
||||
timezones = [];
|
||||
tenantAlias = "";
|
||||
utcOffset = "00:00:00";
|
||||
utcHoursOffset = 0;
|
||||
defaultPage = "/";
|
||||
@ -54,6 +53,8 @@ class SettingsStore {
|
||||
enabledJoin = false;
|
||||
urlLicense = "https://gnu.org/licenses/gpl-3.0.html";
|
||||
urlSupport = "https://helpdesk.onlyoffice.com/";
|
||||
urlOforms = "https://cmsoforms.onlyoffice.com/api/oforms?populate=*&locale=";
|
||||
|
||||
logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg");
|
||||
customNames = {
|
||||
id: "Common",
|
||||
@ -224,6 +225,10 @@ class SettingsStore {
|
||||
) {
|
||||
this.getCurrentCustomSchema(origSettings.nameSchemaId);
|
||||
}
|
||||
|
||||
if (origSettings.tenantAlias) {
|
||||
this.setTenantAlias(origSettings.tenantAlias);
|
||||
}
|
||||
};
|
||||
|
||||
init = async () => {
|
||||
@ -253,8 +258,13 @@ class SettingsStore {
|
||||
this.isLoaded = isLoaded;
|
||||
};
|
||||
|
||||
setCultures = (cultures) => {
|
||||
this.cultures = cultures;
|
||||
};
|
||||
|
||||
getPortalCultures = async () => {
|
||||
this.cultures = await api.settings.getPortalCultures();
|
||||
const cultures = await api.settings.getPortalCultures();
|
||||
this.setCultures(cultures);
|
||||
};
|
||||
|
||||
setIsEncryptionSupport = (isEncryptionSupport) => {
|
||||
@ -431,19 +441,28 @@ class SettingsStore {
|
||||
this.buildVersionInfo.documentServer = "6.4.1";
|
||||
};
|
||||
|
||||
changeTheme = () => {
|
||||
const currentTheme =
|
||||
JSON.stringify(this.theme) === JSON.stringify(Base) ? Dark : Base;
|
||||
localStorage.setItem(
|
||||
"theme",
|
||||
JSON.stringify(this.theme) === JSON.stringify(Base) ? "Dark" : "Base"
|
||||
);
|
||||
this.theme = currentTheme;
|
||||
};
|
||||
setTheme = (key) => {
|
||||
let theme = null;
|
||||
switch (key) {
|
||||
case ThemeKeys.Base:
|
||||
case ThemeKeys.BaseStr:
|
||||
theme = ThemeKeys.BaseStr;
|
||||
break;
|
||||
case ThemeKeys.Dark:
|
||||
case ThemeKeys.DarkStr:
|
||||
theme = ThemeKeys.DarkStr;
|
||||
break;
|
||||
case ThemeKeys.System:
|
||||
case ThemeKeys.SystemStr:
|
||||
default:
|
||||
theme =
|
||||
window.matchMedia &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? ThemeKeys.DarkStr
|
||||
: ThemeKeys.BaseStr;
|
||||
}
|
||||
|
||||
setTheme = (theme) => {
|
||||
this.theme = themes[theme];
|
||||
localStorage.setItem("theme", theme);
|
||||
};
|
||||
|
||||
setMailDomainSettings = async (data) => {
|
||||
@ -453,6 +472,10 @@ class SettingsStore {
|
||||
return res;
|
||||
};
|
||||
|
||||
setTenantAlias = (tenantAlias) => {
|
||||
this.tenantAlias = tenantAlias;
|
||||
};
|
||||
|
||||
getIpRestrictions = async () => {
|
||||
const res = await api.settings.getIpRestrictions();
|
||||
this.ipRestrictions = res?.map((el) => el.ip);
|
||||
|
@ -42,10 +42,8 @@ class TfaStore {
|
||||
this.backupCodes = codes;
|
||||
};
|
||||
|
||||
getTfaConfirmLink = async (res) => {
|
||||
if (res) {
|
||||
return await api.settings.getTfaConfirmLink();
|
||||
}
|
||||
getTfaConfirmLink = async () => {
|
||||
return await api.settings.getTfaConfirmLink();
|
||||
};
|
||||
|
||||
getSecretKeyAndQR = async (confirmKey) => {
|
||||
|
@ -48,6 +48,18 @@ class UserStore {
|
||||
this.setIsLoading(false);
|
||||
};
|
||||
|
||||
changeTheme = async (key) => {
|
||||
this.setIsLoading(true);
|
||||
|
||||
const { theme } = await api.people.changeTheme(key);
|
||||
|
||||
this.user.theme = theme;
|
||||
|
||||
this.setIsLoading(false);
|
||||
|
||||
return theme;
|
||||
};
|
||||
|
||||
setUserIsUpdate = (isUpdate) => {
|
||||
//console.log("setUserIsUpdate");
|
||||
this.userIsUpdate = isUpdate;
|
||||
|
@ -324,3 +324,26 @@ export function convertLanguage(key) {
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
import FilesFilter from "../api/files/filter";
|
||||
export function getFolderOptions(folderId, filter) {
|
||||
if (folderId && typeof folderId === "string") {
|
||||
folderId = encodeURIComponent(folderId.replace(/\\\\/g, "\\"));
|
||||
}
|
||||
|
||||
const params =
|
||||
filter && filter instanceof FilesFilter
|
||||
? `${folderId}?${filter.toApiUrlParams()}`
|
||||
: folderId;
|
||||
|
||||
const options = {
|
||||
method: "get",
|
||||
url: `/files/${params}`,
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
export function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
@ -13,21 +13,33 @@ import {
|
||||
StyledAccessRightItemContent,
|
||||
StyledAccessRightItemTitleAndBadge,
|
||||
} from "./styled-accessright.js";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
const AccessRightSelect = ({ options, onSelect, selectedOption, ...props }) => {
|
||||
const AccessRightSelect = ({
|
||||
options,
|
||||
onSelect,
|
||||
advancedOptions,
|
||||
selectedOption,
|
||||
...props
|
||||
}) => {
|
||||
const [currentItem, setCurrentItem] = useState(selectedOption);
|
||||
|
||||
function onSelectCurrentItem(e) {
|
||||
const key = e.currentTarget.dataset.key;
|
||||
const key = +e.currentTarget.dataset.key;
|
||||
const item = options.find((el) => {
|
||||
return el.key === key;
|
||||
});
|
||||
|
||||
if (item) {
|
||||
setCurrentItem(item);
|
||||
onSelect && onSelect(item);
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
setCurrentItem(selectedOption);
|
||||
}, [selectedOption]);
|
||||
|
||||
const formatToAccessRightItem = (data) => {
|
||||
return (
|
||||
<>
|
||||
@ -67,12 +79,15 @@ const AccessRightSelect = ({ options, onSelect, selectedOption, ...props }) => {
|
||||
|
||||
return (
|
||||
<StyledAccessRightWrapper>
|
||||
<StyledAccessRightIcon src={currentItem?.icon} />
|
||||
<ReactSVG className="access-right__icon" src={currentItem?.icon} />
|
||||
<ComboBox
|
||||
advancedOptions={formatToAccessRightItem(options)}
|
||||
advancedOptions={
|
||||
!!advancedOptions ? advancedOptions : formatToAccessRightItem(options)
|
||||
}
|
||||
onSelect={onSelectCurrentItem}
|
||||
directionX="left"
|
||||
directionY="bottom"
|
||||
opened
|
||||
opened={false}
|
||||
noBorder
|
||||
options={[]}
|
||||
scaled={false}
|
||||
@ -92,8 +107,10 @@ AccessRightSelect.propTypes = {
|
||||
options: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
/** Will be triggered whenever an AccessRightSelect is selected option */
|
||||
onSelect: PropTypes.func,
|
||||
/** List of advanced options */
|
||||
advancedOptions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
||||
/** The option that is selected by default */
|
||||
selectedOption: PropTypes.object,
|
||||
};
|
||||
|
||||
export default AccessRightSelect;
|
||||
export default React.memo(AccessRightSelect);
|
||||
|
@ -3,14 +3,28 @@ import Base from "../themes/base";
|
||||
|
||||
const StyledAccessRightWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.access-right__icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
path {
|
||||
fill: ${(props) => props.theme.dropDownItem.icon.color};
|
||||
}
|
||||
}
|
||||
|
||||
.combo-button {
|
||||
padding-left: 4px;
|
||||
}
|
||||
`;
|
||||
StyledAccessRightWrapper.defaultProps = { theme: Base };
|
||||
|
||||
const StyledAccessRightIcon = styled.img`
|
||||
margin-right: 4.18px;
|
||||
margin-right: 4px;
|
||||
`;
|
||||
|
||||
const StyledAccessRightItem = styled.div`
|
||||
width: 424px;
|
||||
width: auto;
|
||||
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
@ -81,8 +81,10 @@ class AvatarEditor extends React.Component {
|
||||
};
|
||||
|
||||
onClose = () => {
|
||||
this.setState({ visible: false });
|
||||
this.props.onClose();
|
||||
if (this.state.visible) {
|
||||
this.setState({ visible: false });
|
||||
this.props.onClose();
|
||||
}
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
@ -94,6 +96,20 @@ class AvatarEditor extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
keyPress = (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
this.onSaveButtonClick();
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
addEventListener("keydown", this.keyPress, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
removeEventListener("keydown", this.keyPress, false);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
displayType,
|
||||
|
@ -56,7 +56,7 @@ class Backdrop extends React.Component {
|
||||
|
||||
modifyClassName = () => {
|
||||
const { className } = this.props;
|
||||
let modifiedClass = "backdrop-active";
|
||||
let modifiedClass = "backdrop-active not-selectable";
|
||||
|
||||
if (className) {
|
||||
if (typeof className !== "string") {
|
||||
|
@ -37,7 +37,14 @@ Button.propTypes = {
|
||||
/** Size of button.
|
||||
|
||||
The normal size equals 36px and 40px in height on the Desktop and Touchcreen devices. */
|
||||
size: PropTypes.oneOf(["extraSmall", "small", "normal", "medium"]),
|
||||
size: PropTypes.oneOf([
|
||||
"extraSmall",
|
||||
"small",
|
||||
"normal",
|
||||
"medium",
|
||||
"normalDesktop",
|
||||
"normalTouchscreen",
|
||||
]),
|
||||
/** Scale width of button to 100% */
|
||||
scale: PropTypes.bool,
|
||||
/** Icon node element */
|
||||
|
@ -156,8 +156,7 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
: props.theme.button.border.base};
|
||||
|
||||
${(props) => props.scale && `width: 100%;`};
|
||||
min-width: ${(props) =>
|
||||
props.minwidth ? props.minwidth : props.theme.button.minWidth[props.size]};
|
||||
min-width: ${(props) => props.minwidth && props.minwidth};
|
||||
|
||||
padding: ${(props) => `${props.theme.button.padding[props.size]}`};
|
||||
|
||||
@ -214,6 +213,8 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
}
|
||||
|
||||
.button-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -222,7 +223,6 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
|
||||
.icon {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
@ -83,7 +83,9 @@ const CatalogItem = (props) => {
|
||||
)}
|
||||
</StyledCatalogItemImg>
|
||||
|
||||
{showText && <StyledCatalogItemText>{text}</StyledCatalogItemText>}
|
||||
{showText && (
|
||||
<StyledCatalogItemText noSelect={true}>{text}</StyledCatalogItemText>
|
||||
)}
|
||||
|
||||
{showBadge && showText && (
|
||||
<StyledCatalogItemBadgeWrapper
|
||||
|
@ -250,6 +250,10 @@ const StyledCatalogItemSibling = styled.div`
|
||||
css`
|
||||
min-height: ${(props) => props.theme.catalogItem.container.tablet.height};
|
||||
max-height: ${(props) => props.theme.catalogItem.container.tablet.height};
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
`}
|
||||
|
||||
${(props) => props.isDragging && draggingSiblingCss}
|
||||
|
@ -62,6 +62,10 @@ class Checkbox extends React.Component {
|
||||
this.props.onChange && this.props.onChange(e);
|
||||
}
|
||||
|
||||
onClick(e) {
|
||||
return e.preventDefault();
|
||||
}
|
||||
|
||||
render() {
|
||||
//console.log("Checkbox render");
|
||||
const {
|
||||
@ -75,39 +79,49 @@ class Checkbox extends React.Component {
|
||||
title,
|
||||
truncate,
|
||||
name,
|
||||
helpButton,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<StyledLabel
|
||||
id={id}
|
||||
style={style}
|
||||
isDisabled={isDisabled}
|
||||
isIndeterminate={isIndeterminate}
|
||||
className={className}
|
||||
title={title}
|
||||
>
|
||||
<HiddenInput
|
||||
name={name}
|
||||
type="checkbox"
|
||||
checked={this.state.checked}
|
||||
<>
|
||||
<StyledLabel
|
||||
id={id}
|
||||
style={style}
|
||||
isDisabled={isDisabled}
|
||||
ref={this.ref}
|
||||
value={value}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
<RenderCheckboxIcon {...this.props} />
|
||||
{this.props.label && (
|
||||
<Text
|
||||
as="span"
|
||||
title={title}
|
||||
isIndeterminate={isIndeterminate}
|
||||
className={className}
|
||||
title={title}
|
||||
>
|
||||
<HiddenInput
|
||||
name={name}
|
||||
type="checkbox"
|
||||
checked={this.state.checked}
|
||||
isDisabled={isDisabled}
|
||||
truncate={truncate}
|
||||
className="checkbox-text"
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
)}
|
||||
</StyledLabel>
|
||||
ref={this.ref}
|
||||
value={value}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
<RenderCheckboxIcon {...this.props} />
|
||||
<div className="wrapper">
|
||||
{this.props.label && (
|
||||
<Text
|
||||
as="span"
|
||||
title={title}
|
||||
isDisabled={isDisabled}
|
||||
truncate={truncate}
|
||||
className="checkbox-text"
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
)}
|
||||
{helpButton && (
|
||||
<span className="help-button" onClick={this.onClick}>
|
||||
{helpButton}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</StyledLabel>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -137,11 +151,16 @@ Checkbox.propTypes = {
|
||||
title: PropTypes.string,
|
||||
/** Disables word wrapping */
|
||||
truncate: PropTypes.bool,
|
||||
/** Help button render */
|
||||
helpButton: PropTypes.any,
|
||||
|
||||
isLogin: PropTypes.bool,
|
||||
};
|
||||
|
||||
Checkbox.defaultProps = {
|
||||
isChecked: false,
|
||||
truncate: false,
|
||||
isLogin: false,
|
||||
};
|
||||
|
||||
export default React.memo(Checkbox);
|
||||
|
@ -3,7 +3,14 @@ import Base from "../themes/base";
|
||||
|
||||
const StyledLabel = styled.label`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
${(props) =>
|
||||
!props.isLogin &&
|
||||
css`
|
||||
align-items: "center";
|
||||
`};
|
||||
|
||||
justify-content: ${(props) => props.isLogin && "center"};
|
||||
position: relative;
|
||||
margin: 0;
|
||||
|
||||
@ -107,11 +114,21 @@ const StyledLabel = styled.label`
|
||||
`}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.checkbox-text {
|
||||
color: ${(props) =>
|
||||
props.isDisabled
|
||||
? props.theme.text.disableColor
|
||||
: props.theme.text.color};
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.help-button {
|
||||
display: inline-block;
|
||||
margin-left: 4px;
|
||||
}
|
||||
`;
|
||||
StyledLabel.defaultProps = { theme: Base };
|
||||
|
@ -83,10 +83,12 @@ class ContextMenu extends Component {
|
||||
|
||||
hide = (e) => {
|
||||
this.currentEvent = e;
|
||||
this.setState({ visible: false, reshow: false, changeView: false }, () => {
|
||||
if (this.props.onHide) {
|
||||
this.props.onHide(this.currentEvent);
|
||||
}
|
||||
|
||||
this.props.onHide && this.props.onHide(e);
|
||||
this.setState({
|
||||
visible: false,
|
||||
reshow: false,
|
||||
changeView: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@ const styledMobileView = css`
|
||||
max-height: ${(props) => props.theme.newContextMenu.devices.maxHeight};
|
||||
left: ${(props) => props.theme.newContextMenu.devices.left};
|
||||
bottom: ${(props) => props.theme.newContextMenu.devices.bottom};
|
||||
border-radius: ${(props) => props.theme.newContextMenu.mobileBorderRadius};
|
||||
`;
|
||||
|
||||
const StyledContextMenu = styled.div`
|
||||
|
@ -62,7 +62,7 @@ class DropDown extends React.PureComponent {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.open !== prevProps.open) {
|
||||
if (this.props.open) {
|
||||
this.props.enableOnClickOutside();
|
||||
!isMobile && this.props.enableOnClickOutside(); //fixed main-button-mobile click, remove !isMobile if have dd problem
|
||||
this.bindDocumentResizeListener();
|
||||
if (this.props.isDefaultMode) {
|
||||
return this.checkPositionPortal();
|
||||
@ -114,13 +114,14 @@ class DropDown extends React.PureComponent {
|
||||
|
||||
const rects = this.dropDownRef.current.getBoundingClientRect();
|
||||
const parentRects = forwardedRef?.current?.getBoundingClientRect();
|
||||
|
||||
const container = DomHelpers.getViewport();
|
||||
|
||||
const dimensions = parentRects
|
||||
? {
|
||||
toTopCorner: parentRects.top,
|
||||
parentHeight: parentRects.height,
|
||||
containerHeight: parentRects.top,
|
||||
containerHeight: !parentRects.top,
|
||||
}
|
||||
: {
|
||||
toTopCorner: rects.top,
|
||||
@ -352,6 +353,7 @@ DropDownContainer.propTypes = {
|
||||
isDefaultMode: PropTypes.bool,
|
||||
/** Needed to open correctly people and group selector when the section width is small */
|
||||
smallSectionWidth: PropTypes.bool,
|
||||
/** It is necessary when we explicitly set the direction, disables check position */
|
||||
fixedDirection: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
@ -58,8 +58,7 @@ const EmptyContentBody = styled.div`
|
||||
}
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
min-width: 343px;
|
||||
@media (max-width: 428px) {
|
||||
grid-template-areas:
|
||||
"img img img"
|
||||
"headerText headerText headerText"
|
||||
|
@ -29,6 +29,8 @@ class FieldContainer extends React.Component {
|
||||
errorMessage,
|
||||
errorColor,
|
||||
errorMessageWidth,
|
||||
offsetRight,
|
||||
tooltipMaxWidth,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -53,7 +55,9 @@ class FieldContainer extends React.Component {
|
||||
<HelpButton
|
||||
tooltipContent={tooltipContent}
|
||||
place={place}
|
||||
offsetRight={offsetRight}
|
||||
helpButtonHeaderContent={helpButtonHeaderContent}
|
||||
tooltipMaxWidth={tooltipMaxWidth}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -109,6 +113,8 @@ FieldContainer.propTypes = {
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
offsetRight: PropTypes.number,
|
||||
tooltipMaxWidth: PropTypes.string,
|
||||
};
|
||||
|
||||
FieldContainer.defaultProps = {
|
||||
@ -116,6 +122,7 @@ FieldContainer.defaultProps = {
|
||||
labelVisible: true,
|
||||
maxLabelWidth: "110px",
|
||||
errorMessageWidth: "293px",
|
||||
offsetRight: 0,
|
||||
};
|
||||
|
||||
export default FieldContainer;
|
||||
|
@ -106,6 +106,7 @@ class HelpButton extends React.Component {
|
||||
offsetLeft={offsetLeft}
|
||||
afterShow={this.afterShow}
|
||||
afterHide={this.afterHide}
|
||||
maxWidth={tooltipMaxWidth}
|
||||
>
|
||||
{tooltipContent}
|
||||
</Tooltip>
|
||||
|
@ -84,7 +84,8 @@ const StyledLinkWithDropdown = styled(SimpleLinkWithDropdown)`
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
padding-right: ${(props) => props.theme.linkWithDropdown.paddingRight};
|
||||
|
||||
|
@ -16,7 +16,7 @@ import IconButton from "../icon-button";
|
||||
import Button from "../button";
|
||||
import Text from "../text";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import { isMobile, isTablet } from "react-device-detect";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import Backdrop from "../backdrop";
|
||||
|
||||
const ProgressBarMobile = ({
|
||||
@ -98,7 +98,7 @@ const MainButtonMobile = (props) => {
|
||||
|
||||
const [isOpen, setIsOpen] = useState(opened);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [height, setHeight] = useState("90vh");
|
||||
const [height, setHeight] = useState("calc(100% - 48px)");
|
||||
|
||||
const divRef = useRef();
|
||||
|
||||
@ -111,7 +111,10 @@ const MainButtonMobile = (props) => {
|
||||
useEffect(() => {
|
||||
let height =
|
||||
divRef?.current?.getBoundingClientRect()?.height || window.innerHeight;
|
||||
height >= window.innerHeight ? setHeight("90vh") : setHeight(height + "px");
|
||||
|
||||
height >= window.innerHeight
|
||||
? setHeight("calc(100% - 48px)")
|
||||
: setHeight(height + "px");
|
||||
}, [isOpen, isOpenButton, window.innerHeight, isUploading]);
|
||||
|
||||
const ref = useRef();
|
||||
@ -127,7 +130,6 @@ const MainButtonMobile = (props) => {
|
||||
};
|
||||
|
||||
const onMainButtonClick = (e) => {
|
||||
if (isOpen && ref.current.contains(e.target)) return;
|
||||
toggle(!isOpen);
|
||||
};
|
||||
|
||||
@ -191,8 +193,8 @@ const MainButtonMobile = (props) => {
|
||||
/>
|
||||
))}
|
||||
</StyledProgressContainer>
|
||||
<StyledButtonOptions isOpenButton={isOpenButton}>
|
||||
{isOpenButton && buttonOptions
|
||||
<StyledButtonOptions>
|
||||
{buttonOptions
|
||||
? buttonOptions.map((option) =>
|
||||
option.isSeparator ? (
|
||||
<div key={option.key} className="separator-wrapper">
|
||||
@ -213,20 +215,6 @@ const MainButtonMobile = (props) => {
|
||||
)
|
||||
: ""}
|
||||
</StyledButtonOptions>
|
||||
{withButton && (
|
||||
<StyledButtonWrapper
|
||||
isUploading={isUploading}
|
||||
isOpenButton={isOpenButton}
|
||||
>
|
||||
<Button
|
||||
label={title}
|
||||
className="action-mobile-button"
|
||||
primary
|
||||
size="medium"
|
||||
onClick={onUploadClick}
|
||||
/>
|
||||
</StyledButtonWrapper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -249,13 +237,15 @@ const MainButtonMobile = (props) => {
|
||||
manualWidth={manualWidth || "400px"}
|
||||
directionY="top"
|
||||
directionX="right"
|
||||
isMobile={isMobile || isTablet}
|
||||
isMobile={isMobile}
|
||||
fixedDirection={true}
|
||||
heightProp={height}
|
||||
sectionWidth={sectionWidth}
|
||||
isDefaultMode={false}
|
||||
>
|
||||
{isMobile || isTablet ? (
|
||||
{isMobile ? (
|
||||
<Scrollbar
|
||||
style={{ position: "absolute" }}
|
||||
scrollclass="section-scroll"
|
||||
stype="mediumBlack"
|
||||
ref={dropDownRef}
|
||||
|
@ -12,6 +12,8 @@ const StyledFloatingButton = styled(FloatingButton)`
|
||||
z-index: 1010;
|
||||
background: ${(props) => props.theme.mainButtonMobile.buttonColor} !important;
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
|
||||
.circle__mask + div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -56,7 +58,9 @@ const StyledFloatingButton = styled(FloatingButton)`
|
||||
StyledFloatingButton.defaultProps = { theme: Base };
|
||||
|
||||
const mobileDropDown = css`
|
||||
width: ${(props) => props.theme.mainButtonMobile.dropDown.mobile.width};
|
||||
@media (max-width: 428px) {
|
||||
width: ${(props) => props.theme.mainButtonMobile.dropDown.mobile.width};
|
||||
}
|
||||
|
||||
right: ${(props) => props.theme.mainButtonMobile.dropDown.mobile.right};
|
||||
bottom: ${(props) => props.theme.mainButtonMobile.dropDown.mobile.bottom};
|
||||
@ -65,7 +69,7 @@ const mobileDropDown = css`
|
||||
const StyledDropDown = styled(DropDown)`
|
||||
position: ${(props) => props.theme.mainButtonMobile.dropDown.position};
|
||||
width: ${(props) => props.theme.mainButtonMobile.dropDown.width};
|
||||
max-width: calc(100vw - 64px);
|
||||
max-width: calc(100vw - 48px);
|
||||
|
||||
right: ${(props) => props.theme.mainButtonMobile.dropDown.right};
|
||||
bottom: ${(props) => props.theme.mainButtonMobile.dropDown.bottom};
|
||||
@ -134,7 +138,6 @@ const StyledDropDownItem = styled(DropDownItem)`
|
||||
`;
|
||||
|
||||
const StyledButtonOptions = styled.div`
|
||||
display: ${(props) => !props.isOpenButton && "none"};
|
||||
padding: 16px 0;
|
||||
background-color: ${(props) =>
|
||||
props.theme.mainButtonMobile.buttonOptions.backgroundColor};
|
||||
|
@ -81,6 +81,10 @@ class ModalDialog extends React.Component {
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.throttledResize);
|
||||
window.addEventListener("keyup", this.onKeyPress);
|
||||
|
||||
window.onpopstate = () => {
|
||||
this.props.onClose();
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -163,21 +167,29 @@ class ModalDialog extends React.Component {
|
||||
<Loaders.DialogLoader bodyHeight={modalLoaderBodyHeight} />
|
||||
) : (
|
||||
<>
|
||||
<StyledHeader>
|
||||
<Heading className="heading" size="medium" truncate={true}>
|
||||
{header ? header.props.children : null}
|
||||
</Heading>
|
||||
{!withoutCloseButton && (
|
||||
<CloseButton
|
||||
className="modal-dialog-button_close"
|
||||
onClick={onClose}
|
||||
></CloseButton>
|
||||
)}
|
||||
</StyledHeader>
|
||||
{header && (
|
||||
<StyledHeader>
|
||||
<Heading
|
||||
className="heading"
|
||||
size="medium"
|
||||
truncate={true}
|
||||
>
|
||||
{header ? header.props.children : null}
|
||||
</Heading>
|
||||
{!withoutCloseButton && (
|
||||
<CloseButton
|
||||
className="modal-dialog-button_close"
|
||||
onClick={onClose}
|
||||
></CloseButton>
|
||||
)}
|
||||
</StyledHeader>
|
||||
)}
|
||||
<BodyBox paddingProp={modalBodyPadding}>
|
||||
{body ? body.props.children : null}
|
||||
</BodyBox>
|
||||
<Box>{footer ? footer.props.children : null}</Box>
|
||||
<Box className="modal-dialog-modal-footer">
|
||||
{footer ? footer.props.children : null}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appserver/components",
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "echo 'skip it'",
|
||||
|
@ -0,0 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_20597_65864)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.84646 0.979492L5.22299 14.5025L7.15485 15.0201L10.7783 1.49713L8.84646 0.979492ZM2.41419 7.99916L5.20702 5.20614L3.79276 3.79197L0.292868 7.2921C-0.0976332 7.68263 -0.0976212 8.31578 0.292895 8.7063L3.79278 12.2062L5.20699 10.7919L2.41419 7.99916ZM13.5857 8.00004L10.7928 5.20714L12.207 3.79292L15.707 7.29293C15.8945 7.48047 15.9999 7.73482 15.9999 8.00004C15.9999 8.26526 15.8945 8.51961 15.707 8.70715L12.2065 12.2076L10.7923 10.7934L13.5857 8.00004Z" fill="#333333"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_20597_65864">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 777 B |
@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.85498 16L1.15188 16C0.518827 16 0.00382324 15.485 0.00378789 14.8519L0.00378713 6.14776C0.00378708 5.51468 0.518826 4.99964 1.15187 4.99964L4.01036 4.99964L4.01036 9.96112C4.01036 11.1721 4.75801 11.9963 5.96898 11.9963L11.0031 11.9963L11.0031 14.8519C11.0031 15.485 10.4881 16 9.85498 16ZM14.8703 11.0013L6.12976 11.0013C5.50682 11.0013 4.99997 10.4945 5 9.87155L5 1.12969C5 0.506788 5.50679 9.17346e-07 6.12973 8.62887e-07L14.8703 9.87639e-08C15.4932 4.43048e-08 16 0.506787 16 1.12973L16 9.87155C16 10.4945 15.4932 11.0013 14.8703 11.0013Z" fill="#A3A9AE"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.14502 -1.07443e-06L14.8481 -2.59613e-06C15.4812 -2.70681e-06 15.9962 0.515037 15.9962 1.14808L15.9962 9.85224C15.9962 10.4853 15.4812 11.0004 14.8481 11.0004L11.9896 11.0004L11.9896 6.03888C11.9896 4.82791 11.242 4.00369 10.031 4.00369L4.99694 4.00369L4.99694 1.14809C4.99693 0.515038 5.51194 -9.63738e-07 6.14502 -1.07443e-06ZM1.12973 4.99872L9.87024 4.99872C10.4932 4.99872 11 5.50551 11 6.12845L11 14.8703C11 15.4932 10.4932 16 9.87028 16L1.12973 16C0.50679 16 3.70837e-05 15.4932 2.6e-06 14.8703L1.07154e-06 6.12845C9.62618e-07 5.50551 0.506823 4.99872 1.12973 4.99872Z" fill="#A3A9AE"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 747 B |
@ -108,7 +108,6 @@ RadioButtonGroup.defaultProps = {
|
||||
selected: undefined,
|
||||
spacing: "15px",
|
||||
orientation: "horizontal",
|
||||
width: "100%",
|
||||
};
|
||||
|
||||
export default RadioButtonGroup;
|
||||
|
@ -17,7 +17,7 @@ const StyledDiv = styled(ClearDiv)`
|
||||
`) ||
|
||||
(props.orientation === "vertical" &&
|
||||
css`
|
||||
display: block;
|
||||
display: inline-block;
|
||||
`)};
|
||||
|
||||
width: ${(props) => props.width};
|
||||
|
@ -47,6 +47,7 @@ class SaveCancelButtons extends React.Component {
|
||||
isFirstWelcomePageSettings,
|
||||
className,
|
||||
id,
|
||||
isSaving,
|
||||
} = this.props;
|
||||
|
||||
const cancelButtonDisabled =
|
||||
@ -69,11 +70,12 @@ class SaveCancelButtons extends React.Component {
|
||||
onClick={onSaveClick}
|
||||
label={saveButtonLabel}
|
||||
minwidth={displaySettings && "auto"}
|
||||
isLoading={isSaving}
|
||||
/>
|
||||
<Button
|
||||
className="cancel-button"
|
||||
size="normal"
|
||||
isDisabled={cancelButtonDisabled}
|
||||
isDisabled={cancelButtonDisabled || isSaving}
|
||||
onClick={onCancelClick}
|
||||
label={cancelButtonLabel}
|
||||
minwidth={displaySettings && "auto"}
|
||||
@ -109,6 +111,7 @@ SaveCancelButtons.propTypes = {
|
||||
hasScroll: PropTypes.bool,
|
||||
minwidth: PropTypes.string,
|
||||
isFirstWelcomePageSettings: PropTypes.string,
|
||||
isSaving: PropTypes.bool,
|
||||
};
|
||||
|
||||
SaveCancelButtons.defaultProps = {
|
||||
|
@ -39,7 +39,7 @@ export class CustomScrollbars extends React.Component {
|
||||
}
|
||||
|
||||
CustomScrollbars.defaultProps = {
|
||||
stype: "smallBlack",
|
||||
stype: "mediumBlack",
|
||||
};
|
||||
|
||||
const CustomScrollbarsVirtualList = React.forwardRef((props, ref) => (
|
||||
|
@ -114,7 +114,7 @@ Scrollbar.propTypes = {
|
||||
};
|
||||
|
||||
Scrollbar.defaultProps = {
|
||||
stype: "smallBlack",
|
||||
stype: "mediumBlack",
|
||||
};
|
||||
|
||||
export default Scrollbar;
|
||||
|
@ -5,7 +5,7 @@ import StyledButton from "./styled-selector-add-button";
|
||||
import IconButton from "../icon-button";
|
||||
|
||||
const SelectorAddButton = (props) => {
|
||||
const { isDisabled, title, className, id, style } = props;
|
||||
const { isDisabled, title, className, id, style, iconName } = props;
|
||||
|
||||
const onClick = (e) => {
|
||||
!isDisabled && props.onClick && props.onClick(e);
|
||||
@ -22,7 +22,7 @@ const SelectorAddButton = (props) => {
|
||||
>
|
||||
<IconButton
|
||||
size={14}
|
||||
iconName="/static/images/actions.header.touch.react.svg"
|
||||
iconName={iconName}
|
||||
isFill={true}
|
||||
isDisabled={isDisabled}
|
||||
isClickable={!isDisabled}
|
||||
@ -44,10 +44,13 @@ SelectorAddButton.propTypes = {
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Specifies the icon name */
|
||||
iconName: PropTypes.string,
|
||||
};
|
||||
|
||||
SelectorAddButton.defaultProps = {
|
||||
isDisabled: false,
|
||||
iconName: "/static/images/actions.header.touch.react.svg",
|
||||
};
|
||||
|
||||
export default SelectorAddButton;
|
||||
|
@ -12,8 +12,9 @@ import {
|
||||
StyledSubmenuItems,
|
||||
StyledSubmenuItemText,
|
||||
} from "./styled-submenu";
|
||||
import LoaderSubmenu from "./loader";
|
||||
|
||||
const Submenu = ({ data, startSelect = 0, onSelect, ...rest }) => {
|
||||
const Submenu = ({ data, startSelect = 0, onSelect, isLoading, ...rest }) => {
|
||||
if (!data) return null;
|
||||
|
||||
const [currentItem, setCurrentItem] = useState(
|
||||
@ -74,29 +75,43 @@ const Submenu = ({ data, startSelect = 0, onSelect, ...rest }) => {
|
||||
|
||||
return (
|
||||
<StyledSubmenu {...rest}>
|
||||
<StyledSubmenuItems ref={submenuItemsRef} role="list">
|
||||
{data.map((d) => {
|
||||
const isActive = d.id === currentItem.id;
|
||||
|
||||
return (
|
||||
<StyledSubmenuItem key={d.id} id={d.id} onClick={selectSubmenuItem}>
|
||||
<StyledSubmenuItemText>
|
||||
<Text
|
||||
color={isActive ? "#316DAA" : "#657077"}
|
||||
fontSize="13px"
|
||||
fontWeight="600"
|
||||
truncate={false}
|
||||
>
|
||||
{d.name}
|
||||
</Text>
|
||||
</StyledSubmenuItemText>
|
||||
<StyledSubmenuItemLabel color={isActive ? "#316DAA" : "none"} />
|
||||
</StyledSubmenuItem>
|
||||
);
|
||||
})}
|
||||
</StyledSubmenuItems>
|
||||
<StyledSubmenuBottomLine />
|
||||
{isLoading ? (
|
||||
<LoaderSubmenu />
|
||||
) : (
|
||||
<>
|
||||
<div className="sticky">
|
||||
<StyledSubmenuItems ref={submenuItemsRef} role="list">
|
||||
{data.map((d) => {
|
||||
const isActive = d.id === currentItem.id;
|
||||
|
||||
return (
|
||||
<StyledSubmenuItem
|
||||
key={d.id}
|
||||
id={d.id}
|
||||
onClick={selectSubmenuItem}
|
||||
>
|
||||
<StyledSubmenuItemText>
|
||||
<Text
|
||||
color={isActive ? "#316DAA" : "#657077"}
|
||||
fontSize="13px"
|
||||
fontWeight="600"
|
||||
truncate={false}
|
||||
>
|
||||
{d.name}
|
||||
</Text>
|
||||
</StyledSubmenuItemText>
|
||||
<StyledSubmenuItemLabel
|
||||
color={isActive ? "#316DAA" : "none"}
|
||||
/>
|
||||
</StyledSubmenuItem>
|
||||
);
|
||||
})}
|
||||
</StyledSubmenuItems>
|
||||
<StyledSubmenuBottomLine />
|
||||
</div>
|
||||
<div className="sticky-indent"></div>
|
||||
</>
|
||||
)}
|
||||
<StyledSubmenuContentWrapper>
|
||||
{currentItem.content}
|
||||
</StyledSubmenuContentWrapper>
|
||||
@ -108,6 +123,7 @@ Submenu.propTypes = {
|
||||
data: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired,
|
||||
startSelect: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
onSelect: PropTypes.func,
|
||||
isLoading: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Submenu;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { isTablet } from "react-device-detect";
|
||||
|
@ -16,12 +16,23 @@ export const StyledSubmenu = styled.div`
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: ${(props) => props.theme.submenu.backgroundColor};
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.sticky-indent {
|
||||
height: 15px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledSubmenuBottomLine = styled.div`
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
margin: -1px 0 15px 0;
|
||||
margin-top: -1px;
|
||||
background: ${(props) => props.theme.submenu.lineColor};
|
||||
`;
|
||||
|
||||
|
@ -77,13 +77,21 @@ StyledButton.defaultProps = { theme: Base };
|
||||
const GroupMenuItem = ({ item }) => {
|
||||
const { label, disabled, onClick, iconUrl, title } = item;
|
||||
return (
|
||||
<StyledButton
|
||||
label={label}
|
||||
title={title || label}
|
||||
isDisabled={disabled}
|
||||
onClick={onClick}
|
||||
icon={<ReactSVG src={iconUrl} className="combo-button_selected-icon" />}
|
||||
/>
|
||||
<>
|
||||
{disabled ? (
|
||||
<></>
|
||||
) : (
|
||||
<StyledButton
|
||||
label={label}
|
||||
title={title || label}
|
||||
isDisabled={disabled}
|
||||
onClick={onClick}
|
||||
icon={
|
||||
<ReactSVG src={iconUrl} className="combo-button_selected-icon" />
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -41,11 +41,18 @@ const StyledTableContainer = styled.div`
|
||||
props.theme.tableContainer.header.borderImageSource};
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.lengthen-header {
|
||||
border-bottom: ${(props) => props.theme.tableContainer.header.borderBottom};
|
||||
border-image-source: none;
|
||||
}
|
||||
|
||||
.hotkeys-lengthen-header {
|
||||
border-bottom: ${(props) =>
|
||||
props.theme.tableContainer.header.hotkeyBorderBottom};
|
||||
border-image-source: none;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -79,7 +86,7 @@ const StyledTableGroupMenu = styled.div`
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
z-index: 199;
|
||||
height: 53px;
|
||||
height: 52px;
|
||||
box-shadow: ${(props) => props.theme.tableContainer.groupMenu.boxShadow};
|
||||
border-radius: 0px 0px 6px 6px;
|
||||
margin: 0;
|
||||
|
@ -168,7 +168,7 @@ class TabContainer extends Component {
|
||||
selected={activeTab === index}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
<Text className="title_style" fontSize="13px">
|
||||
<Text fontWeight={600} className="title_style" fontSize="13px">
|
||||
{item.title}
|
||||
</Text>
|
||||
</Label>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user