diff --git a/build/install/win/Apache Kafka.aip b/build/install/win/Apache Kafka.aip index 58d6315394..117fdc8e45 100644 --- a/build/install/win/Apache Kafka.aip +++ b/build/install/win/Apache Kafka.aip @@ -1,11 +1,15 @@ - + + + - + + + @@ -33,6 +37,8 @@ + + @@ -128,6 +134,7 @@ + @@ -157,6 +164,8 @@ + + @@ -171,7 +180,7 @@ - + @@ -191,8 +200,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/install/win/Apache ZooKeeper.aip b/build/install/win/Apache ZooKeeper.aip index 264faa65a4..dd628c7f37 100644 --- a/build/install/win/Apache ZooKeeper.aip +++ b/build/install/win/Apache ZooKeeper.aip @@ -1,10 +1,14 @@ - + + + - + + + @@ -29,6 +33,8 @@ + + @@ -99,6 +105,7 @@ + @@ -116,6 +123,8 @@ + + @@ -126,7 +135,7 @@ - + @@ -144,8 +153,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/install/win/AppServer.aip b/build/install/win/AppServer.aip index 66777e5387..0cf77b63e8 100644 --- a/build/install/win/AppServer.aip +++ b/build/install/win/AppServer.aip @@ -1,9 +1,9 @@ - + - + @@ -28,6 +28,10 @@ + + + + @@ -36,8 +40,8 @@ - - + + @@ -74,6 +78,10 @@ + + + + @@ -176,11 +184,11 @@ - + - + @@ -213,22 +221,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -243,6 +251,7 @@ + @@ -254,9 +263,9 @@ - + - + @@ -265,7 +274,23 @@ + + + + + + + + + + + + + + + + @@ -297,14 +322,29 @@ + + + + + + + + + + + + + + + - - + + - + @@ -325,40 +365,75 @@ - - + + - + - - + + - - - + + + - + - - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -369,18 +444,22 @@ - - - - - + + + + + + + + + @@ -427,13 +506,19 @@ - + + + + + + + @@ -527,12 +612,12 @@ - - - - - - + + + + + + @@ -654,10 +739,10 @@ - - - - + + + + @@ -665,7 +750,7 @@ - + diff --git a/build/install/win/CustomActions/C#/Utils/CustomAction.config b/build/install/win/CustomActions/C#/Utils/CustomAction.config new file mode 100644 index 0000000000..07a5c9baa3 --- /dev/null +++ b/build/install/win/CustomActions/C#/Utils/CustomAction.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/build/install/win/CustomActions/C#/Utils/CustomAction.cs b/build/install/win/CustomActions/C#/Utils/CustomAction.cs new file mode 100644 index 0000000000..45b43184c3 --- /dev/null +++ b/build/install/win/CustomActions/C#/Utils/CustomAction.cs @@ -0,0 +1,20 @@ +using System; +using System.Net.Sockets; +using Microsoft.Deployment.WindowsInstaller; + +namespace Utils +{ + public class CustomActions + { + [CustomAction] + public static ActionResult CheckTCPAvailability(Session session) + { + string HOST = session.CustomActionData["HOST"]; + string PORT = session.CustomActionData["PORT"]; + string OUTPUT = session.CustomActionData["OUTPUT"]; + var success = new TcpClient().BeginConnect(HOST, Convert.ToInt32(PORT), null, null).AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1)); + session[OUTPUT] = success.ToString(); + return ActionResult.Success; + } + } +} diff --git a/build/install/win/CustomActions/C#/Utils/Properties/AssemblyInfo.cs b/build/install/win/CustomActions/C#/Utils/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1c22b2f432 --- /dev/null +++ b/build/install/win/CustomActions/C#/Utils/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Utils")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Utils")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("31f44d45-4371-4b33-a846-2e3b78131469")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/build/install/win/CustomActions/C#/Utils/Utils.csproj b/build/install/win/CustomActions/C#/Utils/Utils.csproj new file mode 100644 index 0000000000..2506c1d8be --- /dev/null +++ b/build/install/win/CustomActions/C#/Utils/Utils.csproj @@ -0,0 +1,53 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {F149436D-C079-4011-88D2-B45167C81595} + Library + Properties + Utils + Utils + v4.5 + 512 + $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + True + + + + + + + + + + \ No newline at end of file diff --git a/build/install/win/build-batch.bat b/build/install/win/build-batch.bat index e3bbbf6f2d..1ef7d11794 100644 --- a/build/install/win/build-batch.bat +++ b/build/install/win/build-batch.bat @@ -1,3 +1,6 @@ +REM echo ######## Set variables ######## +set "msbuild4="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"" + REM echo ######## Extracting and preparing files to build ######## %sevenzip% x build\install\win\nginx-1.21.1.zip -o"build\install\win\Files" -y xcopy "build\install\win\Files\nginx-1.21.1" "build\install\win\Files\nginx" /s /y /b /i @@ -25,6 +28,12 @@ copy "build\install\win\kafka-zookeeper\zookeeper\conf\zoo_sample.cfg" "build\in 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 +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 + REM echo ######## Edit zookeeper/kafka cfg and proprties files ######## %sed% -i "s/\(dataDir\).*/\1=.\/..\/zookeeper\/Data/g" build/install/win/kafka-zookeeper/zookeeper/conf/zoo.cfg %sed% -i "s/\(log.dirs\)=.*/\1=kafka-logs/g" build/install/win/kafka-zookeeper/kafka/config/server.properties @@ -74,4 +83,5 @@ REM echo ######## Build MySQL Server Installer ######## iscc "build\install\win\MySQL Server Installer Runner.iss" REM echo ######## Build AppServer package ######## +%AdvancedInstaller% /edit build\install\win\AppServer.aip /SetVersion %BUILD_VERSION%.%BUILD_NUMBER% %AdvancedInstaller% /rebuild build\install\win\AppServer.aip diff --git a/common/ASC.Api.Core/Middleware/IpSecurityFilter.cs b/common/ASC.Api.Core/Middleware/IpSecurityFilter.cs index 0b8741c2e5..d919640712 100644 --- a/common/ASC.Api.Core/Middleware/IpSecurityFilter.cs +++ b/common/ASC.Api.Core/Middleware/IpSecurityFilter.cs @@ -3,6 +3,7 @@ using ASC.Common; using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Common.Settings; using ASC.IPSecurity; using Microsoft.AspNetCore.Mvc; @@ -19,16 +20,18 @@ namespace ASC.Api.Core.Middleware public IpSecurityFilter( IOptionsMonitor options, AuthContext authContext, - IPSecurity.IPSecurity IPSecurity) + IPSecurity.IPSecurity IPSecurity, + SettingsManager settingsManager) { log = options.CurrentValue; AuthContext = authContext; this.IPSecurity = IPSecurity; + SettingsManager = settingsManager; } private AuthContext AuthContext { get; } - public IPRestrictionsSettings IPRestrictionsSettings { get; } private IPSecurity.IPSecurity IPSecurity { get; } + private SettingsManager SettingsManager { get; } public void OnResourceExecuted(ResourceExecutedContext context) { @@ -36,11 +39,17 @@ namespace ASC.Api.Core.Middleware public void OnResourceExecuting(ResourceExecutingContext context) { - if (AuthContext.IsAuthenticated && !IPSecurity.Verify()) + + if (AuthContext.IsAuthenticated) { - context.Result = new StatusCodeResult((int)HttpStatusCode.Forbidden); - log.WarnFormat("IPSecurity: user {0}", AuthContext.CurrentAccount.ID); - return; + var enable = SettingsManager.Load().Enable; + + if (enable && !IPSecurity.Verify()) + { + context.Result = new StatusCodeResult((int)HttpStatusCode.Forbidden); + log.WarnFormat("IPSecurity: user {0}", AuthContext.CurrentAccount.ID); + return; + } } } } diff --git a/common/ASC.IPSecurity/IPSecurity.cs b/common/ASC.IPSecurity/IPSecurity.cs index 0153b97949..24e803d78b 100644 --- a/common/ASC.IPSecurity/IPSecurity.cs +++ b/common/ASC.IPSecurity/IPSecurity.cs @@ -25,8 +25,10 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Net; +using System.Net.Sockets; using System.Web; using ASC.Common; @@ -55,6 +57,7 @@ namespace ASC.IPSecurity private SettingsManager SettingsManager { get; } private readonly string CurrentIpForTest; + private readonly string MyNetworks; public IPSecurity( IConfiguration configuration, @@ -72,6 +75,7 @@ namespace ASC.IPSecurity IPRestrictionsService = iPRestrictionsService; SettingsManager = settingsManager; CurrentIpForTest = configuration["ipsecurity:test"]; + MyNetworks = configuration["ipsecurity:mynetworks"]; var hideSettings = (configuration["web:hide-settings"] ?? "").Split(new[] { ',', ';', ' ' }); IpSecurityEnabled = !hideSettings.Contains("IpSecurity", StringComparer.CurrentCultureIgnoreCase); } @@ -109,6 +113,10 @@ namespace ASC.IPSecurity { return true; } + if (IsMyNetwork(ips)) + { + return true; + } } catch (Exception ex) { @@ -140,5 +148,42 @@ namespace ASC.IPSecurity var portIdx = ip.IndexOf(':'); return portIdx > 0 ? ip.Substring(0, portIdx) : ip; } + + private bool IsMyNetwork(string[] ips) + { + try + { + if (!string.IsNullOrEmpty(MyNetworks)) + { + var myNetworkIps = MyNetworks.Split(new[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries); + + if (ips.Any(requestIp => myNetworkIps.Any(ipAddress => MatchIPs(GetIpWithoutPort(requestIp), ipAddress)))) + { + return true; + } + } + + var hostName = Dns.GetHostName(); + var hostAddresses = Dns.GetHostAddresses(Dns.GetHostName()); + + var localIPs = new List { IPAddress.IPv6Loopback, IPAddress.Loopback }; + + localIPs.AddRange(hostAddresses.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6)); + + foreach (var ipAddress in localIPs) + { + if (ips.Contains(ipAddress.ToString())) + { + return true; + } + } + } + catch (Exception ex) + { + Log.ErrorFormat("Can't verify local network from request with IP-address: {0}", string.Join(",", ips), ex); + } + + return false; + } } } \ No newline at end of file diff --git a/packages/asc-web-common/api/settings/index.js b/packages/asc-web-common/api/settings/index.js index a893900d9c..e9ffee5388 100644 --- a/packages/asc-web-common/api/settings/index.js +++ b/packages/asc-web-common/api/settings/index.js @@ -69,6 +69,13 @@ export function setIpRestrictions(data) { }); } +export function getIpRestrictionsEnable() { + return request({ + method: "get", + url: "/settings/iprestrictions/settings", + }); +} + export function setIpRestrictionsEnable(data) { return request({ method: "put", diff --git a/packages/asc-web-common/components/Article/index.js b/packages/asc-web-common/components/Article/index.js index 02c51adc93..81770240c9 100644 --- a/packages/asc-web-common/components/Article/index.js +++ b/packages/asc-web-common/components/Article/index.js @@ -31,6 +31,7 @@ const Article = ({ toggleShowText, toggleArticleOpen, setIsMobileArticle, + isLoading, children, ...rest }) => { @@ -115,7 +116,11 @@ const Article = ({ className="resizable-block" handleWrapperClass="resizable-border not-selectable" > - + {articleHeaderContent ? articleHeaderContent.props.children : null} {articleMainButtonContent && !isMobileOnly && !isMobileUtils() ? ( @@ -123,7 +128,7 @@ const Article = ({ {articleMainButtonContent.props.children} ) : null} - + {articleBodyContent ? articleBodyContent.props.children : null} diff --git a/packages/asc-web-common/components/Article/styled-article.js b/packages/asc-web-common/components/Article/styled-article.js index 4937e7b46b..246309a5e3 100644 --- a/packages/asc-web-common/components/Article/styled-article.js +++ b/packages/asc-web-common/components/Article/styled-article.js @@ -142,10 +142,18 @@ const StyledArticleHeader = styled.div` justify-content: flex-start; align-items: center; + .loader { + padding-top: 2px; + } + @media ${tablet} { padding: 16px 16px 17px; margin: 0; justify-content: ${(props) => (props.showText ? "flex-start" : "center")}; + .loader { + padding-top: 5px; + padding-bottom: 7px; + } } @media ${mobile} { @@ -159,6 +167,10 @@ const StyledArticleHeader = styled.div` padding: 16px 16px 17px; justify-content: ${(props) => (props.showText ? "flex-start" : "center")}; margin: 0; + .loader { + padding-top: 5px; + padding-bottom: 7px; + } `} ${isMobileOnly && diff --git a/packages/asc-web-common/components/Article/sub-components/article-body-loader.js b/packages/asc-web-common/components/Article/sub-components/article-body-loader.js new file mode 100644 index 0000000000..af4ef2c62b --- /dev/null +++ b/packages/asc-web-common/components/Article/sub-components/article-body-loader.js @@ -0,0 +1,40 @@ +import React from "react"; +import styled from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; +import { isTablet as isTabletUtils } from "@appserver/components/utils/device"; +import { isTablet } from "react-device-detect"; + +const StyledLoader = styled.div` + padding: 0px 16px 0px; + + .loader { + display: block; + width: 20px; + padding-bottom: 16px; + } + + @media (min-width: 1024px) { + padding: 0px 20px 0px; + margin-top: -7px; + + .loader { + width: 216px; + padding-bottom: 12px; + } + } +`; + +const LoaderArticleBody = () => { + const heightLoader = isTabletUtils() || isTablet ? "20px" : "24px"; + return ( + + + + + + + + ); +}; + +export default LoaderArticleBody; diff --git a/packages/asc-web-common/components/Article/sub-components/article-body.js b/packages/asc-web-common/components/Article/sub-components/article-body.js index 7e2bbb5397..66320eb02c 100644 --- a/packages/asc-web-common/components/Article/sub-components/article-body.js +++ b/packages/asc-web-common/components/Article/sub-components/article-body.js @@ -1,8 +1,10 @@ import React from "react"; import Scrollbar from "@appserver/components/scrollbar"; - -const ArticleBody = ({ children }) => { - return ( +import LoaderArticleBody from "./article-body-loader"; +const ArticleBody = ({ children, isLoading = false }) => { + return isLoading ? ( + + ) : ( {children} diff --git a/packages/asc-web-common/components/Article/sub-components/article-header.js b/packages/asc-web-common/components/Article/sub-components/article-header.js index 88020dfca7..501b7211ee 100644 --- a/packages/asc-web-common/components/Article/sub-components/article-header.js +++ b/packages/asc-web-common/components/Article/sub-components/article-header.js @@ -1,5 +1,8 @@ import React from "react"; import PropTypes from "prop-types"; +import Loaders from "@appserver/common/components/Loaders"; +import { isTablet as isTabletUtils } from "@appserver/components/utils/device"; +import { isTablet } from "react-device-detect"; import { StyledArticleHeader, @@ -8,8 +11,20 @@ import { StyledMenuIcon, } from "../styled-article"; -const ArticleHeader = ({ showText, children, onClick, ...rest }) => { - return ( +const ArticleHeader = ({ + showText, + children, + onClick, + isLoading = false, + ...rest +}) => { + const heightLoader = isTabletUtils() || isTablet ? "20px" : "32px"; + + return isLoading ? ( + + + + ) : ( diff --git a/packages/asc-web-common/components/Navigation/Navigation.js b/packages/asc-web-common/components/Navigation/Navigation.js index 529cfacb3b..9be289c396 100644 --- a/packages/asc-web-common/components/Navigation/Navigation.js +++ b/packages/asc-web-common/components/Navigation/Navigation.js @@ -105,6 +105,8 @@ const Navigation = ({ getContextOptionsFolder={getContextOptionsFolder} getContextOptionsPlus={getContextOptionsPlus} toggleDropBox={toggleDropBox} + toggleInfoPanel={toggleInfoPanel} + isInfoPanelVisible={isInfoPanelVisible} onClickAvailable={onClickAvailable} /> )} diff --git a/packages/asc-web-common/components/Navigation/StyledNavigation.js b/packages/asc-web-common/components/Navigation/StyledNavigation.js index 5765ce9195..c96b42cfaf 100644 --- a/packages/asc-web-common/components/Navigation/StyledNavigation.js +++ b/packages/asc-web-common/components/Navigation/StyledNavigation.js @@ -9,6 +9,8 @@ const StyledContainer = styled.div` grid-template-columns: ${(props) => props.isRootFolder ? "auto 1fr" : "29px auto 1fr"}; + padding: ${(props) => (props.isDropBox ? "10px 0 5px" : "10px 0 11px")}; + .arrow-button { width: 17px; min-width: 17px; @@ -16,24 +18,25 @@ const StyledContainer = styled.div` @media ${tablet} { width: 100%; - padding: ${(props) => (props.isDropBox ? "16px 0 5px" : "16px 0 0px")}; + padding: ${(props) => (props.isDropBox ? "14px 0 5px" : "14px 0 15px")}; } ${isMobile && css` width: 100%; padding: ${(props) => - props.isDropBox ? "16px 0 5px" : " 16px 0 0px"} !important; + props.isDropBox ? "12px 0 5px" : " 12px 0 13px"} !important; `} @media ${mobile} { - height: 53px; + padding: ${(props) => + props.isDropBox ? "10px 0 5px" : "10px 0 11px"} !important; } ${isMobileOnly && css` width: 100% !important; padding: ${(props) => - props.isDropBox ? "18px 0 5px" : "18px 0 0"} !important; + props.isDropBox ? "10px 0 5px" : "10px 0 11px"} !important; `} `; diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index c7bdb84f36..d2abd45fc9 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -31,7 +31,6 @@ const StyledContainer = styled.div` } .option-button { - margin-left: auto; margin-right: 15px; min-width: 17px; } @@ -46,7 +45,7 @@ const StyledInfoPanelToggleWrapper = styled.div` align-items: center; align-self: center; justify-content: center; - margin-left: ${({ isRootFolder }) => (isRootFolder ? "auto" : "none")}; + margin-left: auto; .info-panel-toggle-bg { height: 32px; @@ -136,7 +135,7 @@ const ControlButtons = ({
props.dropBoxWidth}px; @@ -85,7 +85,9 @@ const DropBox = React.forwardRef( getContextOptionsFolder, getContextOptionsPlus, toggleDropBox, + toggleInfoPanel, onClickAvailable, + isInfoPanelVisible, }, ref ) => { @@ -141,6 +143,8 @@ const DropBox = React.forwardRef( canCreate={canCreate} getContextOptionsFolder={getContextOptionsFolder} getContextOptionsPlus={getContextOptionsPlus} + toggleInfoPanel={toggleInfoPanel} + isInfoPanelVisible={isInfoPanelVisible} /> diff --git a/packages/asc-web-common/components/Section/index.js b/packages/asc-web-common/components/Section/index.js index 516f1d919f..98e9887f83 100644 --- a/packages/asc-web-common/components/Section/index.js +++ b/packages/asc-web-common/components/Section/index.js @@ -222,7 +222,6 @@ class Section extends React.Component { isTabletView, firstLoad, dragging, - isBackdropVisible, isDesktop, isHomepage, maintenanceExist, @@ -560,9 +559,6 @@ export default inject(({ auth, infoPanelStore }) => { isHeaderVisible, isTabletView, - isBackdropVisible, - - setIsBackdropVisible, isDesktopClient, maintenanceExist, snackbarExist, @@ -579,8 +575,6 @@ export default inject(({ auth, infoPanelStore }) => { isTabletView, isHeaderVisible, - isBackdropVisible, - setIsBackdropVisible, maintenanceExist, snackbarExist, setMaintenanceExist, diff --git a/packages/asc-web-common/components/Section/sub-components/section-container.js b/packages/asc-web-common/components/Section/sub-components/section-container.js index 6aaf8577fe..1a4a13d5be 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-container.js +++ b/packages/asc-web-common/components/Section/sub-components/section-container.js @@ -22,7 +22,7 @@ const tabletProps = css` ${isMobileOnly && css` padding: 0 16px; - margin: 0 -16px; + margin: 0 0 0 -16px; `} } .section-body_filter { diff --git a/packages/asc-web-common/components/Section/sub-components/section-header.js b/packages/asc-web-common/components/Section/sub-components/section-header.js index c541768aed..af235987ce 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-header.js +++ b/packages/asc-web-common/components/Section/sub-components/section-header.js @@ -11,59 +11,42 @@ import Base from "@appserver/components/themes/base"; const StyledSectionHeader = styled.div` position: relative; - height: 53px; - min-height: 53px; - margin-right: 20px; + + padding-right: 20px; + + box-sizing: border-box; + ${NoUserSelect} display: grid; align-items: center; - /* width: calc(100vw - 296px); - max-width: calc(100vw - 296px); */ - - width: ${(props) => - props.infoPanelIsVisible ? "calc(100vw - 696px)" : "calc(100vw - 296px)"}; - max-width: ${(props) => - props.infoPanelIsVisible ? "calc(100vw - 696px)" : "calc(100vw - 296px)"}; + width: 100%; + max-width: 100%; @media ${tablet} { - width: ${(props) => - props.showText ? "calc(100vw - 272px)" : "calc(100vw - 84px)"}; - max-width: ${(props) => - props.showText ? "calc(100vw - 272px)" : "calc(100vw - 84px)"}; - height: 61px; - min-height: 61px; - margin-right: 0px !important; + padding-right: 16px; + margin-right: 0px; } ${isMobile && css` - width: ${(props) => - props.showText ? "calc(100vw - 272px)" : "calc(100vw - 84px)"} !important; - max-width: ${(props) => - props.showText ? "calc(100vw - 272px)" : "calc(100vw - 84px)"} !important; - height: 61px !important; - min-height: 61px !important; - margin-right: 0px !important; + padding-right: 0 !important; + margin-right: -16px !important; `} @media ${mobile} { - width: calc(100vw - 32px) !important; - max-width: calc(100vw - 32px) !important; - height: 53px; - min-height: 53px; - margin-right: 0px !important; + margin-right: 0px; } ${isMobileOnly && css` - width: calc(100vw - 32px) !important; - max-width: calc(100vw - 32px) !important; - height: 53px; - min-height: 53px; - margin-top: -2px; - margin-right: 0px !important; + width: 100vw !important; + max-width: 100vw !important; + + padding-right: 16px !important; + + margin-top: -2px !important; `} `; diff --git a/packages/asc-web-common/store/AuthStore.js b/packages/asc-web-common/store/AuthStore.js index 37e728876d..c852419329 100644 --- a/packages/asc-web-common/store/AuthStore.js +++ b/packages/asc-web-common/store/AuthStore.js @@ -52,12 +52,6 @@ class AuthStore { this.userStore.user && requests.push(this.moduleStore.init()); } - if (this.isAuthenticated) { - this.settingsStore.getPortalPasswordSettings(); - this.tfaStore.getTfaType(); - this.settingsStore.getIpRestrictions(); - } - return Promise.all(requests); }; setLanguage() { diff --git a/packages/asc-web-common/store/SettingsStore.js b/packages/asc-web-common/store/SettingsStore.js index 732efdb206..3e5be9d92b 100644 --- a/packages/asc-web-common/store/SettingsStore.js +++ b/packages/asc-web-common/store/SettingsStore.js @@ -1,6 +1,6 @@ import { makeAutoObservable } from "mobx"; import api from "../api"; -import { ARTICLE_PINNED_KEY, LANGUAGE, TenantStatus } from "../constants"; +import { LANGUAGE, TenantStatus } from "../constants"; import { combineUrl } from "../utils"; import FirebaseHelper from "../utils/firebase"; import { AppServerConfig } from "../constants"; @@ -454,8 +454,8 @@ class SettingsStore { getIpRestrictions = async () => { const res = await api.settings.getIpRestrictions(); - if (res.length === 0) this.ipRestrictionEnabled = false; - else this.ipRestrictionEnabled = true; + this.ipRestrictions = res?.map((el) => el.ip); + console.log(this.ipRestrictions); }; setIpRestrictions = async (ips) => { @@ -463,8 +463,12 @@ class SettingsStore { ips: ips, }; const res = await api.settings.setIpRestrictions(data); - console.log("setIpRestrictions", res); - this.ipRestrictions = ips; + this.ipRestrictions = res; + }; + + getIpRestrictionsEnable = async () => { + const res = await api.settings.getIpRestrictionsEnable(); + this.ipRestrictionEnable = res.enable; }; setIpRestrictionsEnable = async (enable) => { @@ -472,8 +476,7 @@ class SettingsStore { enable: enable, }; const res = await api.settings.setIpRestrictionsEnable(data); - console.log("setIpRestrictionsEnable", res); - this.ipRestrictionEnabled = enable; + this.ipRestrictionEnable = res.enable; }; setMessageSettings = async (turnOn) => { diff --git a/packages/asc-web-components/avatar/index.js b/packages/asc-web-components/avatar/index.js index 4ad56e91ee..41ba9a6e20 100644 --- a/packages/asc-web-components/avatar/index.js +++ b/packages/asc-web-components/avatar/index.js @@ -57,7 +57,7 @@ const Avatar = (props) => { const { size, source, userName, role, editing, editAction } = props; let isDefault = false; - if (source.includes("default_user_photo")) isDefault = true; + if (source?.includes("default_user_photo")) isDefault = true; const avatarContent = source ? ( diff --git a/packages/asc-web-components/save-cancel-buttons/styled-save-cancel-buttons.js b/packages/asc-web-components/save-cancel-buttons/styled-save-cancel-buttons.js index ea9e95b17d..5b63b63a85 100644 --- a/packages/asc-web-components/save-cancel-buttons/styled-save-cancel-buttons.js +++ b/packages/asc-web-components/save-cancel-buttons/styled-save-cancel-buttons.js @@ -81,7 +81,7 @@ const tabletButtons = css` .save-button, .cancel-button { - max-width: max-content; + width: auto; padding-left: 28px; padding-right: 28px; } diff --git a/packages/asc-web-components/search-input/styled-search-input.js b/packages/asc-web-components/search-input/styled-search-input.js index 396f5458d8..a097baa03e 100644 --- a/packages/asc-web-components/search-input/styled-search-input.js +++ b/packages/asc-web-components/search-input/styled-search-input.js @@ -6,6 +6,8 @@ const StyledSearchInput = styled.div` font-style: normal; .search-input-block { + max-height: 32px; + & > input { font-size: ${(props) => props.theme.searchInput.fontSize}; font-weight: ${(props) => props.theme.searchInput.fontWeight}; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 2756c79a75..002f8270fc 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -157,6 +157,8 @@ const StyledInfoPanelToggleWrapper = styled.div` ? props.theme.infoPanel.sectionHeaderToggleIconActive : props.theme.infoPanel.sectionHeaderToggleIcon}; } + + margin-bottom: 1px; } `; StyledInfoPanelToggleWrapper.defaultProps = { theme: Base }; @@ -199,6 +201,8 @@ const StyledTableHeaderCell = styled.div` `} svg { + width: 12px; + height: 12px; path { fill: ${(props) => props.isActive diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 6052f1387a..f207ba64b9 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -62,7 +62,7 @@ const TableGroupMenu = (props) => {
+ + diff --git a/products/ASC.Files/Client/public/images/panel.svg b/products/ASC.Files/Client/public/images/panel.svg deleted file mode 100644 index 8da7c48595..0000000000 --- a/products/ASC.Files/Client/public/images/panel.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/products/ASC.Files/Client/src/HOCs/withHotkeys.js b/products/ASC.Files/Client/src/HOCs/withHotkeys.js index a7139de0c2..47ef004500 100644 --- a/products/ASC.Files/Client/src/HOCs/withHotkeys.js +++ b/products/ASC.Files/Client/src/HOCs/withHotkeys.js @@ -37,7 +37,6 @@ const withHotkeys = (Component) => { activateHotkeys, backToParentFolder, - hideArticle, uploadFile, someDialogIsOpen, } = props; @@ -147,10 +146,7 @@ const withHotkeys = (Component) => { //Crete form template from file useHotkeys( "Alt+Shift+o", - () => { - hideArticle(); - setSelectFileDialogVisible(true); - }, + () => setSelectFileDialogVisible(true), hotkeysFilter ); @@ -217,14 +213,12 @@ const withHotkeys = (Component) => { return inject( ({ - auth, filesStore, dialogsStore, settingsStore, filesActionsStore, hotkeyStore, }) => { - const { hideArticle } = auth.settingsStore; const { setSelected, viewAs, setViewAs, fileActionStore } = filesStore; const { setAction } = fileActionStore; @@ -291,7 +285,6 @@ const withHotkeys = (Component) => { activateHotkeys, backToParentFolder, - hideArticle, uploadFile, someDialogIsOpen, }; diff --git a/products/ASC.Files/Client/src/components/Article/Body/index.js b/products/ASC.Files/Client/src/components/Article/Body/index.js index d43f8eeb23..a5e05a7304 100644 --- a/products/ASC.Files/Client/src/components/Article/Body/index.js +++ b/products/ASC.Files/Client/src/components/Article/Body/index.js @@ -142,7 +142,6 @@ export default inject( toggleArticleOpen, personal, - hideArticle, isDesktopClient, FirebaseHelper, theme, @@ -171,7 +170,6 @@ export default inject( setTreeFolders, setNewFilesPanelVisible, - hideArticle, firstLoad, isDesktopClient, FirebaseHelper, diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js index c0d8b0da60..5f3c05ce0e 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js @@ -116,7 +116,11 @@ const StyledTile = styled.div` } .tile-folder-loader { - padding-top: 4px; + padding-top: 16px; + width: 32px; + height: 32px; + margin-left: 21px; + margin-right: 14px; } :hover { @@ -180,8 +184,11 @@ const StyledFileTileBottom = styled.div` box-sizing: border-box; .tile-file-loader { - padding-top: 4px; - padding-left: 3px; + padding-top: 16px; + width: 32px; + height: 32px; + margin-left: 23px; + margin-right: 14px; } `; diff --git a/products/ASC.Files/Client/src/store/ContextOptionsStore.js b/products/ASC.Files/Client/src/store/ContextOptionsStore.js index 92f9aff574..a9aa6ef386 100644 --- a/products/ASC.Files/Client/src/store/ContextOptionsStore.js +++ b/products/ASC.Files/Client/src/store/ContextOptionsStore.js @@ -63,7 +63,7 @@ class ContextOptionsStore { const { setConvertPasswordDialogVisible, setFormCreationInfo, - } = dialogsStore; + } = this.dialogsStore; const { title, id, folderId, fileExst } = item; const newTitle = @@ -412,7 +412,7 @@ class ContextOptionsStore { }, { key: "copy", - label: t("Duplicate"), + label: t("Common:Duplicate"), onClick: () => this.onDuplicate(item, t), disabled: false, }, @@ -436,7 +436,7 @@ class ContextOptionsStore { }, { key: "copy", - label: t("Duplicate"), + label: t("Common:Duplicate"), icon: "/static/images/copy.react.svg", onClick: () => this.onDuplicate(item, t), disabled: false, diff --git a/products/ASC.Files/Client/src/store/DialogsStore.js b/products/ASC.Files/Client/src/store/DialogsStore.js index f10f5cc4fd..8e39eb4c3c 100644 --- a/products/ASC.Files/Client/src/store/DialogsStore.js +++ b/products/ASC.Files/Client/src/store/DialogsStore.js @@ -153,7 +153,6 @@ class DialogsStore { this.setNewFilesIds(null); } - this.authStore.settingsStore.hideArticle(); this.newFilesPanelVisible = newFilesPanelVisible; }; diff --git a/products/ASC.Files/Client/src/store/HotkeyStore.js b/products/ASC.Files/Client/src/store/HotkeyStore.js index a0486e4a56..2e6a211c7f 100644 --- a/products/ASC.Files/Client/src/store/HotkeyStore.js +++ b/products/ASC.Files/Client/src/store/HotkeyStore.js @@ -49,7 +49,7 @@ class HotkeyStore { if (!hotkeyCaret) { const scroll = document.getElementsByClassName("section-scroll"); - scroll && scroll[0].focus(); + scroll && scroll[0] && scroll[0].focus(); } if (!hotkeyCaret && selection.length) { @@ -129,26 +129,31 @@ class HotkeyStore { }; selectBottom = () => { - const { viewAs, hotkeyCaret } = this.filesStore; + const { viewAs, hotkeyCaret, selection } = this.filesStore; - if (!hotkeyCaret) return this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) return this.selectFirstFile(); else if (viewAs === "tile") this.setSelectionWithCaret([this.nextForTileDown]); else if (this.nextFile) this.setSelectionWithCaret([this.nextFile]); }; selectUpper = () => { - const { hotkeyCaret, viewAs } = this.filesStore; + const { hotkeyCaret, viewAs, selection } = this.filesStore; - if (!hotkeyCaret) return this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) return this.selectFirstFile(); else if (viewAs === "tile") this.setSelectionWithCaret([this.prevForTileUp]); else if (this.prevFile) this.setSelectionWithCaret([this.prevFile]); }; selectLeft = () => { - const { hotkeyCaret, filesList, setHotkeyCaretStart } = this.filesStore; - if (!hotkeyCaret) { + const { + hotkeyCaret, + filesList, + setHotkeyCaretStart, + selection, + } = this.filesStore; + if (!hotkeyCaret && !selection.length) { this.selectFirstFile(); setHotkeyCaretStart(filesList[0]); @@ -158,9 +163,14 @@ class HotkeyStore { }; selectRight = () => { - const { hotkeyCaret, filesList, setHotkeyCaretStart } = this.filesStore; + const { + hotkeyCaret, + filesList, + setHotkeyCaretStart, + selection, + } = this.filesStore; - if (!hotkeyCaret) { + if (!hotkeyCaret && !selection.length) { this.selectFirstFile(); setHotkeyCaretStart(filesList[0]); } else if (this.nextFile) { @@ -183,7 +193,7 @@ class HotkeyStore { if (!hotkeyCaretStart) { setHotkeyCaretStart(hotkeyCaret); } - if (!hotkeyCaret) return this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) return this.selectFirstFile(); if (viewAs === "tile") { if (this.nextForTileDown.id === hotkeyCaret.id) return; @@ -218,7 +228,7 @@ class HotkeyStore { if (!hotkeyCaretStart) { setHotkeyCaretStart(hotkeyCaret); } - if (!hotkeyCaret) this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) this.selectFirstFile(); if (viewAs === "tile") { if (this.prevForTileUp.id === hotkeyCaret.id) return; @@ -251,7 +261,7 @@ class HotkeyStore { filesList, } = this.filesStore; - if (!hotkeyCaret) return this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) return this.selectFirstFile(); const nextFile = this.nextFile; if (!nextFile) return; @@ -309,7 +319,7 @@ class HotkeyStore { hotkeyCaretStart, } = this.filesStore; - if (!hotkeyCaret) return this.selectFirstFile(); + if (!hotkeyCaret && !selection.length) return this.selectFirstFile(); const prevFile = this.prevFile; if (!prevFile) return; @@ -461,8 +471,9 @@ class HotkeyStore { } get caretIndex() { - const { filesList, hotkeyCaret } = this.filesStore; - const caretIndex = filesList.findIndex((f) => f.id === hotkeyCaret.id); + const { filesList, hotkeyCaret, selection } = this.filesStore; + const id = selection.length ? selection[0].id : hotkeyCaret?.id; + const caretIndex = filesList.findIndex((f) => f.id === id); if (caretIndex !== -1) return caretIndex; else return null; diff --git a/web/ASC.Web.Api/Controllers/SettingsController.cs b/web/ASC.Web.Api/Controllers/SettingsController.cs index bf85dac311..4cea654fc6 100644 --- a/web/ASC.Web.Api/Controllers/SettingsController.cs +++ b/web/ASC.Web.Api/Controllers/SettingsController.cs @@ -1405,6 +1405,13 @@ namespace ASC.Api.Settings return IPRestrictionsService.Save(model.Ips, Tenant.TenantId); } + [Read("iprestrictions/settings")] + public IPRestrictionsSettings GetIpRestrictionsSettings() + { + PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); + return SettingsManager.Load(); + } + [Update("iprestrictions/settings")] public IPRestrictionsSettings UpdateIpRestrictionsSettingsFromBody([FromBody] IpRestrictionsModel model) { diff --git a/web/ASC.Web.Client/src/Shell.jsx b/web/ASC.Web.Client/src/Shell.jsx index 7e282f0a50..42cf43404d 100644 --- a/web/ASC.Web.Client/src/Shell.jsx +++ b/web/ASC.Web.Client/src/Shell.jsx @@ -578,6 +578,7 @@ const ShellWrapper = inject(({ auth, backup }) => { setTheme, } = settingsStore; const { setPreparationPortalDialogVisible } = backup; + return { loadBaseInfo: async () => { await init(); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Article/Body/index.js b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Article/Body/index.js index c53f287700..35a5748a21 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Article/Body/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Article/Body/index.js @@ -6,6 +6,10 @@ import { withTranslation } from "react-i18next"; import { isArrayEqual } from "@appserver/components/utils/array"; +import { isMobileOnly } from "react-device-detect"; + +import { isMobile } from "@appserver/components/utils/device"; + import { //getKeyByLink, settingsTree, @@ -55,7 +59,7 @@ class ArticleBodyContent extends React.Component { componentDidUpdate(prevProps, prevState) { if (!isArrayEqual(prevState.selectedKeys, this.state.selectedKeys)) { const { selectedKeys } = this.state; - console.log(selectedKeys); + const { match, history } = this.props; const settingsPath = getSelectedLinkByKey(selectedKeys[0], settingsTree); const newPath = match.path + settingsPath; @@ -66,13 +70,17 @@ class ArticleBodyContent extends React.Component { onSelect = (value) => { const { selectedKeys } = this.state; - console.log(selectedKeys, value); + const { toggleArticleOpen } = this.props; if (isArrayEqual([value], selectedKeys)) { return; } this.setState({ selectedKeys: [value + "-0"] }); + + if (isMobileOnly || isMobile()) { + toggleArticleOpen(); + } }; mapKeys = (tKey) => { @@ -145,5 +153,6 @@ class ArticleBodyContent extends React.Component { export default inject(({ auth }) => { return { showText: auth.settingsStore.showText, + toggleArticleOpen: auth.settingsStore.toggleArticleOpen, }; })(withRouter(withTranslation("Settings")(observer(ArticleBodyContent)))); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js index 3bd814049f..cd7841e500 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js @@ -110,8 +110,9 @@ class SectionHeaderContent extends React.Component { const resultPath = locationPathname.slice(fullSettingsUrlLength + 1); const arrayOfParams = resultPath.split("/"); - const key = getKeyByLink(arrayOfParams, settingsTree)[0]; - const header = getTKeyByKey(key, settingsTree); + const key = getKeyByLink(arrayOfParams, settingsTree); + const currKey = key.length > 3 ? key : key[0]; + const header = getTKeyByKey(currKey, settingsTree); const isCategory = checkPropertyByLink( arrayOfParams, settingsTree, @@ -133,8 +134,9 @@ class SectionHeaderContent extends React.Component { componentDidUpdate() { const arrayOfParams = this.getArrayOfParams(); - const key = getKeyByLink(arrayOfParams, settingsTree)[0]; - const header = getTKeyByKey(key, settingsTree); + const key = getKeyByLink(arrayOfParams, settingsTree); + const currKey = key.length > 3 ? key : key[0]; + const header = getTKeyByKey(currKey, settingsTree); const isCategory = checkPropertyByLink( arrayOfParams, settingsTree, diff --git a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/loaderSectionHeader.js b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/loaderSectionHeader.js new file mode 100644 index 0000000000..3a5d63745c --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/loaderSectionHeader.js @@ -0,0 +1,46 @@ +import React from "react"; +import styled, { css } from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; +import { isDesktop as isDesktopUtils } from "@appserver/components/utils/device"; +import { isTablet } from "react-device-detect"; + +const tabletStyles = css` + padding-top: 12px; + .loader { + width: 184px; + } +`; + +const StyledLoader = styled.div` + padding-top: 8px; + + .loader { + width: 273px; + } + + @media (min-width: 600px) { + ${tabletStyles} + } + + ${isTablet && + css` + ${tabletStyles} + `} + + @media (min-width: 1025px) { + .loader { + width: 296px; + } + } +`; + +const LoaderSectionHeader = () => { + const heightLoader = isDesktopUtils() ? "29px" : "37px"; + return ( + + + + ); +}; + +export default LoaderSectionHeader; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/Layout/index.js b/web/ASC.Web.Client/src/components/pages/Settings/Layout/index.js index 30a7025ea0..6a6dadd596 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/Layout/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/Layout/index.js @@ -4,6 +4,7 @@ import { ArticleHeaderContent, ArticleBodyContent } from "./Article"; import { SectionHeaderContent, SectionPagingContent } from "./Section"; import { inject, observer } from "mobx-react"; import Section from "@appserver/common/components/Section"; +import LoaderSectionHeader from "./Section/loaderSectionHeader"; const ArticleSettings = React.memo(() => { return ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js index 18e10239d3..4bc741b9a2 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js @@ -10,6 +10,7 @@ import { AppServerConfig } from "@appserver/common/constants"; import withCultureNames from "@appserver/common/hoc/withCultureNames"; import history from "@appserver/common/history"; import { Base } from "@appserver/components/themes"; +import LoaderCustomizationNavbar from "./sub-components/loaderCustomizationNavbar"; import { StyledArrowRightIcon } from "../common/settingsCustomization/StyledSettings"; @@ -51,6 +52,9 @@ const CustomizationNavbar = ({ t, theme, helpUrlCommonSettings }) => { e.preventDefault(); history.push(e.target.pathname); }; + + //return ; + return (
diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js index dd6a0fade3..a8e22436a1 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js @@ -1,6 +1,7 @@ import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import styled from "styled-components"; +import { inject, observer } from "mobx-react"; import withCultureNames from "@appserver/common/hoc/withCultureNames"; import LanguageAndTimeZone from "./settingsCustomization/language-and-time-zone"; import WelcomePageSettings from "./settingsCustomization/welcome-page-settings"; @@ -9,8 +10,11 @@ import { isSmallTablet } from "@appserver/components/utils/device"; import CustomizationNavbar from "./customization-navbar"; import { Base } from "@appserver/components/themes"; import { setDocumentTitle } from "../../../../../helpers/utils"; +import LoaderDescriptionCustomization from "./sub-components/loaderDescriptionCustomization"; const StyledComponent = styled.div` + width: 100%; + .combo-button-label { max-width: 100%; } @@ -61,9 +65,9 @@ const StyledComponent = styled.div` StyledComponent.defaultProps = { theme: Base }; -const Customization = ({ t }) => { +const Customization = ({ t, setIsLoadingArticleSettings }) => { const [mobileView, setMobileView] = useState(true); - const [isLoadingCustomization, setIsLoadingCustomization] = useState(true); + const [isLoadingCustomization, setIsLoadingCustomization] = useState(false); const checkInnerWidth = () => { if (isSmallTablet()) { @@ -75,8 +79,12 @@ const Customization = ({ t }) => { useEffect(() => { setDocumentTitle(t("Customization")); - //TODO: add method to get the portal name - setIsLoadingCustomization(false); + //TODO: Add method to get the portal name + setIsLoadingArticleSettings(true); + setTimeout(() => { + setIsLoadingCustomization(false); + setIsLoadingArticleSettings(isLoadingCustomization); + }, 3000); window.addEventListener("resize", checkInnerWidth); return () => window.removeEventListener("resize", checkInnerWidth); @@ -91,6 +99,7 @@ const Customization = ({ t }) => {
{`${t( "Settings:CustomizationDescription" )}`}
+ {/* */} { ); }; -export default withCultureNames( - withTranslation(["Settings", "Common"])(Customization) +export default inject(({ setup }) => { + const { setIsLoadingArticleSettings } = setup; + + return { + setIsLoadingArticleSettings, + }; +})( + withCultureNames( + withTranslation(["Settings", "Common"])(observer(Customization)) + ) ); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/index.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/index.js index d768f69546..df8aa31da5 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/index.js @@ -8,7 +8,7 @@ import config from "../../../../../../package.json"; import Customization from "./customization"; import WhiteLabel from "./whitelabel"; -import AppLoader from "@appserver/common/components/AppLoader"; +import LoaderSubmenu from "./sub-components/loaderSubmenu"; const SubmenuCommon = (props) => { const { t, history } = props; @@ -34,7 +34,7 @@ const SubmenuCommon = (props) => { if (currentTab !== -1) { setCurrentTab(currentTab); } - setIsLoading(true); + //setIsLoading(true); }, []); const onSelect = (e) => { @@ -46,9 +46,9 @@ const SubmenuCommon = (props) => { ) ); }; - - return !isLoading ? ( - + //TODO: isLoading + return isLoading ? ( + ) : ( { return timezones.map((timezone) => { return { key: timezone.id, label: timezone.displayName }; @@ -399,6 +399,7 @@ class LanguageAndTimeZone extends React.Component {
); + //return ; return !isLoadedData ? ( ) : ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js index dadc5d78e2..a121685d5c 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js @@ -18,6 +18,7 @@ import { PortalRenamingTooltip } from "../sub-components/common-tooltips"; import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; import { setDocumentTitle } from "../../../../../../helpers/utils"; +import LoaderCustomization from "../sub-components/loaderCustomization"; const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { // TODO: Change false @@ -186,6 +187,7 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
); + //return ; return !isLoadedData ? ( ) : ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js index c64ca67997..deb17746ae 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js @@ -19,7 +19,7 @@ import { isMobileOnly } from "react-device-detect"; import { isSmallTablet } from "@appserver/components/utils/device"; import checkScrollSettingsBlock from "../utils"; import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; -import LoaderLngTZSettings from "../sub-components/loaderLngTZSettings"; +import LoaderCustomization from "../sub-components/loaderCustomization"; let greetingTitleFromSessionStorage = ""; let greetingTitleDefaultFromSessionStorage = ""; @@ -250,6 +250,7 @@ class WelcomePageSettings extends React.Component {
); + // return ; return !isLoadedData ? ( ) : ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomization.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomization.js new file mode 100644 index 0000000000..46e48c0d58 --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomization.js @@ -0,0 +1,143 @@ +import React from "react"; +import styled, { css } from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; + +import { isTablet } from "react-device-detect"; + +const tabletStyles = css` + .header { + display: block; + width: ${(props) => + props.lngTZSettings + ? "283px" + : props.welcomePage + ? "201px" + : props.portalRenaming + ? "150px" + : 0}; + padding-bottom: 16px; + } + + .description { + display: none; + } + + .title { + display: block; + width: ${(props) => + props.lngTZSettings + ? "65px" + : props.welcomePage + ? "31px" + : props.portalRenaming + ? "113px" + : 0}; + } + + .combo-box { + display: block; + width: 350px; + } + + .field-container { + display: block; + width: 350px; + } + + .save-cancel-buttons { + display: block; + position: static; + width: 350px; + padding: 0; + } +`; + +const StyledLoader = styled.div` + .header { + display: none; + } + + .description { + width: 100%; + padding-bottom: 12px; + } + + .title { + width: ${(props) => (props.portalRenaming ? "49px" : "63.7px")}; + padding-bottom: 4px; + } + + .title-long { + display: block; + width: 68px; + padding-bottom: 4px; + } + + .combo-box { + display: block; + width: 100%; + padding-bottom: 24px; + } + + .field-container { + width: 100%; + padding-bottom: 12px; + } + + .save-cancel-buttons { + display: block; + position: absolute; + bottom: 0; + left: 0; + width: calc(100% - 32px); + padding: 0 0 16px 16px; + } + + @media (min-width: 600px) { + ${tabletStyles} + } + + ${isTablet && + ` + ${tabletStyles} + `} +`; + +const LoaderCustomization = ({ + lngTZSettings, + portalRenaming, + welcomePage, +}) => { + const heightSaveCancelButtons = window.innerWidth < 600 ? "40px" : "32px"; + + return ( + + + + {portalRenaming && ( + + )} + + + + {lngTZSettings && ( + <> + + + + + )} + + + ); +}; + +export default LoaderCustomization; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomizationNavbar.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomizationNavbar.js new file mode 100644 index 0000000000..5a0e75daae --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderCustomizationNavbar.js @@ -0,0 +1,44 @@ +import React from "react"; +import styled from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; + +const StyledLoader = styled.div` + .title-long { + width: 283px; + padding-bottom: 8px; + } + + .width { + width: 100%; + padding-bottom: 8px; + } + + .link { + width: 57px; + padding-bottom: 20px; + } + + .title { + display: block; + width: 132px; + padding-bottom: 8px; + } +`; + +const LoaderCustomizationNavbar = () => { + return ( + + + + + + + + + + + + ); +}; + +export default LoaderCustomizationNavbar; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderDescriptionCustomization.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderDescriptionCustomization.js new file mode 100644 index 0000000000..ba023bd663 --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderDescriptionCustomization.js @@ -0,0 +1,38 @@ +import React from "react"; +import styled, { css } from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; +import { isTablet } from "react-device-detect"; + +const tabletStyles = css` + .description { + width: 684px; + padding-bottom: 20px; + } +`; + +const StyledLoader = styled.div` + @media (min-width: 600px) { + ${tabletStyles} + } + + ${isTablet && + css` + ${tabletStyles} + `} + + @media (min-width: 1024px) { + .description { + width: 700px; + } + } +`; + +const LoaderDescriptionCustomization = () => { + return ( + + + + ); +}; + +export default LoaderDescriptionCustomization; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderLngTZSettings.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderLngTZSettings.js deleted file mode 100644 index 2838c7f6e0..0000000000 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderLngTZSettings.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import Loaders from "@appserver/common/components/Loaders"; - -const StyledLoader = styled.div``; - -const LoaderLngTZSettings = () => { - return ( - - - - ); -}; - -export default LoaderLngTZSettings; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderSubmenu.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderSubmenu.js new file mode 100644 index 0000000000..3ac979a609 --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderSubmenu.js @@ -0,0 +1,32 @@ +import React from "react"; +import styled from "styled-components"; +import Loaders from "@appserver/common/components/Loaders"; +import { isTablet } from "react-device-detect"; + +const StyledLoader = styled.div` + margin-top: -4px; + + .loader { + padding-right: 4px; + } + + @media (min-width: 600px) { + margin-top: -9px; + } + + ${isTablet && + css` + margin-top: -9px; + `} +`; + +const LoaderSubmenu = () => { + return ( + + + + + ); +}; + +export default LoaderSubmenu; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js index 05b3533c07..b78fe43b21 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js @@ -308,7 +308,6 @@ class WhiteLabel extends React.Component { ) : ( <> - В разработке
{t("LogoSettings")} diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js index cc21f96a08..9f213d080d 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js @@ -85,34 +85,6 @@ export const StyledMobileCategoryWrapper = styled.div` StyledMobileCategoryWrapper.defaultProps = { theme: Base }; -export const ButtonsWrapper = styled.div` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - margin-top: 24px; - - @media (max-width: 600px) { - position: absolute; - bottom: 16px; - width: calc(100vw - 84px); - - .button { - height: 40px; - width: 100%; - } - - .reminder { - position: absolute; - bottom: 48px; - } - } - - @media (max-width: 430px) { - width: calc(100vw - 32px); - } -`; - export const LearnMoreWrapper = styled.div` display: none; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/ipSecurity.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/ipSecurity.js index a4bddcff38..ba1f9fb881 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/ipSecurity.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/ipSecurity.js @@ -8,10 +8,10 @@ import RadioButtonGroup from "@appserver/components/radio-button-group"; import toastr from "@appserver/components/toast/toastr"; import { LearnMoreWrapper } from "../StyledSecurity"; import UserFields from "../sub-components/user-fields"; -import Buttons from "../sub-components/buttons"; import { size } from "@appserver/components/utils/device"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; import isEqual from "lodash/isEqual"; +import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; const MainContainer = styled.div` width: 100%; @@ -31,19 +31,23 @@ const MainContainer = styled.div` .warning-text { margin-bottom: 9px; } + + .save-cancel-buttons { + margin-top: 24px; + } `; const IpSecurity = (props) => { const { t, history, - ipRestrictionEnabled, + ipRestrictionEnable, setIpRestrictionsEnable, ipRestrictions, setIpRestrictions, } = props; - const regexp = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))|((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])/; //check ip valid + const regexp = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/; //check ip valid const [enable, setEnable] = useState(false); const [ips, setIps] = useState(); @@ -58,7 +62,7 @@ const IpSecurity = (props) => { saveToSessionStorage("defaultIPSettings", defaultSettings); } else { const defaultData = { - enable: ipRestrictionEnabled, + enable: ipRestrictionEnable, ips: ipRestrictions, }; saveToSessionStorage("defaultIPSettings", defaultData); @@ -68,7 +72,7 @@ const IpSecurity = (props) => { setEnable(currentSettings.enable); setIps(currentSettings.ips); } else { - setEnable(ipRestrictionEnabled); + setEnable(ipRestrictionEnable); setIps(ipRestrictions); } @@ -125,21 +129,25 @@ const IpSecurity = (props) => { setIps([...ips, ""]); }; - const onSaveClick = () => { + const onSaveClick = async () => { const valid = ips.map((ip) => regexp.test(ip)); if (valid.includes(false)) { return; } - setIpRestrictions(ips); - setIpRestrictionsEnable(enable); + try { + await setIpRestrictions(ips); + await setIpRestrictionsEnable(enable); - saveToSessionStorage("defaultIPSettings", { - enable: enable, - ips: ips, - }); - setShowReminder(false); - toastr.success(t("SuccessfullySaveSettingsMessage")); + saveToSessionStorage("defaultIPSettings", { + enable: enable, + ips: ips, + }); + setShowReminder(false); + toastr.success(t("SuccessfullySaveSettingsMessage")); + } catch (error) { + toastr.error(error); + } }; const onCancelClick = () => { @@ -188,21 +196,30 @@ const IpSecurity = (props) => { /> )} - - {t("Common:Warning")}! - - {t("IPSecurityWarningHelper")} + {enable && ( + <> + + {t("Common:Warning")}! + + {t("IPSecurityWarningHelper")} + + )} - ); @@ -210,14 +227,14 @@ const IpSecurity = (props) => { export default inject(({ auth }) => { const { - ipRestrictionEnabled, + ipRestrictionEnable, setIpRestrictionsEnable, ipRestrictions, setIpRestrictions, } = auth.settingsStore; return { - ipRestrictionEnabled, + ipRestrictionEnable, setIpRestrictionsEnable, ipRestrictions, setIpRestrictions, diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js index f77c7e56d0..9a1ff43e16 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js @@ -11,10 +11,10 @@ import Checkbox from "@appserver/components/checkbox"; import { getLanguage } from "@appserver/common/utils"; import { LearnMoreWrapper } from "../StyledSecurity"; import toastr from "@appserver/components/toast/toastr"; -import Buttons from "../sub-components/buttons"; import { size } from "@appserver/components/utils/device"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; import isEqual from "lodash/isEqual"; +import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; const MainContainer = styled.div` width: 100%; @@ -30,6 +30,7 @@ const MainContainer = styled.div` flex-direction: column; gap: 8px; margin-top: 18px; + margin-bottom: 24px; } `; @@ -216,11 +217,16 @@ const PasswordStrength = (props) => { /> - ); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js index 0a22c2ce4b..348de8140a 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js @@ -8,13 +8,17 @@ import Text from "@appserver/components/text"; import Link from "@appserver/components/link"; import toastr from "@appserver/components/toast/toastr"; import { getLanguage } from "@appserver/common/utils"; -import Buttons from "../sub-components/buttons"; import { LearnMoreWrapper } from "../StyledSecurity"; import { size } from "@appserver/components/utils/device"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; +import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; const MainContainer = styled.div` width: 100%; + + .box { + margin-bottom: 24px; + } `; const TwoFactorAuth = (props) => { @@ -145,11 +149,16 @@ const TwoFactorAuth = (props) => { onClick={onSelectTfaType} /> - ); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js index 0e4462335e..5e0853106f 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js @@ -10,24 +10,20 @@ import { LearnMoreWrapper } from "../StyledSecurity"; import { getLanguage } from "@appserver/common/utils"; import toastr from "@appserver/components/toast/toastr"; import UserFields from "../sub-components/user-fields"; -import Buttons from "../sub-components/buttons"; import { size } from "@appserver/components/utils/device"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; import isEqual from "lodash/isEqual"; +import SaveCancelButtons from "@appserver/components/save-cancel-buttons"; const MainContainer = styled.div` width: 100%; - .user-fields { - margin-bottom: 18px; - } - .box { margin-bottom: 11px; } - .warning-text { - margin-bottom: 9px; + .save-cancel-buttons { + margin-top: 24px; } `; @@ -45,9 +41,10 @@ const TrustedMail = (props) => { const [type, setType] = useState("0"); const [domains, setDomains] = useState([]); const [showReminder, setShowReminder] = useState(false); + const [isSaving, setIsSaving] = useState(false); const [isLoading, setIsLoading] = useState(false); - const getSettings = async () => { + const getSettings = () => { const currentSettings = getFromSessionStorage("currentTrustedMailSettings"); const defaultSettings = getFromSessionStorage("defaultTrustedMailSettings"); @@ -68,7 +65,6 @@ const TrustedMail = (props) => { setType(String(trustedDomainsType)); setDomains(trustedDomains); } - setIsLoading(true); }; @@ -81,7 +77,6 @@ const TrustedMail = (props) => { useEffect(() => { if (!isLoading) return; - const defaultSettings = getFromSessionStorage("defaultTrustedMailSettings"); const newSettings = { type: type, @@ -124,25 +119,33 @@ const TrustedMail = (props) => { setDomains(newInputs); }; - const onSaveClick = () => { + const onSaveClick = async () => { + setIsSaving(true); const valid = domains.map((domain) => regexp.test(domain)); if (type === "1" && valid.includes(false)) { + setIsSaving(false); toastr.error(t("Common:IncorrectDomain")); return; } - const data = { - type: Number(type), - domains: domains, - inviteUsersAsVisitors: true, - }; - setMailDomainSettings(data); - saveToSessionStorage("defaultTrustedMailSettings", { - type: type, - domains: domains, - }); - setShowReminder(false); - toastr.success(t("SuccessfullySaveSettingsMessage")); + try { + const data = { + type: Number(type), + domains: domains, + inviteUsersAsVisitors: true, + }; + await setMailDomainSettings(data); + saveToSessionStorage("defaultTrustedMailSettings", { + type: type, + domains: domains, + }); + setShowReminder(false); + toastr.success(t("SuccessfullySaveSettingsMessage")); + } catch (error) { + toastr.error(error); + } + + setIsSaving(false); }; const onCancelClick = () => { @@ -194,7 +197,6 @@ const TrustedMail = (props) => { {type === "1" && ( { /> )} - ); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/index.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/index.js index 25af60801e..1667952c5d 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/index.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react"; import Submenu from "@appserver/components/submenu"; import { withRouter } from "react-router"; import { withTranslation } from "react-i18next"; +import { inject, observer } from "mobx-react"; import { AppServerConfig } from "@appserver/common/constants"; import { combineUrl } from "@appserver/common/utils"; import config from "../../../../../../package.json"; @@ -11,7 +12,7 @@ import AccessPortal from "./access-portal/index.js"; import AppLoader from "@appserver/common/components/AppLoader"; const SecurityWrapper = (props) => { - const { t, history } = props; + const { t, history, loadBaseInfo } = props; const [currentTab, setCurrentTab] = useState(0); const [isLoading, setIsLoading] = useState(false); @@ -28,11 +29,16 @@ const SecurityWrapper = (props) => { }, ]; - useEffect(() => { + const load = async () => { + await loadBaseInfo(); const path = location.pathname; const currentTab = data.findIndex((item) => path.includes(item.id)); if (currentTab !== -1) setCurrentTab(currentTab); setIsLoading(true); + }; + + useEffect(() => { + load(); }, []); const onSelect = (e) => { @@ -55,4 +61,12 @@ const SecurityWrapper = (props) => { ); }; -export default withTranslation("Settings")(withRouter(SecurityWrapper)); +export default inject(({ setup }) => { + const { initSettings } = setup; + + return { + loadBaseInfo: async () => { + await initSettings(); + }, + }; +})(withTranslation("Settings")(withRouter(observer(SecurityWrapper)))); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/buttons.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/buttons.js deleted file mode 100644 index 374f5925cf..0000000000 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/buttons.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from "react"; -import Button from "@appserver/components/button"; -import Text from "@appserver/components/text"; -import { ButtonsWrapper } from "../StyledSecurity"; - -const Buttons = (props) => { - const { t, showReminder, onSaveClick, onCancelClick } = props; - - return ( - -