Merge branch 'develop' into feature/templates
This commit is contained in:
commit
657e6ee609
@ -429,13 +429,12 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
|
||||
{toast}
|
||||
{/* <ReactSmartBanner t={t} ready={ready} /> */}
|
||||
{withoutNavMenu ? <></> : <NavMenu />}
|
||||
{currentDeviceType === DeviceType.mobile && !isFrame && <MainBar />}
|
||||
<IndicatorLoader />
|
||||
<ScrollToTop />
|
||||
<DialogsWrapper t={t} />
|
||||
|
||||
<Main isDesktop={isDesktop}>
|
||||
{currentDeviceType !== DeviceType.mobile && !isFrame && <MainBar />}
|
||||
{!isFrame && <MainBar />}
|
||||
<div className="main-container">
|
||||
<Outlet />
|
||||
</div>
|
||||
|
@ -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 (
|
||||
<Scrollbar id="customScrollBar" {...scrollProp}>
|
||||
<LayoutContextProvider
|
||||
value={{
|
||||
scrollRefLayout: this.scrollRefPage,
|
||||
isVisible: this.state.visibleContent,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LayoutContextProvider>
|
||||
</Scrollbar>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MobileLayout.propTypes = {
|
||||
children: PropTypes.any,
|
||||
};
|
||||
|
||||
export default MobileLayout;
|
@ -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;
|
@ -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() ? <MobileLayout {...props} /> : children}
|
||||
<Scrollbar id="customScrollBar">{children}</Scrollbar>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 (
|
||||
<LayoutContextConsumer>
|
||||
{(value) => (
|
||||
<StyledContainer isLoaded={isLoaded} isVisible={value.isVisible}>
|
||||
<Backdrop
|
||||
visible={isBackdropVisible}
|
||||
onClick={backdropClick}
|
||||
withBackground={true}
|
||||
withBlur={true}
|
||||
/>
|
||||
<StyledContainer isLoaded={isLoaded}>
|
||||
<Backdrop
|
||||
visible={isBackdropVisible}
|
||||
onClick={backdropClick}
|
||||
withBackground={true}
|
||||
withBlur={true}
|
||||
/>
|
||||
|
||||
{!hideHeader &&
|
||||
(isLoaded && isAuthenticated ? (
|
||||
<>
|
||||
{!isPreparationPortal && (
|
||||
<HeaderNav hideProfileMenu={hideProfileMenu} />
|
||||
)}
|
||||
<Header
|
||||
customHeader={customHeader}
|
||||
isPreparationPortal={isPreparationPortal}
|
||||
isNavOpened={isNavOpened}
|
||||
onClick={showNav}
|
||||
onNavMouseEnter={handleNavMouseEnter}
|
||||
onNavMouseLeave={handleNavMouseLeave}
|
||||
toggleAside={toggleAside}
|
||||
backdropClick={backdropClick}
|
||||
/>
|
||||
</>
|
||||
) : !isLoaded && isAuthenticated ? (
|
||||
<NavMenuHeaderLoader />
|
||||
) : (
|
||||
<HeaderUnAuth />
|
||||
))}
|
||||
{!hideHeader &&
|
||||
(isLoaded && isAuthenticated ? (
|
||||
<>
|
||||
{!isPreparationPortal && (
|
||||
<HeaderNav hideProfileMenu={hideProfileMenu} />
|
||||
)}
|
||||
<Header
|
||||
customHeader={customHeader}
|
||||
isPreparationPortal={isPreparationPortal}
|
||||
isNavOpened={isNavOpened}
|
||||
onClick={showNav}
|
||||
onNavMouseEnter={handleNavMouseEnter}
|
||||
onNavMouseLeave={handleNavMouseLeave}
|
||||
toggleAside={toggleAside}
|
||||
backdropClick={backdropClick}
|
||||
/>
|
||||
</>
|
||||
) : !isLoaded && isAuthenticated ? (
|
||||
<NavMenuHeaderLoader />
|
||||
) : (
|
||||
<HeaderUnAuth />
|
||||
))}
|
||||
|
||||
{isAsideAvailable && (
|
||||
<Aside visible={isAsideVisible} onClick={backdropClick}>
|
||||
{asideContent}
|
||||
</Aside>
|
||||
)}
|
||||
</StyledContainer>
|
||||
{isAsideAvailable && (
|
||||
<Aside visible={isAsideVisible} onClick={backdropClick}>
|
||||
{asideContent}
|
||||
</Aside>
|
||||
)}
|
||||
</LayoutContextConsumer>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,6 +425,7 @@ const StyledCrossIcon = styled(CrossIcon)`
|
||||
StyledCrossIcon.defaultProps = { theme: Base };
|
||||
|
||||
const StyledDeleteIcon = styled(DeleteIcon)`
|
||||
cursor: pointer;
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
|
@ -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}
|
||||
/>
|
||||
<StyledDeleteIcon
|
||||
className="delete-icon"
|
||||
|
@ -66,6 +66,7 @@ const Row = memo(({ data, index, style }) => {
|
||||
<Item
|
||||
t={t}
|
||||
item={item}
|
||||
theme={theme}
|
||||
setInviteItems={setInviteItems}
|
||||
changeInviteItem={changeInviteItem}
|
||||
inviteItems={inviteItems}
|
||||
@ -196,7 +197,7 @@ const ItemsList = ({
|
||||
export default inject(({ userStore, dialogsStore, settingsStore }) => {
|
||||
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));
|
||||
|
@ -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 && (
|
||||
<MediaViewer
|
||||
t={t}
|
||||
files={files}
|
||||
getIcon={getIcon}
|
||||
visible={visible}
|
||||
playlist={playlist}
|
||||
prevMedia={prevMedia}
|
||||
nextMedia={nextMedia}
|
||||
onCopyLink={onCopyLink}
|
||||
userAccess={userAccess}
|
||||
onChangeUrl={onChangeUrl}
|
||||
isPreviewFile={firstLoad}
|
||||
onDuplicate={onDuplicate}
|
||||
onMoveAction={onMoveAction}
|
||||
onCopyAction={onCopyAction}
|
||||
onClose={onMediaViewerClose}
|
||||
onDelete={onDeleteMediaFile}
|
||||
onClickRename={onClickRename}
|
||||
onClickDelete={onClickDelete}
|
||||
setActiveFiles={setActiveFiles}
|
||||
archiveRoomsId={archiveRoomsId}
|
||||
onPreviewClick={onPreviewClick}
|
||||
onDownload={onDownloadMediaFile}
|
||||
onClickLinkEdit={onClickLinkEdit}
|
||||
onClickDownload={onClickDownload}
|
||||
onShowInfoPanel={onShowInfoPanel}
|
||||
playlistPos={currentPostionIndex}
|
||||
currentFileId={currentMediaFileId}
|
||||
onClickDownloadAs={onClickDownloadAs}
|
||||
currentDeviceType={currentDeviceType}
|
||||
extsImagePreviewed={extsImagePreviewed}
|
||||
setBufferSelection={setBufferSelection}
|
||||
onEmptyPlaylistError={onMediaViewerClose}
|
||||
deleteDialogVisible={deleteDialogVisible}
|
||||
pluginContextMenuItems={pluginContextMenuItems}
|
||||
<Portal
|
||||
visible
|
||||
element={
|
||||
<MediaViewer
|
||||
t={t}
|
||||
files={files}
|
||||
getIcon={getIcon}
|
||||
visible={visible}
|
||||
playlist={playlist}
|
||||
prevMedia={prevMedia}
|
||||
nextMedia={nextMedia}
|
||||
onCopyLink={onCopyLink}
|
||||
userAccess={userAccess}
|
||||
onChangeUrl={onChangeUrl}
|
||||
isPreviewFile={firstLoad}
|
||||
onDuplicate={onDuplicate}
|
||||
onMoveAction={onMoveAction}
|
||||
onCopyAction={onCopyAction}
|
||||
onClose={onMediaViewerClose}
|
||||
onDelete={onDeleteMediaFile}
|
||||
onClickRename={onClickRename}
|
||||
onClickDelete={onClickDelete}
|
||||
setActiveFiles={setActiveFiles}
|
||||
archiveRoomsId={archiveRoomsId}
|
||||
onPreviewClick={onPreviewClick}
|
||||
onDownload={onDownloadMediaFile}
|
||||
onClickLinkEdit={onClickLinkEdit}
|
||||
onClickDownload={onClickDownload}
|
||||
onShowInfoPanel={onShowInfoPanel}
|
||||
playlistPos={currentPostionIndex}
|
||||
currentFileId={currentMediaFileId}
|
||||
onClickDownloadAs={onClickDownloadAs}
|
||||
currentDeviceType={currentDeviceType}
|
||||
extsImagePreviewed={extsImagePreviewed}
|
||||
setBufferSelection={setBufferSelection}
|
||||
onEmptyPlaylistError={onMediaViewerClose}
|
||||
deleteDialogVisible={deleteDialogVisible}
|
||||
pluginContextMenuItems={pluginContextMenuItems}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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}
|
||||
/>
|
||||
|
||||
<SsoComboBox
|
||||
@ -195,7 +195,7 @@ const Certificates = (props) => {
|
||||
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,
|
||||
|
@ -58,7 +58,7 @@ const SingleSignOn = (props) => {
|
||||
const isMobileView = currentDeviceType === DeviceType.mobile;
|
||||
|
||||
useEffect(() => {
|
||||
isSSOAvailable && !isMobileView && init();
|
||||
isSSOAvailable && init();
|
||||
setDocumentTitle(t("Settings:SingleSignOn"));
|
||||
}, []);
|
||||
|
||||
|
@ -53,7 +53,7 @@ const SsoComboBox = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<FieldContainer isVertical labelText={labelText}>
|
||||
<FieldContainer isVertical labelVisible labelText={labelText}>
|
||||
<StyledInputWrapper>
|
||||
<ComboBox
|
||||
id={name}
|
||||
|
@ -28,241 +28,330 @@ import React from "react";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import loadable from "@loadable/component";
|
||||
|
||||
import Error404 from "@docspace/shared/components/errors/Error404";
|
||||
import componentLoader from "@docspace/shared/utils/component-loader";
|
||||
|
||||
import PrivateRoute from "../components/PrivateRouteWrapper";
|
||||
import ErrorBoundary from "../components/ErrorBoundaryWrapper";
|
||||
|
||||
import Error404 from "@docspace/shared/components/errors/Error404";
|
||||
|
||||
import { generalRoutes } from "./general";
|
||||
|
||||
const PortalSettings = loadable(() => 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 = {
|
||||
|
@ -651,6 +651,8 @@ class GroupsStore {
|
||||
};
|
||||
|
||||
changeGroupContextSelection = (group: TGroup, isSingleMenu: boolean) => {
|
||||
this.peopleStore.selectionStore.setBufferSelection(null);
|
||||
|
||||
if (isSingleMenu) {
|
||||
this.singleContextMenuAction(group);
|
||||
} else {
|
||||
|
@ -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":
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -54,7 +54,7 @@ export const checkIsAuthenticated = async () => {
|
||||
|
||||
export async function getSettings() {
|
||||
const [getSettings] = createRequest(
|
||||
[`/settings?withPassword=false`],
|
||||
[`/settings?withPassword=true`],
|
||||
[["", ""]],
|
||||
"GET",
|
||||
);
|
||||
|
@ -348,7 +348,7 @@ ContextMenuButtonPure.defaultProps = {
|
||||
size: 16,
|
||||
isDisabled: false,
|
||||
directionX: "left",
|
||||
isFill: false,
|
||||
isFill: true,
|
||||
|
||||
usePortal: true,
|
||||
displayIconBorder: false,
|
||||
|
@ -52,6 +52,7 @@ const PureText = ({
|
||||
|
||||
const StyledText = styled(PureText)`
|
||||
text-decoration: ${(props) => props.theme.link.textDecoration};
|
||||
text-underline-offset: 2px;
|
||||
|
||||
${(props) =>
|
||||
props.enableUserSelect
|
||||
|
@ -140,6 +140,7 @@ export const StyledSwitchToolbar = styled.div<StyledSwitchToolbarProps>`
|
||||
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<StyledViewerContainerProps>`
|
||||
color: ${(props) => props.theme.mediaViewer.color};
|
||||
display: ${(props) => (props.visible ? "block" : "none")};
|
||||
overflow: hidden;
|
||||
span {
|
||||
> span {
|
||||
position: fixed;
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
|
@ -39,6 +39,7 @@ interface ImageViewerProps {
|
||||
isFistImage: boolean;
|
||||
isLastImage: boolean;
|
||||
panelVisible: boolean;
|
||||
isPublicFile?: boolean;
|
||||
mobileDetails: JSX.Element;
|
||||
toolbar: ReturnType<typeof getCustomToolbar>;
|
||||
devices: DevicesType;
|
||||
|
@ -93,6 +93,7 @@ export const ImageViewer = ({
|
||||
contextModel,
|
||||
errorTitle,
|
||||
devices,
|
||||
isPublicFile,
|
||||
}: ImageViewerProps) => {
|
||||
const imgRef = useRef<HTMLImageElement>(null);
|
||||
const imgWrapperRef = useRef<HTMLDivElement>(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?.();
|
||||
}
|
||||
|
@ -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 ? (
|
||||
<Portal
|
||||
visible
|
||||
element={
|
||||
<ImageViewer
|
||||
isTiff={isTiff}
|
||||
devices={devices}
|
||||
toolbar={toolbar}
|
||||
errorTitle={errorTitle}
|
||||
panelVisible={panelVisible}
|
||||
mobileDetails={mobileDetails}
|
||||
imageId={playlistFile.fileId}
|
||||
version={playlistFile.version}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
thumbnailSrc={playlistFile.thumbnailUrl}
|
||||
src={fileUrl}
|
||||
onMask={onMaskClick}
|
||||
onPrev={onPrevClick}
|
||||
onNext={onNextClick}
|
||||
contextModel={contextModel}
|
||||
generateContextMenu={generateContextMenu}
|
||||
setIsOpenContextMenu={setIsOpenContextMenu}
|
||||
resetToolbarVisibleTimer={resetToolbarVisibleTimer}
|
||||
/>
|
||||
}
|
||||
<ImageViewer
|
||||
key={fileUrl}
|
||||
isTiff={isTiff}
|
||||
devices={devices}
|
||||
toolbar={toolbar}
|
||||
errorTitle={errorTitle}
|
||||
panelVisible={panelVisible}
|
||||
mobileDetails={mobileDetails}
|
||||
imageId={playlistFile.fileId}
|
||||
version={playlistFile.version}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
thumbnailSrc={playlistFile.thumbnailUrl}
|
||||
src={fileUrl}
|
||||
onMask={onMaskClick}
|
||||
onPrev={onPrevClick}
|
||||
onNext={onNextClick}
|
||||
contextModel={contextModel}
|
||||
generateContextMenu={generateContextMenu}
|
||||
setIsOpenContextMenu={setIsOpenContextMenu}
|
||||
resetToolbarVisibleTimer={resetToolbarVisibleTimer}
|
||||
isPublicFile={isPublicFile}
|
||||
/>
|
||||
) : isVideo || isAudio ? (
|
||||
<Portal
|
||||
visible
|
||||
element={
|
||||
<ViewerPlayer
|
||||
isError={isError}
|
||||
src={fileUrl}
|
||||
devices={devices}
|
||||
isAudio={isAudio}
|
||||
isVideo={isVideo}
|
||||
audioIcon={audioIcon}
|
||||
errorTitle={errorTitle}
|
||||
panelVisible={panelVisible}
|
||||
isFullScreen={isFullscreen}
|
||||
isPreviewFile={isPreviewFile}
|
||||
mobileDetails={mobileDetails}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
isOpenContextMenu={isOpenContextMenu}
|
||||
thumbnailSrc={playlistFile.thumbnailUrl}
|
||||
canDownload={!!targetFile?.security.Download}
|
||||
onPrev={onPrevClick}
|
||||
onNext={onNextClick}
|
||||
setIsError={setIsError}
|
||||
onMask={handleMaskClick}
|
||||
contextModel={contextModel}
|
||||
setPanelVisible={setPanelVisible}
|
||||
setIsFullScreen={setIsFullScreen}
|
||||
onDownloadClick={onDownloadClick}
|
||||
generateContextMenu={generateContextMenu}
|
||||
removeToolbarVisibleTimer={removeToolbarVisibleTimer}
|
||||
removePanelVisibleTimeout={removePanelVisibleTimeout}
|
||||
restartToolbarVisibleTimer={restartToolbarVisibleTimer}
|
||||
isThirdParty={targetFile?.providerItem}
|
||||
/>
|
||||
}
|
||||
<ViewerPlayer
|
||||
isError={isError}
|
||||
src={fileUrl}
|
||||
devices={devices}
|
||||
isAudio={isAudio}
|
||||
isVideo={isVideo}
|
||||
audioIcon={audioIcon}
|
||||
errorTitle={errorTitle}
|
||||
panelVisible={panelVisible}
|
||||
isFullScreen={isFullscreen}
|
||||
isPreviewFile={isPreviewFile}
|
||||
mobileDetails={mobileDetails}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
isOpenContextMenu={isOpenContextMenu}
|
||||
thumbnailSrc={playlistFile.thumbnailUrl}
|
||||
canDownload={!!targetFile?.security.Download}
|
||||
onPrev={onPrevClick}
|
||||
onNext={onNextClick}
|
||||
setIsError={setIsError}
|
||||
onMask={handleMaskClick}
|
||||
contextModel={contextModel}
|
||||
setPanelVisible={setPanelVisible}
|
||||
setIsFullScreen={setIsFullScreen}
|
||||
onDownloadClick={onDownloadClick}
|
||||
generateContextMenu={generateContextMenu}
|
||||
removeToolbarVisibleTimer={removeToolbarVisibleTimer}
|
||||
removePanelVisibleTimeout={removePanelVisibleTimeout}
|
||||
restartToolbarVisibleTimer={restartToolbarVisibleTimer}
|
||||
isThirdParty={targetFile?.providerItem}
|
||||
/>
|
||||
) : (
|
||||
isPdf && (
|
||||
<Portal
|
||||
visible
|
||||
element={
|
||||
<PDFViewer
|
||||
title={title}
|
||||
toolbar={toolbar}
|
||||
devices={devices}
|
||||
src={fileUrl ?? ""}
|
||||
mobileDetails={mobileDetails}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
isPDFSidebarOpen={isPDFSidebarOpen}
|
||||
onNext={onNextClick}
|
||||
onPrev={onPrevClick}
|
||||
onMask={handleMaskClick}
|
||||
generateContextMenu={generateContextMenu}
|
||||
setIsOpenContextMenu={setIsOpenContextMenu}
|
||||
setIsPDFSidebarOpen={setIsPDFSidebarOpen}
|
||||
/>
|
||||
}
|
||||
<PDFViewer
|
||||
title={title}
|
||||
toolbar={toolbar}
|
||||
devices={devices}
|
||||
src={fileUrl ?? ""}
|
||||
mobileDetails={mobileDetails}
|
||||
isLastImage={!isNotLastElement}
|
||||
isFistImage={!isNotFirstElement}
|
||||
isPDFSidebarOpen={isPDFSidebarOpen}
|
||||
onNext={onNextClick}
|
||||
onPrev={onPrevClick}
|
||||
onMask={handleMaskClick}
|
||||
generateContextMenu={generateContextMenu}
|
||||
setIsOpenContextMenu={setIsOpenContextMenu}
|
||||
setIsPDFSidebarOpen={setIsPDFSidebarOpen}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
|
@ -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<ImperativeHandle, ImageViewerToolbarProps>(
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const contextMenuRef = useRef<HTMLLIElement>(null);
|
||||
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [percent, setPercent] = useState<number>(() =>
|
||||
Math.round(percentValue * 100),
|
||||
);
|
||||
|
||||
useClickOutside(contextMenuRef, () => {
|
||||
setIsOpen(false);
|
||||
});
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => {
|
||||
@ -71,6 +85,7 @@ const ViewerToolbar = forwardRef<ImperativeHandle, ImageViewerToolbarProps>(
|
||||
const contextMenu = generateContextMenu(isOpen);
|
||||
return (
|
||||
<ToolbarItem
|
||||
ref={contextMenuRef}
|
||||
style={{ position: "relative" }}
|
||||
key={item.key}
|
||||
onClick={() => {
|
||||
|
@ -2094,6 +2094,7 @@ export const getBaseTheme = () => {
|
||||
borderColor: grayLightMid,
|
||||
thumbnailBorderColor: grayLightMid,
|
||||
textColor: black,
|
||||
errorColor: "#F21C0E",
|
||||
|
||||
closeButtonWrapperPadding: "0px",
|
||||
closeButtonIcon: white,
|
||||
|
@ -2067,6 +2067,7 @@ const Dark: TTheme = {
|
||||
borderColor: "#474747",
|
||||
thumbnailBorderColor: grayLightMid,
|
||||
textColor: white,
|
||||
errorColor: "#E06451",
|
||||
|
||||
closeButtonWrapperPadding: "6px",
|
||||
closeButtonIcon: black,
|
||||
|
@ -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}`);
|
||||
|
||||
|
@ -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 = <T extends HTMLElement>(
|
||||
ref: RefObject<T>,
|
||||
handler: VoidFunction,
|
||||
...deps: DependencyList
|
||||
) => {
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: MouseEvent) => {
|
||||
|
Loading…
Reference in New Issue
Block a user