diff --git a/packages/client/src/Shell.jsx b/packages/client/src/Shell.jsx index 521af8f316..e3f0a21e4c 100644 --- a/packages/client/src/Shell.jsx +++ b/packages/client/src/Shell.jsx @@ -429,13 +429,12 @@ const Shell = ({ items = [], page = "home", ...rest }) => { {toast} {/* */} {withoutNavMenu ? <> : } - {currentDeviceType === DeviceType.mobile && !isFrame && }
- {currentDeviceType !== DeviceType.mobile && !isFrame && } + {!isFrame && }
diff --git a/packages/client/src/components/Layout/MobileLayout.js b/packages/client/src/components/Layout/MobileLayout.js deleted file mode 100644 index 44adc9414a..0000000000 --- a/packages/client/src/components/Layout/MobileLayout.js +++ /dev/null @@ -1,183 +0,0 @@ -// (c) Copyright Ascensio System SIA 2009-2024 -// -// 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 - -import React, { Component, createRef } from "react"; -import { - isDesktop, - isTouchDevice, - getBannerAttribute, -} from "@docspace/shared/utils"; -import { Scrollbar } from "@docspace/shared/components/scrollbar"; -import { LayoutContextProvider } from "./context"; - -import PropTypes from "prop-types"; -import { - isTablet, - isMobile, - isSafari, - isIOS, - isChrome, -} from "react-device-detect"; -class MobileLayout extends Component { - constructor(props) { - super(props); - - this.state = { - prevScrollPosition: window.pageYOffset, - visibleContent: true, - }; - - this.scrollRefPage = createRef(); - } - - componentDidMount() { - this.customScrollElm = document.querySelector( - "#customScrollBar > .scroll-wrapper > .scroller", - ); - - if (!isChrome) this.customScrollElm.scrollTo(0, 0); - - this.customScrollElm.addEventListener( - "scroll", - this.scrolledTheVerticalAxis, - ); - - // this.setState({ visibleContent: true }); - } - - componentWillUnmount() { - this.customScrollElm.removeEventListener( - "scroll", - this.scrolledTheVerticalAxis, - ); - } - - scrolledTheVerticalAxis = () => { - const { prevScrollPosition, visibleContent } = this.state; - const { headerHeight } = getBannerAttribute(); - - const currentScrollPosition = - this.customScrollElm.scrollTop > 0 ? this.customScrollElm.scrollTop : 0; - - if ( - !isDesktop() && - document.getElementsByClassName("backdrop-active").length > 0 && - !this.props.isArticleVisibleOnUnpin - ) { - const elements = document.getElementsByClassName("backdrop-active"); - elements[0].click(); - return; - } - - if (visibleContent && isMobile && !isTouchDevice) { - return; - } - if ( - (isSafari || isIOS) && - this.customScrollElm.scrollHeight - this.customScrollElm.clientHeight < - headerHeight - ) { - if (!this.state.visibleContent) - this.setState({ - visibleContent: true, - }); - return; - } - - if ( - prevScrollPosition - currentScrollPosition > 0 && - currentScrollPosition < headerHeight - ) { - if (!this.state.visibleContent) - this.setState({ - visibleContent: true, - }); - return; - } - - if ( - (isSafari || isIOS) && - Math.abs(currentScrollPosition - prevScrollPosition) <= headerHeight && - currentScrollPosition === 0 - ) { - if (!this.state.visibleContent) - this.setState({ - visibleContent: true, - }); - return; - } - - if (Math.abs(currentScrollPosition - prevScrollPosition) <= headerHeight) { - return; - } - - if (prevScrollPosition === 0 && currentScrollPosition > 100) { - if (Math.abs(currentScrollPosition - prevScrollPosition) <= 104) { - return; - } - } - - let isVisible = prevScrollPosition >= currentScrollPosition; - - if ( - (isSafari || isIOS) && - currentScrollPosition >= - this.customScrollElm.scrollHeight - this.customScrollElm.clientHeight && - this.customScrollElm.scrollHeight !== this.customScrollElm.clientHeight - ) { - isVisible = false; - } - - this.setState({ - prevScrollPosition: currentScrollPosition, - visibleContent: isVisible, - }); - }; - - render() { - const scrollProp = { ref: this.scrollRefPage }; - const { children } = this.props; - - return ( - - - {children} - - - ); - } -} - -MobileLayout.propTypes = { - children: PropTypes.any, -}; - -export default MobileLayout; diff --git a/packages/client/src/components/Layout/context.js b/packages/client/src/components/Layout/context.js deleted file mode 100644 index efba9839f0..0000000000 --- a/packages/client/src/components/Layout/context.js +++ /dev/null @@ -1,32 +0,0 @@ -// (c) Copyright Ascensio System SIA 2009-2024 -// -// 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 - -import { createContext } from "react"; - -const LayoutContext = createContext({}); - -export const LayoutContextProvider = LayoutContext.Provider; -export const LayoutContextConsumer = LayoutContext.Consumer; diff --git a/packages/client/src/components/Layout/index.js b/packages/client/src/components/Layout/index.js index 9b56d7c825..2507c32729 100644 --- a/packages/client/src/components/Layout/index.js +++ b/packages/client/src/components/Layout/index.js @@ -24,18 +24,19 @@ // 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 -import React, { useEffect, useState } from "react"; -import styled, { css } from "styled-components"; import PropTypes from "prop-types"; -import MobileLayout from "./MobileLayout"; +import { inject, observer } from "mobx-react"; +import styled, { css } from "styled-components"; +import React, { useEffect, useState } from "react"; import { useNavigate, useLocation } from "react-router-dom"; +import { isMobile, isMobileOnly } from "react-device-detect"; + +import { Scrollbar } from "@docspace/shared/components/scrollbar"; import { isTablet as isTabletUtils, - isMobile as isMobileUtils, + mobileMore, tablet, } from "@docspace/shared/utils"; -import { isMobile, isMobileOnly } from "react-device-detect"; -import { inject, observer } from "mobx-react"; const StyledContainer = styled.div` user-select: none; @@ -58,6 +59,14 @@ const StyledContainer = styled.div` padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); `} + + @media ${mobileMore} { + #customScrollBar { + > .scroll-wrapper > .scroller > .scroll-body { + padding-inline: 0px !important; + } + } + } `; const Layout = (props) => { @@ -157,7 +166,7 @@ const Layout = (props) => { contentHeight={contentHeight} isPortrait={isPortrait} > - {isMobileUtils() ? : children} + {children} ); }; diff --git a/packages/client/src/components/Main/index.js b/packages/client/src/components/Main/index.js index 94ec64b2b6..273f33a5af 100644 --- a/packages/client/src/components/Main/index.js +++ b/packages/client/src/components/Main/index.js @@ -33,7 +33,7 @@ import { isMobile as isMobileUtils } from "@docspace/shared/utils"; const StyledMain = styled.main` height: ${(props) => props.mainHeight && `${props.mainHeight}px`}; - width: 100vw; + width: 100%; z-index: 0; display: flex; flex-direction: column; diff --git a/packages/client/src/components/NavMenu/index.js b/packages/client/src/components/NavMenu/index.js index 8e967f496f..ab61002f23 100644 --- a/packages/client/src/components/NavMenu/index.js +++ b/packages/client/src/components/NavMenu/index.js @@ -39,7 +39,6 @@ import { withTranslation } from "react-i18next"; import { useNavigate, useLocation } from "react-router-dom"; import { NavMenuHeaderLoader } from "@docspace/shared/skeletons/nav-menu"; -import { LayoutContextConsumer } from "../Layout/context"; import { inject, observer } from "mobx-react"; import PreparationPortalDialog from "../dialogs/PreparationPortalDialog"; @@ -167,47 +166,43 @@ const NavMenu = (props) => { const isPreparationPortal = location.pathname === "/preparation-portal"; return ( - - {(value) => ( - - + + - {!hideHeader && - (isLoaded && isAuthenticated ? ( - <> - {!isPreparationPortal && ( - - )} -
- - ) : !isLoaded && isAuthenticated ? ( - - ) : ( - - ))} + {!hideHeader && + (isLoaded && isAuthenticated ? ( + <> + {!isPreparationPortal && ( + + )} +
+ + ) : !isLoaded && isAuthenticated ? ( + + ) : ( + + ))} - {isAsideAvailable && ( - - )} - + {isAsideAvailable && ( + )} - + ); }; diff --git a/packages/client/src/components/dialogs/CreateEditGroupDialog/sub-components/GroupMemberRow/index.styled.ts b/packages/client/src/components/dialogs/CreateEditGroupDialog/sub-components/GroupMemberRow/index.styled.ts index 499cfff2ca..64fe27fef1 100644 --- a/packages/client/src/components/dialogs/CreateEditGroupDialog/sub-components/GroupMemberRow/index.styled.ts +++ b/packages/client/src/components/dialogs/CreateEditGroupDialog/sub-components/GroupMemberRow/index.styled.ts @@ -44,12 +44,18 @@ export const GroupMemberRow = styled.div<{}>` align-items: flex-start; justify-content: center; padding: 9px 0; + width: 100%; + overflow: hidden; .name { color: ${({ theme }) => theme.sideBarRow.titleColor}; font-size: 14px; font-weight: 600; line-height: 16px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; } .email { @@ -57,6 +63,10 @@ export const GroupMemberRow = styled.div<{}>` font-size: 10px; font-weight: 400; line-height: normal; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; } } diff --git a/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js b/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js index a02a0309a7..4919d3486b 100644 --- a/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js +++ b/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js @@ -425,6 +425,7 @@ const StyledCrossIcon = styled(CrossIcon)` StyledCrossIcon.defaultProps = { theme: Base }; const StyledDeleteIcon = styled(DeleteIcon)` +cursor: pointer; ${(props) => props.theme.interfaceDirection === "rtl" ? css` diff --git a/packages/client/src/components/panels/InvitePanel/sub-components/Item.js b/packages/client/src/components/panels/InvitePanel/sub-components/Item.js index 3c0b8fdff1..be3bc7b83a 100644 --- a/packages/client/src/components/panels/InvitePanel/sub-components/Item.js +++ b/packages/client/src/components/panels/InvitePanel/sub-components/Item.js @@ -50,6 +50,7 @@ import AccessSelector from "./AccessSelector"; const Item = ({ t, item, + theme, setInviteItems, inviteItems, changeInviteItem, @@ -216,7 +217,7 @@ const Item = ({ tooltipContent={t("EmailErrorMessage")} openOnClick={false} size={16} - color="#F21C0E" + color={theme.infoPanel.errorColor} /> { { const { setInviteItems, inviteItems, changeInviteItem } = dialogsStore; const { isOwner } = userStore.user; - const { standalone } = settingsStore; + const { theme, standalone } = settingsStore; return { setInviteItems, @@ -204,5 +205,6 @@ export default inject(({ userStore, dialogsStore, settingsStore }) => { changeInviteItem, isOwner, standalone, + theme, }; })(observer(ItemsList)); diff --git a/packages/client/src/pages/Home/MediaViewer/index.js b/packages/client/src/pages/Home/MediaViewer/index.js index 842cf2a726..514270d30f 100644 --- a/packages/client/src/pages/Home/MediaViewer/index.js +++ b/packages/client/src/pages/Home/MediaViewer/index.js @@ -34,6 +34,7 @@ import { PluginFileType } from "SRC_DIR/helpers/plugins/enums"; import { UrlActionType } from "@docspace/shared/enums"; import MediaViewer from "@docspace/shared/components/media-viewer/MediaViewer"; +import { Portal } from "@docspace/shared/components/portal"; const FilesMediaViewer = (props) => { const { @@ -275,41 +276,46 @@ const FilesMediaViewer = (props) => { return ( visible && ( - + } /> ) ); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager.js index d0b4bdedc4..c558d714c3 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager.js +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager.js @@ -898,7 +898,7 @@ const Manager = (props) => { scale={true} onChange={onChangePage} placeholder={t("EnterPage")} - value={config.filter.page || 1} + value={config.filter.page} isDisabled={!config.filter.count} tabIndex={7} /> diff --git a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/Certificates.js b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/Certificates.js index 15da75aac3..a7d3695844 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/Certificates.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/Certificates.js @@ -65,7 +65,7 @@ const Certificates = (props) => { spShowAdditionalParameters, idpVerifyAlgorithm, spEncryptAlgorithm, - spDecryptAlgorithm, + spSigningAlgorithm, isLoadingXml, isDisabledSpSigning, isDisabledSpEncrypt, @@ -186,7 +186,7 @@ const Certificates = (props) => { name="spSigningAlgorithm" options={verifyAlgorithmsOptions} tabIndex={14} - value={spEncryptAlgorithm} + value={spSigningAlgorithm} /> { name={"spEncryptAlgorithm"} options={decryptAlgorithmsOptions} tabIndex={15} - value={spDecryptAlgorithm} + value={spEncryptAlgorithm} /> )} @@ -220,7 +220,7 @@ export default inject(({ ssoStore }) => { spShowAdditionalParameters, idpVerifyAlgorithm, spEncryptAlgorithm, - spDecryptAlgorithm, + spSigningAlgorithm, isLoadingXml, isDisabledSpSigning, isDisabledSpEncrypt, @@ -237,7 +237,7 @@ export default inject(({ ssoStore }) => { spShowAdditionalParameters, idpVerifyAlgorithm, spEncryptAlgorithm, - spDecryptAlgorithm, + spSigningAlgorithm, isLoadingXml, isDisabledSpSigning, isDisabledSpEncrypt, diff --git a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/index.js b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/index.js index 1b4697ab1b..90156a8721 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/index.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/index.js @@ -58,7 +58,7 @@ const SingleSignOn = (props) => { const isMobileView = currentDeviceType === DeviceType.mobile; useEffect(() => { - isSSOAvailable && !isMobileView && init(); + isSSOAvailable && init(); setDocumentTitle(t("Settings:SingleSignOn")); }, []); diff --git a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/sub-components/SsoComboBox.js b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/sub-components/SsoComboBox.js index 033933de32..5e25020805 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/sub-components/SsoComboBox.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/sub-components/SsoComboBox.js @@ -53,7 +53,7 @@ const SsoComboBox = (props) => { }; return ( - + import("../pages/PortalSettings")); - -const CustomizationSettings = loadable( - () => import("../pages/PortalSettings/categories/common/index.js"), -); -const LanguageAndTimeZoneSettings = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Customization/language-and-time-zone" - ), -); -const WelcomePageSettings = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Customization/welcome-page-settings" - ), -); -const DNSSettings = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Customization/dns-settings" - ), -); -const PortalRenaming = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Customization/portal-renaming" - ), -); -const WhiteLabel = loadable( - () => import("../pages/PortalSettings/categories/common/Branding/whitelabel"), -); -const CompanyInfoSettings = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Branding/companyInfoSettings" - ), -); -const AdditionalResources = loadable( - () => - import( - "../pages/PortalSettings/categories/common/Branding/additionalResources" - ), -); -const SecuritySettings = loadable( - () => import("../pages/PortalSettings/categories/security/index.js"), -); -const TfaPage = loadable( - () => import("../pages/PortalSettings/categories/security/access-portal/tfa"), -); -const PasswordStrengthPage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/passwordStrength" - ), -); -const TrustedMailPage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/trustedMail" - ), -); -const IpSecurityPage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/ipSecurity" - ), -); -const BruteForceProtectionPage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/bruteForceProtection" - ), -); -const AdminMessagePage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/adminMessage" - ), -); -const SessionLifetimePage = loadable( - () => - import( - "../pages/PortalSettings/categories/security/access-portal/sessionLifetime" - ), -); -const Integration = loadable( - () => import("../pages/PortalSettings/categories/integration"), -); -const Payments = loadable( - () => import("../pages/PortalSettings/categories/payments"), -); -const Statistics = loadable( - () => import("../pages/PortalSettings/categories/storage-management"), -); -const QuotaPerRoom = loadable( - () => - import( - "../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerRoom.js" - ), -); -const QuotaPerUser = loadable( - () => - import( - "../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerUser.js" - ), -); -const ThirdParty = loadable( - () => - import( - "../pages/PortalSettings/categories/integration/ThirdPartyServicesSettings" - ), +const PortalSettings = loadable(() => + componentLoader(() => import("../pages/PortalSettings")), ); -const DocumentService = loadable( - () => - import("../pages/PortalSettings/categories/integration/DocumentService"), +const CustomizationSettings = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/common/index.js"), + ), +); +const LanguageAndTimeZoneSettings = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/common/Customization/language-and-time-zone" + ), + ), +); +const WelcomePageSettings = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/common/Customization/welcome-page-settings" + ), + ), +); +const DNSSettings = loadable(() => + componentLoader( + () => () => + import( + "../pages/PortalSettings/categories/common/Customization/dns-settings" + ), + ), +); +const PortalRenaming = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/common/Customization/portal-renaming" + ), + ), +); +const WhiteLabel = loadable(() => + componentLoader( + () => + import("../pages/PortalSettings/categories/common/Branding/whitelabel"), + ), +); +const CompanyInfoSettings = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/common/Branding/companyInfoSettings" + ), + ), +); +const AdditionalResources = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/common/Branding/additionalResources" + ), + ), +); +const SecuritySettings = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/security/index.js"), + ), +); +const TfaPage = loadable(() => + componentLoader( + () => + import("../pages/PortalSettings/categories/security/access-portal/tfa"), + ), +); +const PasswordStrengthPage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/passwordStrength" + ), + ), +); +const TrustedMailPage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/trustedMail" + ), + ), +); +const IpSecurityPage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/ipSecurity" + ), + ), +); +const BruteForceProtectionPage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/bruteForceProtection" + ), + ), +); +const AdminMessagePage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/adminMessage" + ), + ), +); +const SessionLifetimePage = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/security/access-portal/sessionLifetime" + ), + ), +); +const Integration = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/integration"), + ), +); +const Payments = loadable(() => + componentLoader(() => import("../pages/PortalSettings/categories/payments")), +); +const Statistics = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/storage-management"), + ), +); +const QuotaPerRoom = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerRoom.js" + ), + ), +); +const QuotaPerUser = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerUser.js" + ), + ), +); +const ThirdParty = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/integration/ThirdPartyServicesSettings" + ), + ), ); -const SingleSignOn = loadable( - () => import("../pages/PortalSettings/categories/integration/SingleSignOn"), -); -const SPSettings = loadable( - () => - import( - "../pages/PortalSettings/categories/integration/SingleSignOn/SPSettings" - ), -); -const SPMetadata = loadable( - () => - import( - "../pages/PortalSettings/categories/integration/SingleSignOn/ProviderMetadata" - ), +const DocumentService = loadable(() => + componentLoader( + () => + import("../pages/PortalSettings/categories/integration/DocumentService"), + ), ); -const DeveloperTools = loadable( - () => import("../pages/PortalSettings/categories/developer-tools/index.js"), +const SingleSignOn = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/integration/SingleSignOn"), + ), +); +const SPSettings = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/integration/SingleSignOn/SPSettings" + ), + ), +); +const SPMetadata = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/integration/SingleSignOn/ProviderMetadata" + ), + ), ); -const DataImport = loadable( - () => import("../pages/PortalSettings/categories/data-import/index.js"), -); -const GoogleDataImport = loadable( - () => - import( - "../pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js" - ), -); -const NextcloudDataImport = loadable( - () => - import( - "../pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js" - ), -); -const OnlyofficeDataImport = loadable( - () => - import( - "../pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js" - ), +const DeveloperTools = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/developer-tools/index.js"), + ), ); -const WebhookHistory = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookHistory" - ), +const DataImport = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/data-import/index.js"), + ), ); -const WebhookDetails = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookEventDetails" - ), +const GoogleDataImport = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js" + ), + ), ); -const Backup = loadable( - () => import("../pages/PortalSettings/categories/data-management/index"), +const NextcloudDataImport = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js" + ), + ), ); -const DeleteDataPage = loadable( - () => import("../pages/PortalSettings/categories/delete-data"), +const OnlyofficeDataImport = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js" + ), + ), ); -const RestoreBackup = loadable( - () => - import( - "../pages/PortalSettings/categories/data-management/backup/restore-backup/index" - ), -); -const Bonus = loadable(() => import("../pages/Bonus")); -const DocSpace = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/DocSpace" - ), +const WebhookHistory = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookHistory" + ), + ), ); -const SimpleRoom = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/SimpleRoom" - ), +const WebhookDetails = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookEventDetails" + ), + ), ); -const Manager = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager" - ), +const Backup = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/data-management/index"), + ), ); -const RoomSelector = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/RoomSelector" - ), +const DeleteDataPage = loadable(() => + componentLoader( + () => import("../pages/PortalSettings/categories/delete-data"), + ), ); -const FileSelector = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/FileSelector" - ), +const RestoreBackup = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/data-management/backup/restore-backup/index" + ), + ), ); -const Editor = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Editor" - ), +const Bonus = loadable(() => componentLoader(() => import("../pages/Bonus"))); + +const DocSpace = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/DocSpace" + ), + ), ); -const Viewer = loadable( - () => - import( - "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Viewer" - ), +const SimpleRoom = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/SimpleRoom" + ), + ), +); +const Manager = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager" + ), + ), +); +const RoomSelector = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/RoomSelector" + ), + ), +); +const FileSelector = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/FileSelector" + ), + ), +); +const Editor = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Editor" + ), + ), +); +const Viewer = loadable(() => + componentLoader( + () => + import( + "../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Viewer" + ), + ), ); const PortalSettingsRoutes = { diff --git a/packages/client/src/store/GroupsStore.ts b/packages/client/src/store/GroupsStore.ts index 1eae05429f..cd3c8b07f0 100644 --- a/packages/client/src/store/GroupsStore.ts +++ b/packages/client/src/store/GroupsStore.ts @@ -651,6 +651,8 @@ class GroupsStore { }; changeGroupContextSelection = (group: TGroup, isSingleMenu: boolean) => { + this.peopleStore.selectionStore.setBufferSelection(null); + if (isSingleMenu) { this.singleContextMenuAction(group); } else { diff --git a/packages/client/webpack.config.js b/packages/client/webpack.config.js index 8c6833c04d..5d5f20186e 100644 --- a/packages/client/webpack.config.js +++ b/packages/client/webpack.config.js @@ -338,7 +338,6 @@ module.exports = (env, argv) => { "./shell": "./src/Shell", "./store": "./src/store", "./Layout": "./src/components/Layout", - "./Layout/context": "./src/components/Layout/context.js", "./Main": "./src/components/Main", "./NavMenu": "./src/components/NavMenu", "./PreparationPortalDialog": diff --git a/packages/doceditor/src/app/(root)/create/page.tsx b/packages/doceditor/src/app/(root)/create/page.tsx index c9c2b8a32a..10f3502c61 100644 --- a/packages/doceditor/src/app/(root)/create/page.tsx +++ b/packages/doceditor/src/app/(root)/create/page.tsx @@ -120,7 +120,7 @@ async function Page({ searchParams }: { searchParams: TSearchParams }) { searchParams.append("action", action); } - const redirectURL = `${baseURL}/doceditor?${searchParams.toString()}`; + const redirectURL = `/doceditor?${searchParams.toString()}`; return permanentRedirect(redirectURL); } diff --git a/packages/doceditor/src/utils/actions.ts b/packages/doceditor/src/utils/actions.ts index 6ccb4e3e4a..8e5f361ea4 100644 --- a/packages/doceditor/src/utils/actions.ts +++ b/packages/doceditor/src/utils/actions.ts @@ -28,10 +28,7 @@ import { headers } from "next/headers"; -import { - createRequest, - getBaseUrl, -} from "@docspace/shared/utils/next-ssr-helper"; +import { createRequest } from "@docspace/shared/utils/next-ssr-helper"; import { TenantStatus, EditorConfigErrorType } from "@docspace/shared/enums"; import type { TDocServiceLocation, @@ -80,6 +77,7 @@ export async function fileCopyAs( enableExternalExt, password, }), + false, ); const file = await (await fetch(createFile)).json(); @@ -141,6 +139,7 @@ export async function createFile( [["Content-Type", "application/json;charset=utf-8"]], "POST", JSON.stringify({ title, templateId, formId }), + false, ); const file = await (await fetch(createFile)).json(); @@ -311,6 +310,8 @@ export async function getUser(share?: string) { [`/people/@self`], [share ? ["Request-Token", share] : ["", ""]], "GET", + undefined, + false, ); if (!cookie?.includes("asc_auth_key")) return undefined; @@ -335,6 +336,8 @@ export async function getSettings(share?: string) { ], [share ? ["Request-Token", share] : ["", ""]], "GET", + undefined, + false, ); const settingsRes = await fetch(getSettings); @@ -360,6 +363,7 @@ export async function checkFillFromDraft( ], "POST", JSON.stringify({ fileId: templateFileId }), + false, ); const response = await fetch(checkFillFormDraft); @@ -383,6 +387,8 @@ export async function openEdit( [`/files/file/${fileId}/openedit?${searchParams}`], [share ? ["Request-Token", share] : ["", ""]], "GET", + undefined, + false, ); const res = await fetch(getConfig); @@ -442,6 +448,8 @@ export async function getEditorUrl( [`/files/docservice?${editorSearchParams ? editorSearchParams : ""}`], [share ? ["Request-Token", share] : ["", ""]], "GET", + undefined, + false, ); const res = await fetch(request); diff --git a/packages/login/src/middleware.ts b/packages/login/src/middleware.ts index 374d2129d5..357020289e 100644 --- a/packages/login/src/middleware.ts +++ b/packages/login/src/middleware.ts @@ -32,7 +32,7 @@ export function middleware(request: NextRequest) { const host = request.headers.get("x-forwarded-host"); const proto = request.headers.get("x-forwarded-proto"); - const redirectUrl = `${proto}:${host}`; + const redirectUrl = `${proto}://${host}`; if (request.nextUrl.pathname === "/health") { console.log("Get login health check for portal: ", redirectUrl); diff --git a/packages/login/src/utils/actions.ts b/packages/login/src/utils/actions.ts index 93c714c2bb..4edc5c616b 100644 --- a/packages/login/src/utils/actions.ts +++ b/packages/login/src/utils/actions.ts @@ -54,7 +54,7 @@ export const checkIsAuthenticated = async () => { export async function getSettings() { const [getSettings] = createRequest( - [`/settings?withPassword=false`], + [`/settings?withPassword=true`], [["", ""]], "GET", ); diff --git a/packages/shared/components/context-menu-button/ContextMenuButton.tsx b/packages/shared/components/context-menu-button/ContextMenuButton.tsx index 5e60625d28..a304537ab0 100644 --- a/packages/shared/components/context-menu-button/ContextMenuButton.tsx +++ b/packages/shared/components/context-menu-button/ContextMenuButton.tsx @@ -348,7 +348,7 @@ ContextMenuButtonPure.defaultProps = { size: 16, isDisabled: false, directionX: "left", - isFill: false, + isFill: true, usePortal: true, displayIconBorder: false, diff --git a/packages/shared/components/link/Link.styled.tsx b/packages/shared/components/link/Link.styled.tsx index a7641fcb25..b94bbfffd0 100644 --- a/packages/shared/components/link/Link.styled.tsx +++ b/packages/shared/components/link/Link.styled.tsx @@ -52,6 +52,7 @@ const PureText = ({ const StyledText = styled(PureText)` text-decoration: ${(props) => props.theme.link.textDecoration}; + text-underline-offset: 2px; ${(props) => props.enableUserSelect diff --git a/packages/shared/components/media-viewer/MediaViewer.styled.ts b/packages/shared/components/media-viewer/MediaViewer.styled.ts index 47ee110586..48a121d056 100644 --- a/packages/shared/components/media-viewer/MediaViewer.styled.ts +++ b/packages/shared/components/media-viewer/MediaViewer.styled.ts @@ -140,6 +140,7 @@ export const StyledSwitchToolbar = styled.div` display: block; opacity: 0; transition: all 0.3s; + top: 0; ${(props) => props.left ? "left: 0" : props.isPDFFile ? "right: 20px" : "right: 0"}; @@ -154,7 +155,7 @@ export const StyledViewerContainer = styled.div` color: ${(props) => props.theme.mediaViewer.color}; display: ${(props) => (props.visible ? "block" : "none")}; overflow: hidden; - span { + > span { position: fixed; ${(props) => props.theme.interfaceDirection === "rtl" diff --git a/packages/shared/components/media-viewer/sub-components/ImageViewer/ImageViewer.props.ts b/packages/shared/components/media-viewer/sub-components/ImageViewer/ImageViewer.props.ts index 0281112bb9..6dcf2a90c9 100644 --- a/packages/shared/components/media-viewer/sub-components/ImageViewer/ImageViewer.props.ts +++ b/packages/shared/components/media-viewer/sub-components/ImageViewer/ImageViewer.props.ts @@ -39,6 +39,7 @@ interface ImageViewerProps { isFistImage: boolean; isLastImage: boolean; panelVisible: boolean; + isPublicFile?: boolean; mobileDetails: JSX.Element; toolbar: ReturnType; devices: DevicesType; diff --git a/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx b/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx index 7947ed0a20..756bdf930c 100644 --- a/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx +++ b/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx @@ -93,6 +93,7 @@ export const ImageViewer = ({ contextModel, errorTitle, devices, + isPublicFile, }: ImageViewerProps) => { const imgRef = useRef(null); const imgWrapperRef = useRef(null); @@ -523,7 +524,7 @@ export const ImageViewer = ({ : dx, y: dy, opacity: - style.scale.get() === 1 && !isDesktop && mdy > 0 + style.scale.get() === 1 && !isDesktop && mdy > 0 && !isPublicFile ? imgRef.current.height / 10 / mdy : style.opacity.get(), immediate: true, @@ -541,7 +542,7 @@ export const ImageViewer = ({ cancel(); } - if (style.scale.get() === 1 && !isDesktop) { + if (style.scale.get() === 1 && !isDesktop && !isPublicFile) { if (mdx < -imgRef.current.width / 4) { return onNext?.(); } diff --git a/packages/shared/components/media-viewer/sub-components/Viewer/index.tsx b/packages/shared/components/media-viewer/sub-components/Viewer/index.tsx index 1247fa83aa..c982ece042 100644 --- a/packages/shared/components/media-viewer/sub-components/Viewer/index.tsx +++ b/packages/shared/components/media-viewer/sub-components/Viewer/index.tsx @@ -33,7 +33,6 @@ import React, { } from "react"; import { DeviceType } from "@docspace/shared/enums"; -import { Portal } from "@docspace/shared/components/portal"; import { includesMethod } from "@docspace/shared/utils/typeGuards"; import type { TContextMenuRef } from "@docspace/shared/components/context-menu"; @@ -251,91 +250,78 @@ export const Viewer = (props: ViewerProps) => { )} {isImage ? ( - - } + ) : isVideo || isAudio ? ( - - } + ) : ( isPdf && ( - - } + ) )} diff --git a/packages/shared/components/media-viewer/sub-components/ViewerToolbar/index.tsx b/packages/shared/components/media-viewer/sub-components/ViewerToolbar/index.tsx index bda72d8010..5593aff92b 100644 --- a/packages/shared/components/media-viewer/sub-components/ViewerToolbar/index.tsx +++ b/packages/shared/components/media-viewer/sub-components/ViewerToolbar/index.tsx @@ -24,9 +24,17 @@ // 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 -import React, { forwardRef, useImperativeHandle, useState } from "react"; +import React, { + forwardRef, + useImperativeHandle, + useRef, + useState, +} from "react"; import MediaContextMenu from "PUBLIC_DIR/images/vertical-dots.react.svg"; + +import { useClickOutside } from "../../../../utils/useClickOutside"; + import ImageViewerToolbarProps, { ImperativeHandle, ToolbarItemType, @@ -50,11 +58,17 @@ const ViewerToolbar = forwardRef( }, ref, ) => { + const contextMenuRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); const [percent, setPercent] = useState(() => Math.round(percentValue * 100), ); + useClickOutside(contextMenuRef, () => { + setIsOpen(false); + }); + useImperativeHandle( ref, () => { @@ -71,6 +85,7 @@ const ViewerToolbar = forwardRef( const contextMenu = generateContextMenu(isOpen); return ( { diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index 6948ef9350..e719eb6d1e 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -2094,6 +2094,7 @@ export const getBaseTheme = () => { borderColor: grayLightMid, thumbnailBorderColor: grayLightMid, textColor: black, + errorColor: "#F21C0E", closeButtonWrapperPadding: "0px", closeButtonIcon: white, diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index 3d7daf1ebb..13536754d9 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -2067,6 +2067,7 @@ const Dark: TTheme = { borderColor: "#474747", thumbnailBorderColor: grayLightMid, textColor: white, + errorColor: "#E06451", closeButtonWrapperPadding: "6px", closeButtonIcon: black, diff --git a/packages/shared/utils/next-ssr-helper.ts b/packages/shared/utils/next-ssr-helper.ts index 13466f1a56..1a2a1a2e47 100644 --- a/packages/shared/utils/next-ssr-helper.ts +++ b/packages/shared/utils/next-ssr-helper.ts @@ -34,13 +34,17 @@ export const getBaseUrl = () => { const host = hdrs.get("x-forwarded-host"); const proto = hdrs.get("x-forwarded-proto"); - const baseURL = `${proto}:${host}`; + const baseURL = `${proto}://${host}`; return baseURL; }; -export const getAPIUrl = () => { - const baseUrl = process.env.API_HOST?.trim() ?? getBaseUrl(); +export const getAPIUrl = (internalRequest: boolean) => { + const baseUrl = internalRequest + ? process.env.API_HOST?.trim() ?? getBaseUrl() + : getBaseUrl(); + + // const baseUrl = getBaseUrl(); const baseAPIUrl = `${baseUrl}/${API_PREFIX}`; @@ -52,18 +56,19 @@ export const createRequest = ( newHeaders: [string, string][], method: string, body?: string, + internalRequest: boolean = true, ) => { const hdrs = new Headers(headers()); - const apiURL = getAPIUrl(); + const apiURL = getAPIUrl(internalRequest); newHeaders.forEach((hdr) => { if (hdr[0]) hdrs.set(hdr[0], hdr[1]); }); - const host = hdrs.get("x-forwarded-host"); + const baseURL = getBaseUrl(); - if (host && process.env.API_HOST?.trim()) hdrs.set("origin", host); + if (baseURL && process.env.API_HOST?.trim()) hdrs.set("origin", baseURL); const urls = paths.map((path) => `${apiURL}${path}`); diff --git a/packages/shared/utils/useClickOutside.ts b/packages/shared/utils/useClickOutside.ts index 11aa3d1cf9..558d137bde 100644 --- a/packages/shared/utils/useClickOutside.ts +++ b/packages/shared/utils/useClickOutside.ts @@ -28,12 +28,12 @@ "use client"; -import { useEffect } from "react"; +import { DependencyList, RefObject, useEffect } from "react"; -export const useClickOutside = ( - ref: { current: HTMLElement }, - handler: () => void, - ...deps: unknown[] +export const useClickOutside = ( + ref: RefObject, + handler: VoidFunction, + ...deps: DependencyList ) => { useEffect(() => { const handleClickOutside = (e: MouseEvent) => {