Merge branch 'develop' into bugfix/size-column

This commit is contained in:
Ilya Oleshko 2024-06-26 12:07:49 +03:00
commit f58b381f0e
50 changed files with 1135 additions and 572 deletions

View File

@ -3,5 +3,13 @@
"CodeCopySuccess": "Code has been copied to the clipboard",
"EmbedCode": "Embed code",
"Height": "Height",
"Width": "Width"
"Width": "Width",
"Link": "Link",
"DisplaySettings": "Display settings",
"EmbeddingDescription": "Embed Public room into your website or blog. Apply additional display settings for customizing the embedded content.",
"CodeSuccessfullyCopied": "Code to insert successfully copied to clipboard",
"LinkProtectedWithPassword": "The link is protected with a password.",
"ContentRestricted": "Content copying, file downloading and printing are restricted.",
"EmbeddingBarDescription": "Embedding will only work for the URLs specified by the DocSpace admin in the JavaScript SDK settings.",
"EmbeddingBarAllowList": "Add the website URL for embedding to the <1>allow list</1>."
}

View File

@ -180,5 +180,7 @@
"WantToRestoreTheRoom": "All shared links in this room will become active, and its contents will be available to everyone with the link. Do you want to restore the room?",
"WantToRestoreTheRooms": "All shared links in restored rooms will become active, and their contents will be available to everyone with the room links. Do you want to restore the rooms?",
"WithSubfolders": "With subfolders",
"YouLeftTheRoom": "You have left the room"
"YouLeftTheRoom": "You have left the room",
"Protected": "protected",
"Embed": "Embed"
}

View File

@ -131,8 +131,8 @@ export default function withBadges(WrappedComponent) {
const file = {
...options,
ExtraLocationTitle: draftLocation.folderTitle,
ExtraLocation: draftLocation.folderId,
parentId: draftLocation.folderId,
parentTitle: draftLocation.folderTitle,
id: draftLocation.fileId,
title: draftLocation.fileTitle,
};

View File

@ -33,7 +33,7 @@ import FormFillRectSvgUrl from "PUBLIC_DIR/images/form.fill.rect.svg?url";
import AccessEditFormReactSvgUrl from "PUBLIC_DIR/images/access.edit.form.react.svg?url";
import FileActionsConvertEditDocReactSvgUrl from "PUBLIC_DIR/images/file.actions.convert.edit.doc.react.svg?url";
import LinkReactSvgUrl from "PUBLIC_DIR/images/link.react.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import Refresh12ReactSvgUrl from "PUBLIC_DIR/images/icons/12/refresh.react.svg?url";
import Mute12ReactSvgUrl from "PUBLIC_DIR/images/icons/12/mute.react.svg?url";
import Mute16ReactSvgUrl from "PUBLIC_DIR/images/icons/16/mute.react.svg?url";

View File

@ -120,7 +120,7 @@ const Panels = (props) => {
editLinkPanelIsVisible,
unsavedChangesDialogVisible,
deleteLinkDialogVisible,
embeddingPanelIsVisible,
embeddingPanelData,
moveToPublicRoomVisible,
backupToPublicRoomVisible,
settingsPluginDialogVisible,
@ -332,7 +332,7 @@ const Panels = (props) => {
<UnsavedChangesDialog key="unsaved-dialog" />
),
deleteLinkDialogVisible && <DeleteLinkDialog key="delete-link-dialog" />,
embeddingPanelIsVisible && <EmbeddingPanel key="embedding-panel" />,
embeddingPanelData.visible && <EmbeddingPanel key="embedding-panel" />,
moveToPublicRoomVisible && (
<MoveToPublicRoom key="move-to-public-room-panel" />
),
@ -406,7 +406,7 @@ export default inject(
editGroupMembersDialogVisible,
editLinkPanelIsVisible,
deleteLinkDialogVisible,
embeddingPanelIsVisible,
embeddingPanelData,
moveToPublicRoomVisible,
backupToPublicRoomVisible,
leaveRoomDialogVisible,
@ -471,7 +471,7 @@ export default inject(
editLinkPanelIsVisible,
unsavedChangesDialogVisible,
deleteLinkDialogVisible,
embeddingPanelIsVisible,
embeddingPanelData,
moveToPublicRoomVisible,
backupToPublicRoomVisible,
settingsPluginDialogVisible,

View File

@ -23,9 +23,10 @@
// 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 { useMemo } from "react";
import { inject } from "mobx-react";
import { withTranslation } from "react-i18next";
import { decode } from "he";
import { Avatar } from "@docspace/shared/components/avatar";
import { Text } from "@docspace/shared/components/text";
@ -39,7 +40,10 @@ const ChangeRoomOwner = ({
onOwnerChange,
currentColorScheme,
}) => {
const userName = roomOwner.displayName ?? roomOwner.label;
const userName = useMemo(
() => decode(roomOwner.displayName ?? roomOwner.label),
[roomOwner.displayName, roomOwner.label],
);
return (
<Styled.ChangeRoomOwner>

View File

@ -146,25 +146,22 @@ const DeleteLinkDialog = withTranslation(["Common", "Files"])(
DeleteLinkDialogComponent,
);
export default inject(
({ dialogsStore, publicRoomStore, filesStore, infoPanelStore }) => {
const { infoPanelSelection } = infoPanelStore;
const {
deleteLinkDialogVisible: visible,
setDeleteLinkDialogVisible: setIsVisible,
linkParams,
} = dialogsStore;
const { editExternalLink, deleteExternalLink } = publicRoomStore;
export default inject(({ dialogsStore, publicRoomStore, filesStore }) => {
const {
deleteLinkDialogVisible: visible,
setDeleteLinkDialogVisible: setIsVisible,
linkParams,
} = dialogsStore;
const { editExternalLink, deleteExternalLink } = publicRoomStore;
return {
visible,
setIsVisible,
roomId: infoPanelSelection.id,
link: linkParams.link,
editExternalLink,
deleteExternalLink,
isPublicRoomType: infoPanelSelection.roomType === RoomsType.PublicRoom,
setRoomShared: filesStore.setRoomShared,
};
},
)(observer(DeleteLinkDialog));
return {
visible,
setIsVisible,
roomId: linkParams.roomId,
link: linkParams.link,
editExternalLink,
deleteExternalLink,
isPublicRoomType: linkParams.isPublic,
setRoomShared: filesStore.setRoomShared,
};
})(observer(DeleteLinkDialog));

View File

@ -32,13 +32,17 @@ import { Backdrop } from "@docspace/shared/components/backdrop";
import PeopleSelector from "@docspace/shared/selectors/People";
import { withTranslation } from "react-i18next";
import Filter from "@docspace/shared/api/people/filter";
import { EmployeeType, DeviceType } from "@docspace/shared/enums";
import { EmployeeType } from "@docspace/shared/enums";
import { Portal } from "@docspace/shared/components/portal";
import { PRODUCT_NAME } from "@docspace/shared/constants";
const StyledChangeRoomOwner = styled.div`
display: contents;
.change-owner_people-selector {
overflow: visible;
}
${({ showBackButton }) =>
!showBackButton &&
css`
@ -93,12 +97,7 @@ const ChangeRoomOwner = (props) => {
if (e.keyCode === 13 || e.which === 13) onChangeRoomOwner();
};
const onChangeRoomOwner = async (
user,
selectedAccess,
newFooterInputValue,
isChecked,
) => {
const onChangeRoomOwner = async (user, isChecked) => {
if (showBackButton) {
setRoomParams && setRoomParams(user[0]);
} else {
@ -164,16 +163,13 @@ const ChangeRoomOwner = (props) => {
emptyScreenDescription={t("CreateEditRoomDialog:PeopleSelectorInfo", {
productName: PRODUCT_NAME,
})}
className="change-owner_people-selector"
/>
</Aside>
</StyledChangeRoomOwner>
);
return currentDeviceType === DeviceType.mobile ? (
<Portal visible={visible} element={asideComponent} />
) : (
asideComponent
);
return <Portal visible={visible} element={asideComponent} />;
};
export default inject(

View File

@ -40,7 +40,6 @@ import LinkBlock from "./LinkBlock";
import ToggleBlock from "./ToggleBlock";
import PasswordAccessBlock from "./PasswordAccessBlock";
import LimitTimeBlock from "./LimitTimeBlock";
import { RoomsType } from "@docspace/shared/enums";
import { DeviceType } from "@docspace/shared/enums";
import moment from "moment";
@ -65,6 +64,7 @@ const EditLinkPanel = (props) => {
isPublic,
isFormRoom,
currentDeviceType,
setLinkParams,
} = props;
const [isLoading, setIsLoading] = useState(false);
@ -130,6 +130,7 @@ const EditLinkPanel = (props) => {
editExternalLink(roomId, newLink)
.then((link) => {
setExternalLink(link);
setLinkParams({ link, roomId, isPublic, isFormRoom });
if (isEdit) {
copy(linkValue);
@ -301,31 +302,23 @@ const EditLinkPanel = (props) => {
};
export default inject(
({
authStore,
settingsStore,
dialogsStore,
publicRoomStore,
infoPanelStore,
}) => {
const { infoPanelSelection } = infoPanelStore;
({ authStore, settingsStore, dialogsStore, publicRoomStore }) => {
const {
editLinkPanelIsVisible,
setEditLinkPanelIsVisible,
unsavedChangesDialogVisible,
setUnsavedChangesDialog,
linkParams,
setLinkParams,
} = dialogsStore;
const { externalLinks, editExternalLink, setExternalLink } =
publicRoomStore;
const { isEdit } = linkParams;
const { isEdit, roomId, isPublic, isFormRoom } = linkParams;
const linkId = linkParams?.link?.sharedTo?.id;
const link = externalLinks.find((l) => l?.sharedTo?.id === linkId);
const shareLink = link?.sharedTo?.shareLink;
const isPublic = infoPanelSelection?.roomType === RoomsType.PublicRoom;
const isFormRoom = infoPanelSelection?.roomType === RoomsType.FormRoom;
return {
visible: editLinkPanelIsVisible,
@ -333,7 +326,7 @@ export default inject(
isEdit,
linkId: link?.sharedTo?.id,
editExternalLink,
roomId: infoPanelSelection.id,
roomId,
setExternalLink,
isLocked: !!link?.sharedTo?.password,
password: link?.sharedTo?.password ?? "",
@ -348,6 +341,7 @@ export default inject(
isPublic,
isFormRoom,
currentDeviceType: settingsStore.currentDeviceType,
setLinkParams,
};
},
)(

View File

@ -1,181 +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, { useState } from "react";
import copy from "copy-to-clipboard";
import { Text } from "@docspace/shared/components/text";
import { Link } from "@docspace/shared/components/link";
import { toastr } from "@docspace/shared/components/toast";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { IconButton } from "@docspace/shared/components/icon-button";
import { Button } from "@docspace/shared/components/button";
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
import { StyledBody } from "./StyledEmbeddingPanel";
import { objectToGetParams } from "@docspace/shared/utils/common";
const EmbeddingBody = ({ t, link, requestToken, roomId }) => {
const [size, setSize] = useState("auto");
const [widthValue, setWidthValue] = useState("100%");
const [heightValue, setHeightValue] = useState("100%");
const config = {
width: `${widthValue}`,
height: `${heightValue}`,
frameId: "ds-frame-embedding",
mode: "manager",
init: true,
showHeader: true,
showTitle: true,
showMenu: false,
showFilter: true,
rootPath: "/rooms/share",
id: roomId,
requestToken,
withSubfolders: false,
};
const scriptUrl = `${window.location.origin}/static/scripts/api.js`;
const params = objectToGetParams(config);
const codeBlock = `<div id="${config.frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const onChangeWidth = (e) => setWidthValue(e.target.value);
const onChangeHeight = (e) => setHeightValue(e.target.value);
const onCopyLink = () => {
copy(codeBlock);
toastr.success(t("EmbeddingPanel:CodeCopySuccess"));
};
const getSizes = (size) => {
switch (size) {
case "auto":
return ["100%", "100%"];
case "mobile":
return ["400px", "600px"];
case "tablet":
return ["600px", "800px"];
default:
return ["100%", "100%"];
}
};
const onSelectSize = (e) => {
const size = e.currentTarget.dataset.size;
const [width, height] = getSizes(size);
setSize(size);
setWidthValue(width);
setHeightValue(height);
};
const onPreviewClick = () => {
console.log("onPreviewClick???");
};
const linkProps = {
isHovered: true,
type: "action",
onClick: onSelectSize,
};
return (
<StyledBody>
<div className="embedding-panel_body">
<Text className="embedding-panel_text">{t("Common:Size")}:</Text>
<div className="embedding-panel_links-container">
<Link
data-size="auto"
className={`embedding-panel_link ${
size === "auto" && "embedding-panel_link_active"
}`}
{...linkProps}
>
{t("Auto")}
</Link>
<Link
data-size="tablet"
className={`embedding-panel_link ${
size === "tablet" && "embedding-panel_link_active"
}`}
{...linkProps}
>
600 x 800 px
</Link>
<Link
data-size="mobile"
className={`embedding-panel_link ${
size === "mobile" && "embedding-panel_link_active"
}`}
{...linkProps}
>
400 x 600 px
</Link>
</div>
<div className="embedding-panel_inputs-container">
<div>
<Text className="embedding-panel_text">{t("Width")}:</Text>
<TextInput
className="embedding-panel_input"
value={widthValue}
onChange={onChangeWidth}
/>
</div>
<div>
<Text className="embedding-panel_text">{t("Height")}:</Text>
<TextInput
className="embedding-panel_input"
value={heightValue}
onChange={onChangeHeight}
/>
</div>
{/* <Button
className="embedding-panel_preview-button"
primary
size="small"
label={t("Common:Preview")}
onClick={onPreviewClick}
/> */}
</div>
<div className="embedding-panel_code-container">
<Text className="embedding-panel_text">
{t("EmbeddingPanel:EmbedCode")}:
</Text>
<IconButton
className="embedding-panel_copy-icon"
size="16"
iconName={CopyReactSvgUrl}
onClick={onCopyLink}
/>
<Textarea isReadOnly value={codeBlock} heightTextArea="150px" />
</div>
</div>
</StyledBody>
);
};
export default EmbeddingBody;

View File

@ -25,89 +25,99 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import styled, { css } from "styled-components";
import { Scrollbar } from "@docspace/shared/components/scrollbar";
import { Base } from "@docspace/shared/themes";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
const StyledEmbeddingPanel = styled.div`
.embedding-panel {
.scroll-body {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-left: 0 !important;
`
: css`
padding-right: 0 !important;
`}
}
const StyledModalDialog = styled(ModalDialog)`
.modal-header {
margin: 0;
}
.embedding_header {
padding: 0 16px;
border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom};
.hotkeys_heading {
font-weight: 700;
font-size: 18px;
}
}
`;
StyledEmbeddingPanel.defaultProps = { theme: Base };
const StyledScrollbar = styled(Scrollbar)`
position: relative;
padding: 16px 0;
height: calc(100vh - 87px) !important;
`;
const StyledBody = styled.div`
.embedding-panel_header-link {
margin: 10px 0 2px;
}
.embedding-panel_combo-box {
margin-bottom: 6px;
}
.embedding-panel_banner {
display: flex;
padding: 12px 16px;
gap: 16px;
margin: 0px -16px 12px;
background-color: ${(props) => props.theme.infoBlock.background};
.embedding-panel_banner-close-icon {
min-width: 12px;
min-height: 12px;
margin-left: auto;
}
}
.embedding-panel_body {
padding: 20px 16px 0 16px;
}
.embedding-panel_links-container {
display: flex;
.embedding-panel_link {
box-sizing: border-box;
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin-left: 8px;
`
: css`
margin-right: 8px;
`}
border: 1px solid #eceef1;
border-radius: 16px;
line-height: 20px;
padding: 3px 15px;
text-decoration: none;
.embedding-panel_description {
color: ${({ theme }) => theme.embeddingPanel.descriptionTextColor};
margin: 18px 0;
}
.embedding-panel_link_active {
color: #ffffff;
background: #265a8f;
.embedding-panel_bar {
.embedding-panel_bar-header {
display: flex;
align-items: center;
gap: 4px;
}
.header-icon {
svg path {
fill: ${({ theme }) => theme.embeddingPanel.iconColor};
}
}
}
}
.embedding-panel_inputs-container {
display: flex;
margin-top: 16px;
.embedding-panel_header-text {
margin: 16px 0;
}
.embedding-panel_input {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin-left: 8px;
`
: css`
margin-right: 8px;
`}
width: 94px;
.embedding-panel_checkbox-container {
display: flex;
flex-direction: column;
gap: 10px;
.embedding-panel_checkbox-element {
display: inline-flex;
align-items: center;
gap: 4px;
}
}
.embedding-panel_inputs-container {
display: flex;
margin-bottom: 20px;
gap: 8px;
.embedding-panel_block {
width: 100%;
.embedding-panel_size-block {
display: flex;
align-items: center;
height: 32px;
}
}
.embedding-panel_input {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin-left: 8px;
`
: css`
margin-right: 8px;
`}
width: 94px;
}
}
}
@ -139,4 +149,4 @@ const StyledBody = styled.div`
}
`;
export { StyledEmbeddingPanel, StyledScrollbar, StyledBody };
export { StyledModalDialog, StyledBody };

View File

@ -1,130 +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, { useRef, useEffect } from "react";
import { inject, observer } from "mobx-react";
import { Backdrop } from "@docspace/shared/components/backdrop";
import { Heading } from "@docspace/shared/components/heading";
import { Aside } from "@docspace/shared/components/aside";
import { withTranslation } from "react-i18next";
import { StyledEmbeddingPanel, StyledScrollbar } from "./StyledEmbeddingPanel";
import EmbeddingBody from "./EmbeddingBody";
import { DeviceType } from "@docspace/shared/enums";
import { Portal } from "@docspace/shared/components/portal";
const EmbeddingPanelComponent = (props) => {
const {
t,
link,
requestToken,
roomId,
visible,
setEmbeddingPanelIsVisible,
currentDeviceType,
} = props;
const scrollRef = useRef(null);
const onClose = () => {
setEmbeddingPanelIsVisible(false);
};
const onKeyPress = (e) =>
(e.key === "Esc" || e.key === "Escape") && onClose();
useEffect(() => {
scrollRef.current && scrollRef.current?.view?.focus();
document.addEventListener("keyup", onKeyPress);
return () => document.removeEventListener("keyup", onKeyPress);
});
const embeddingPanelComponent = (
<StyledEmbeddingPanel>
<Backdrop
onClick={onClose}
visible={visible}
isAside={true}
zIndex={310}
/>
<Aside
className="embedding-panel"
visible={visible}
onClose={onClose}
withoutBodyScroll={true}
>
<div className="embedding_header">
<Heading className="hotkeys_heading">
{t("Files:EmbeddingSettings")}
</Heading>
</div>
<StyledScrollbar ref={scrollRef}>
<EmbeddingBody
t={t}
link={link}
requestToken={requestToken}
roomId={roomId}
/>
</StyledScrollbar>
</Aside>
</StyledEmbeddingPanel>
);
const renderPortal = () => {
const rootElement = document.getElementById("root");
return (
<Portal
element={embeddingPanelComponent}
appendTo={rootElement}
visible={visible}
/>
);
};
return currentDeviceType === DeviceType.mobile
? renderPortal()
: embeddingPanelComponent;
};
export default inject(({ dialogsStore, settingsStore }) => {
const { embeddingPanelIsVisible, setEmbeddingPanelIsVisible, linkParams } =
dialogsStore;
const { currentDeviceType } = settingsStore;
return {
visible: embeddingPanelIsVisible,
setEmbeddingPanelIsVisible,
link: linkParams?.link?.sharedTo?.shareLink,
requestToken: linkParams?.link?.sharedTo?.requestToken,
roomId: linkParams?.roomId,
currentDeviceType,
};
})(
withTranslation(["Files", "EmbeddingPanel"])(
observer(EmbeddingPanelComponent),
),
);

View File

@ -0,0 +1,610 @@
// (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 { useState, useEffect, useCallback, useRef } from "react";
import { inject, observer } from "mobx-react";
import { useNavigate } from "react-router-dom";
import { withTranslation, Trans } from "react-i18next";
import copy from "copy-to-clipboard";
import isEqual from "lodash/isEqual";
import { objectToGetParams } from "@docspace/shared/utils/common";
import { Text } from "@docspace/shared/components/text";
import { toastr } from "@docspace/shared/components/toast";
import { Textarea } from "@docspace/shared/components/textarea";
import { IconButton } from "@docspace/shared/components/icon-button";
import PublicRoomBar from "@docspace/shared/components/public-room-bar";
import { Link, LinkType } from "@docspace/shared/components/link";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { ComboBox, TOption } from "@docspace/shared/components/combobox";
import { TData } from "@docspace/shared/components/toast/Toast.type";
import { TTranslation } from "@docspace/shared/types";
import { TColorScheme, TTheme } from "@docspace/shared/themes";
import { SettingsStore } from "@docspace/shared/store/SettingsStore";
import { UserStore } from "@docspace/shared/store/UserStore";
import {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
import HeaderUrl from "PUBLIC_DIR/images/sdk-presets_header.react.svg?url";
import HeaderDarkUrl from "PUBLIC_DIR/images/sdk-presets_header_dark.png?url";
import SearchUrl from "PUBLIC_DIR/images/sdk-presets_search.react.svg?url";
import SearchDarkUrl from "PUBLIC_DIR/images/sdk-presets_search_dark.png?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import CrossReactSvg from "PUBLIC_DIR/images/cross.react.svg?url";
import { StyledModalDialog, StyledBody } from "./StyledEmbeddingPanel";
import { DisplayBlock } from "./sub-components/DisplayBlock";
import { CheckboxElement } from "./sub-components/CheckboxElement";
import PublicRoomStore from "../../../store/PublicRoomStore";
import DialogsStore from "../../../store/DialogsStore";
type LinkParamsLinkShareToType = {
denyDownload: boolean;
id: string;
internal: boolean;
isExpired: boolean;
linkType: number;
primary: boolean;
requestToken: string;
shareLink: string;
title: string;
password?: string;
};
type LinkParamsLinkType = {
access: number;
canEditAccess: boolean;
isLocked: boolean;
isOwner: boolean;
sharedTo?: LinkParamsLinkShareToType;
subjectType: number;
};
type LinkParamsType = {
roomId: number | string;
isEdit?: boolean;
link: LinkParamsLinkType;
};
type EmbeddingPanelProps = {
t: TTranslation;
theme: TTheme;
requestToken: string;
roomId: number;
visible: boolean;
setEmbeddingPanelData: (value: {
visible: boolean;
fileId?: string | number;
}) => void;
setEditLinkPanelIsVisible: (value: boolean) => void;
currentColorScheme: TColorScheme;
linkParams: LinkParamsType;
setLinkParams: (linkParams: LinkParamsType) => void;
fetchExternalLinks: (roomId: string | number) => LinkParamsLinkType[];
isAdmin: boolean;
fileId?: string | number;
};
type TOptionType = TOption & {
sharedTo: LinkParamsLinkShareToType;
};
const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
const {
t,
theme,
visible,
setEmbeddingPanelData,
setEditLinkPanelIsVisible,
currentColorScheme,
linkParams,
setLinkParams,
fetchExternalLinks,
isAdmin,
fileId,
} = props;
const { roomId, link } = linkParams;
const navigate = useNavigate();
const [sharedLinksOptions, setSharedLinksOptions] = useState<TOptionType[]>(
[],
);
const [selectedLink, setSelectedLink] = useState<TOptionType>();
const [barIsVisible, setBarIsVisible] = useState(!!fileId);
const [isLoading, setIsLoading] = useState(false);
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const [widthValue, setWidthValue] = useState("100");
const [widthDimension, setWidthDimension] = useState<TOption>(
dataDimensions[0],
);
const [heightValue, setHeightValue] = useState("820");
const [heightDimension, setHeightDimension] = useState<TOption>(
dataDimensions[1],
);
const fileConfig = {
mode: "viewer",
width: `${widthValue}${dataDimensions[0].label}`,
height: `${heightValue}${dataDimensions[1].label}`,
frameId: "ds-frame",
init: true,
id: fileId,
};
const roomConfig = {
width: `${widthValue}${dataDimensions[0].label}`,
height: `${heightValue}${dataDimensions[1].label}`,
frameId: "ds-frame",
showHeader: true,
showTitle: true,
showMenu: false,
showFilter: true,
mode: "manager",
init: true,
requestToken: link?.sharedTo?.requestToken,
rootPath: "/rooms/share",
id: roomId,
filter: {
count: 100,
page: 1,
sortorder: "descending",
sortby: "DateAndTime",
search: "",
withSubfolders: false,
},
};
const [config, setConfig] = useState(fileId ? fileConfig : roomConfig);
const params = objectToGetParams(config);
const codeBlock = `<div id="${config.frameId}">Fallback text</div>\n<script src="${SDK_SCRIPT_URL}${params}"></script>`;
const currentLink = selectedLink ?? link;
const linkTitle = currentLink?.sharedTo?.title;
const withPassword = currentLink?.sharedTo?.password;
const denyDownload = currentLink?.sharedTo?.denyDownload;
const contentRestrictedTitle = t("EmbeddingPanel:ContentRestricted");
const withPasswordTitle = t("EmbeddingPanel:LinkProtectedWithPassword");
let barSubTitle = "";
if (withPassword) {
barSubTitle = withPasswordTitle;
if (denyDownload) {
barSubTitle += ` ${contentRestrictedTitle}`;
}
} else {
barSubTitle = contentRestrictedTitle;
}
const showLinkBar =
selectedLink?.sharedTo?.password || selectedLink?.sharedTo?.denyDownload;
const onClose = () => {
setEmbeddingPanelData({ visible: false });
};
const onChangeWidth = (e: React.ChangeEvent<HTMLInputElement>) => {
setWidthValue(e.target.value);
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
};
const onChangeHeight = (e: React.ChangeEvent<HTMLInputElement>) => {
setHeightValue(e.target.value);
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
};
const onChangeWidthDimension = (item: TOption) => {
setWidthDimension(item);
setConfig((config) => {
return { ...config, width: `${widthValue}${item.label}` };
});
};
const onChangeHeightDimension = (item: TOption) => {
setHeightDimension(item);
setConfig((config) => {
return { ...config, height: `${heightValue}${item.label}` };
});
};
const onCopyLink = () => {
copy(codeBlock);
toastr.success(t("EmbeddingPanel:CodeSuccessfullyCopied"));
};
const onHeaderChange = () => {
setConfig((config) => {
return { ...config, showTitle: !config.showTitle };
});
};
const onTitleChange = () => {
setConfig((config) => {
return { ...config, showFilter: !config.showFilter };
});
};
const onCopyAndClose = () => {
onCopyLink();
onClose();
};
const onEditLink = () => {
setLinkParams({ ...linkParams, isEdit: true, link: selectedLink ?? link });
setEditLinkPanelIsVisible(true);
};
const onChangeSharedLink = (item: TOptionType) => {
setSelectedLink(item);
setConfig((config) => {
return { ...config, requestToken: item?.sharedTo?.requestToken };
});
};
const onCloseBar = () => {
setBarIsVisible(false);
};
const onOpenDevTools = () => {
navigate("/portal-settings/developer-tools");
onClose();
};
const onKeyPress = (e: KeyboardEvent) => {
if (e.key === "Esc" || e.key === "Escape") {
onClose();
}
};
useEffect(() => {
document.addEventListener("keyup", onKeyPress);
return () => document.removeEventListener("keyup", onKeyPress);
});
const getLinks = useCallback(async () => {
try {
setIsLoading(true);
const roomLinks = await fetchExternalLinks(roomId);
if (roomLinks && roomLinks.length) {
const linksOptions = roomLinks.map((l: LinkParamsLinkType) => {
return {
key: l.sharedTo?.id,
label: l.sharedTo?.title,
sharedTo: l.sharedTo,
} as TOptionType;
});
setSelectedLink(linksOptions[0]);
setSharedLinksOptions(linksOptions);
onChangeSharedLink(linksOptions[0]);
}
} catch (error) {
toastr.error(error as TData);
} finally {
setIsLoading(false);
}
}, [roomId, fetchExternalLinks]);
useEffect(() => {
if (fileId) {
getLinks();
}
}, [fileId, getLinks]);
const usePrevious = (value: LinkParamsLinkType | null) => {
const ref = useRef<LinkParamsLinkType | null>();
useEffect(() => {
ref.current = value;
});
return ref.current;
};
const prevLink = usePrevious(link ?? null);
useEffect(() => {
if (sharedLinksOptions?.length && prevLink && !isEqual(prevLink, link)) {
const newSharedLinks = [...sharedLinksOptions];
const newLinkIndex = newSharedLinks.findIndex(
(l) => l.sharedTo.id === link.sharedTo?.id,
);
if (newLinkIndex > -1)
newSharedLinks[newLinkIndex] = {
key: link.sharedTo?.id,
label: link.sharedTo?.title,
sharedTo: link.sharedTo,
} as TOptionType;
setSharedLinksOptions(newSharedLinks);
setSelectedLink({
key: link.sharedTo?.id,
label: link.sharedTo?.title,
sharedTo: link.sharedTo,
} as TOptionType);
}
}, [link, prevLink, sharedLinksOptions]);
const barTitle = (
<div className="embedding-panel_bar-header">
<Link
isHovered
type={LinkType.action}
fontSize="13px"
fontWeight={600}
color={currentColorScheme?.main?.accent}
onClick={onEditLink}
isTextOverflow
>
{linkTitle}
</Link>
<Text fontSize="12px" fontWeight={600}>
{t("Files:Protected")}
</Text>
</div>
);
return (
<StyledModalDialog
visible={visible}
onClose={onClose}
displayType={ModalDialogType.aside}
>
<ModalDialog.Header>{t("Files:EmbeddingSettings")}</ModalDialog.Header>
<ModalDialog.Body>
<StyledBody>
{barIsVisible && (
<div className="embedding-panel_banner">
<Text fontSize="12px" fontWeight={400}>
{isAdmin ? (
<Trans
t={t}
ns="EmbeddingPanel"
i18nKey="EmbeddingBarAllowList"
components={{
1: (
<Link
onClick={onOpenDevTools}
color={currentColorScheme?.main?.accent}
isHovered
/>
),
}}
>
{`"Add the website URL for embedding to the <1>allow list</1>."`}
</Trans>
) : (
t("EmbeddingPanel:EmbeddingBarDescription")
)}
</Text>
<IconButton
className="embedding-panel_banner-close-icon"
size={12}
iconName={CrossReactSvg}
onClick={onCloseBar}
/>
</div>
)}
<div className="embedding-panel_body">
{!fileId && (
<Text fontSize="12px" className="embedding-panel_description">
{t("EmbeddingPanel:EmbeddingDescription")}
</Text>
)}
{sharedLinksOptions && sharedLinksOptions.length > 1 && (
<>
<Text
className="embedding-panel_header-link"
fontSize="15px"
fontWeight={600}
>
{t("EmbeddingPanel:Link")}
</Text>
<ComboBox
className="embedding-panel_combo-box"
scaled
onSelect={onChangeSharedLink}
options={sharedLinksOptions}
selectedOption={selectedLink as TOption}
displaySelectedOption
directionY="bottom"
/>
</>
)}
{showLinkBar && (
<PublicRoomBar
className="embedding-panel_bar"
headerText={barTitle}
bodyText={barSubTitle}
iconName={TabletLinkReactSvgUrl}
/>
)}
<Text
className="embedding-panel_header-text"
fontSize="15px"
fontWeight={600}
>
{t("EmbeddingPanel:DisplaySettings")}
</Text>
<div className="embedding-panel_inputs-container">
<DisplayBlock
label={t("EmbeddingPanel:Width")}
inputValue={widthValue}
onInputChange={onChangeWidth}
selectedOption={widthDimension}
onSelectDimension={onChangeWidthDimension}
/>
<DisplayBlock
label={t("EmbeddingPanel:Height")}
inputValue={heightValue}
onInputChange={onChangeHeight}
selectedOption={heightDimension}
onSelectDimension={onChangeHeightDimension}
/>
</div>
{!fileId && (
<>
<Text
className="embedding-panel_header-text"
fontSize="15px"
fontWeight={600}
>
{t("JavascriptSdk:InterfaceElements")}
</Text>
<div className="embedding-panel_checkbox-container">
<CheckboxElement
label={t("Common:Title")}
onChange={onHeaderChange}
isChecked={config.showTitle}
img={theme.isBase ? HeaderUrl : HeaderDarkUrl}
title={t("JavascriptSdk:Header")}
description={t("JavascriptSdk:HeaderDescription")}
/>
<CheckboxElement
label={t("JavascriptSdk:SearchFilterAndSort")}
onChange={onTitleChange}
isChecked={config.showFilter}
img={theme.isBase ? SearchUrl : SearchDarkUrl}
title={t("JavascriptSdk:SearchBlock")}
description={t(
"JavascriptSdk:ManagerSearchBlockDescription",
)}
/>
</div>
</>
)}
<div className="embedding-panel_code-container">
<Text
className="embedding-panel_header-text"
fontSize="15px"
fontWeight={600}
>
{t("JavascriptSdk:Code")}
</Text>
<IconButton
className="embedding-panel_copy-icon"
size={16}
iconName={CopyReactSvgUrl}
onClick={onCopyLink}
/>
<Textarea isReadOnly value={codeBlock} heightTextArea="150px" />
</div>
</div>
</StyledBody>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="send-invitation"
scale
size={ButtonSize.normal}
primary
onClick={onCopyAndClose}
label={t("Common:Copy")}
isLoading={isLoading}
/>
<Button
className="cancel-button"
scale
size={ButtonSize.normal}
onClick={onClose}
label={t("Common:CancelButton")}
isLoading={isLoading}
/>
</ModalDialog.Footer>
</StyledModalDialog>
);
};
export default inject(
({
dialogsStore,
settingsStore,
userStore,
publicRoomStore,
}: {
dialogsStore: DialogsStore;
settingsStore: SettingsStore;
userStore: UserStore;
publicRoomStore: PublicRoomStore;
}) => {
const {
embeddingPanelData,
setEmbeddingPanelData,
linkParams,
setEditLinkPanelIsVisible,
setLinkParams,
} = dialogsStore;
const { theme, currentColorScheme } = settingsStore;
const { user } = userStore;
const { fetchExternalLinks } = publicRoomStore;
return {
theme,
currentColorScheme,
visible: embeddingPanelData.visible,
fileId: embeddingPanelData.fileId,
setEmbeddingPanelData,
setEditLinkPanelIsVisible,
linkParams,
setLinkParams,
fetchExternalLinks,
isAdmin: user?.isAdmin,
};
},
)(
withTranslation(["Files", "EmbeddingPanel", "JavascriptSdk"])(
observer(EmbeddingPanelComponent),
),
);

View File

@ -0,0 +1,68 @@
// (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 { Checkbox } from "@docspace/shared/components/checkbox";
import { HelpButton } from "@docspace/shared/components/help-button";
import { TooltipContent } from "../../../../pages/PortalSettings/categories/developer-tools/JavascriptSDK/sub-components/TooltipContent";
type CheckboxElementProps = {
img: string;
label: string;
title: string;
description: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
isChecked: boolean;
};
const CheckboxElement = ({
img,
label,
title,
description,
onChange,
isChecked,
}: CheckboxElementProps) => {
return (
<div className="embedding-panel_checkbox-element">
<Checkbox
className="checkbox"
label={label}
onChange={onChange}
isChecked={isChecked}
/>
<HelpButton
place="right"
offsetRight={4}
size={12}
tooltipContent={
<TooltipContent img={img} title={title} description={description} />
}
/>
</div>
);
};
export { CheckboxElement };

View File

@ -0,0 +1,83 @@
// (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 { Text } from "@docspace/shared/components/text";
import {
ComboBox,
ComboBoxSize,
TOption,
} from "@docspace/shared/components/combobox";
import {
InputSize,
InputType,
TextInput,
} from "@docspace/shared/components/text-input";
import { dataDimensions } from "../../../../pages/PortalSettings/categories/developer-tools/JavascriptSDK/constants";
type DisplayBlockProps = {
label: string;
inputValue: string;
onInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
selectedOption: TOption;
onSelectDimension: (option: TOption) => void;
};
const DisplayBlock = ({
label,
inputValue,
onInputChange,
selectedOption,
onSelectDimension,
}: DisplayBlockProps) => {
return (
<div className="embedding-panel_block">
<Text fontSize="13px" fontWeight={600} className="embedding-panel_text">
{label}
</Text>
<div className="embedding-panel_size-block">
<TextInput
type={InputType.text}
size={InputSize.base}
className="embedding-panel_input"
value={inputValue}
onChange={onInputChange}
/>
<ComboBox
size={ComboBoxSize.content}
scaled={false}
scaledOptions
onSelect={onSelectDimension}
options={dataDimensions}
selectedOption={selectedOption}
displaySelectedOption
directionY="bottom"
/>
</div>
</div>
);
};
export { DisplayBlock };

View File

@ -109,18 +109,6 @@ const Gallery = ({
{parseAndFormatDate(gallerySelected.attributes.updatedAt, culture)}
</Text>
</div>
<div className="property">
<Text className="property-title">{t("Common:Size")}</Text>
<Text className="property-content">
{gallerySelected.attributes.file_size}
</Text>
</div>
<div className="property">
<Text className="property-title">{t("Common:Pages")}</Text>
<Text className="property-content">
{gallerySelected.attributes.file_pages}
</Text>
</div>
</StyledProperties>
</>
);

View File

@ -54,7 +54,7 @@ const HistoryBlock = ({ t, feed, isLastEntity }) => {
userName={initiator.displayName}
source={
initiator.hasAvatar
? initiator.avatarSmall
? initiator.avatar
: DefaultUserAvatarSmall ||
(initiator.displayName ? "" : initiator.email && AtReactSvgUrl)
}

View File

@ -123,7 +123,7 @@ const Members = ({
const onAddNewLink = async () => {
if (isPublicRoom || primaryLink) {
setLinkParams({ isEdit: false });
setLinkParams({ roomId: infoPanelSelection?.id, isEdit: false });
setEditLinkPanelIsVisible(true);
} else {
getPrimaryLink(infoPanelSelection.id).then((link) => {

View File

@ -35,7 +35,7 @@ import { IconButton } from "@docspace/shared/components/icon-button";
import { ContextMenuButton } from "@docspace/shared/components/context-menu-button";
import { toastr } from "@docspace/shared/components/toast";
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
import LinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url";
import LinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import SettingsReactSvgUrl from "PUBLIC_DIR/images/catalog.settings.react.svg?url";
import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url";
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
@ -60,11 +60,12 @@ const LinkRow = (props) => {
editExternalLink,
setEditLinkPanelIsVisible,
setDeleteLinkDialogVisible,
setEmbeddingPanelIsVisible,
setEmbeddingPanelData,
isArchiveFolder,
theme,
setIsScrollLocked,
isPublicRoomType,
isFormRoom,
...rest
} = props;
@ -90,33 +91,39 @@ const LinkRow = (props) => {
const onEditLink = () => {
setEditLinkPanelIsVisible(true);
setLinkParams({ isEdit: true, link });
setLinkParams({
isEdit: true,
link,
roomId,
isPublic: isPublicRoomType,
isFormRoom,
});
onCloseContextMenu();
};
const onDisableLink = () => {
if (isExpired) {
setEditLinkPanelIsVisible(true);
setLinkParams({ isEdit: true, link });
return;
}
// const onDisableLink = () => {
// if (isExpired) {
// setEditLinkPanelIsVisible(true);
// setLinkParams({ isEdit: true, link, roomId, isPublic: isPublicRoomType, isFormRoom });
// return;
// }
setIsLoading(true);
// setIsLoading(true);
const newLink = JSON.parse(JSON.stringify(link));
newLink.sharedTo.disabled = !newLink.sharedTo.disabled;
// const newLink = JSON.parse(JSON.stringify(link));
// newLink.sharedTo.disabled = !newLink.sharedTo.disabled;
editExternalLink(roomId, newLink)
.then((link) => {
setExternalLink(link);
// editExternalLink(roomId, newLink)
// .then((link) => {
// setExternalLink(link);
disabled
? toastr.success(t("Files:LinkEnabledSuccessfully"))
: toastr.success(t("Files:LinkDisabledSuccessfully"));
})
.catch((err) => toastr.error(err?.message))
.finally(() => setIsLoading(false));
};
// disabled
// ? toastr.success(t("Files:LinkEnabledSuccessfully"))
// : toastr.success(t("Files:LinkDisabledSuccessfully"));
// })
// .catch((err) => toastr.error(err?.message))
// .finally(() => setIsLoading(false));
// };
const onCopyPassword = () => {
copy(password);
@ -124,13 +131,13 @@ const LinkRow = (props) => {
};
const onEmbeddingClick = () => {
setLinkParams({ link, roomId });
setEmbeddingPanelIsVisible(true);
setLinkParams({ link, roomId, isPublic: isPublicRoomType, isFormRoom });
setEmbeddingPanelData({ visible: true });
onCloseContextMenu();
};
const onDeleteLink = () => {
setLinkParams({ link });
setLinkParams({ link, roomId, isPublic: isPublicRoomType, isFormRoom });
setDeleteLinkDialogVisible(true);
onCloseContextMenu();
};
@ -149,6 +156,8 @@ const LinkRow = (props) => {
setIsScrollLocked(false);
};
const isDisabled = disabled || isExpired;
const getData = () => {
return [
{
@ -167,20 +176,20 @@ const LinkRow = (props) => {
// icon: ShareReactSvgUrl,
// // onClick: () => args.onClickLabel("label2"),
// },
// !isExpired && {
// key: "embedding-settings-key",
// label: t("Files:EmbeddingSettings"),
// icon: CodeReactSvgUrl,
// onClick: onEmbeddingClick,
// },
!disabled &&
!isExpired && {
key: "copy-link-settings-key",
label: t("Files:CopySharedLink"),
icon: CopyToReactSvgUrl,
onClick: onCopyExternalLink,
},
!isDisabled && {
key: "copy-link-settings-key",
label: t("Files:CopySharedLink"),
icon: CopyToReactSvgUrl,
onClick: onCopyExternalLink,
},
!isDisabled && {
key: "embedding-settings-key",
label: t("Files:EmbeddingSettings"),
icon: CodeReactSvgUrl,
onClick: onEmbeddingClick,
},
// disabled
// ? {
@ -305,7 +314,7 @@ export default inject(
const {
setEditLinkPanelIsVisible,
setDeleteLinkDialogVisible,
setEmbeddingPanelIsVisible,
setEmbeddingPanelData,
setLinkParams,
} = dialogsStore;
const { editExternalLink, setExternalLink } = publicRoomStore;
@ -318,12 +327,13 @@ export default inject(
setExternalLink,
setEditLinkPanelIsVisible,
setDeleteLinkDialogVisible,
setEmbeddingPanelIsVisible,
setEmbeddingPanelData,
isArchiveFolder: isArchiveFolderRoot,
theme,
isPublicRoomType:
infoPanelSelection.roomType === RoomsType.PublicRoom ||
infoPanelSelection.roomType === RoomsType.FormRoom,
isFormRoom: infoPanelSelection?.roomType === RoomsType.FormRoom,
};
},
)(

View File

@ -44,7 +44,7 @@ import PublicRoomIconUrl from "PUBLIC_DIR/images/public-room.react.svg?url";
import LeaveRoomSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import React from "react";
import { inject, observer } from "mobx-react";
@ -543,6 +543,7 @@ const SectionHeaderContent = (props) => {
disabled:
isRecycleBinFolder ||
isPersonalRoom ||
!security?.CopyLink ||
((isPublicRoomType || isCustomRoomType || isFormRoomType) &&
haveLinksRight &&
!isArchive),

View File

@ -26,8 +26,6 @@
export const showPreviewThreshold = 720;
export const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
export const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },

View File

@ -38,7 +38,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -53,7 +52,7 @@ import {
Container,
ControlsSection,
} from "./StyledPresets";
import { PRODUCT_NAME } from "@docspace/shared/constants";
import { PRODUCT_NAME, SDK_SCRIPT_URL } from "@docspace/shared/constants";
const DocSpace = (props) => {
const { t, setDocumentTitle, theme } = props;
@ -88,7 +87,7 @@ const DocSpace = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -124,7 +123,7 @@ const DocSpace = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
/>
<Controls>

View File

@ -45,7 +45,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -63,6 +62,7 @@ import {
Container,
FilesSelectorInputWrapper,
} from "./StyledPresets";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const Editor = (props) => {
const { t, setDocumentTitle, getFilePrimaryLink, theme } = props;
@ -83,7 +83,7 @@ const Editor = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -154,7 +154,7 @@ const Editor = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
isDisabled={config?.id === undefined}
/>

View File

@ -60,7 +60,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -78,6 +77,7 @@ import {
Container,
FilesSelectorInputWrapper,
} from "./StyledPresets";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const FileSelector = (props) => {
const { t, setDocumentTitle, fetchExternalLinks, theme, organizationName } =
@ -175,7 +175,7 @@ const FileSelector = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -276,7 +276,7 @@ const FileSelector = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
/>
<Controls>

View File

@ -69,7 +69,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -90,7 +89,7 @@ import {
SelectedItemsContainer,
CheckboxGroup,
} from "./StyledPresets";
import { PRODUCT_NAME } from "@docspace/shared/constants";
import { PRODUCT_NAME, SDK_SCRIPT_URL } from "@docspace/shared/constants";
const Manager = (props) => {
const { t, setDocumentTitle, fetchExternalLinks, theme, currentColorScheme } =
@ -165,7 +164,7 @@ const Manager = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -358,7 +357,7 @@ const Manager = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
/>
<Controls>

View File

@ -49,7 +49,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -64,6 +63,7 @@ import {
Frame,
Container,
} from "./StyledPresets";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const RoomSelector = (props) => {
const { t, setDocumentTitle, theme } = props;
@ -135,7 +135,7 @@ const RoomSelector = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -188,7 +188,7 @@ const RoomSelector = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
/>
<Controls>

View File

@ -60,7 +60,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -79,6 +78,7 @@ import {
ControlsSection,
CheckboxGroup,
} from "./StyledPresets";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const SimpleRoom = (props) => {
const { t, setDocumentTitle, fetchExternalLinks, currentColorScheme, theme } =
@ -119,7 +119,7 @@ const SimpleRoom = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -244,7 +244,7 @@ const SimpleRoom = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
isDisabled={config?.id === undefined}
/>

View File

@ -47,7 +47,6 @@ import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
@ -65,6 +64,7 @@ import {
Container,
FilesSelectorInputWrapper,
} from "./StyledPresets";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const Viewer = (props) => {
const { t, setDocumentTitle, getFilePrimaryLink, theme } = props;
@ -86,7 +86,7 @@ const Viewer = (props) => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
const loadCurrentFrame = () => loadFrame(config, SDK_SCRIPT_URL);
useEffect(() => {
loadCurrentFrame();
@ -157,7 +157,7 @@ const Viewer = (props) => {
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
scriptUrl={SDK_SCRIPT_URL}
config={config}
isDisabled={config?.id === undefined}
/>

View File

@ -31,6 +31,7 @@ import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { githubLightInit, githubDarkInit } from "@uiw/codemirror-theme-github";
import { Base } from "@docspace/shared/themes";
import { SDK_SCRIPT_URL } from "@docspace/shared/constants";
const StyledContainer = styled.div`
border: 1px solid ${(props) => props.theme.plugins.borderColor};
@ -43,7 +44,7 @@ const StyledContainer = styled.div`
StyledContainer.defaultProps = { theme: Base };
const CodeBlock = ({ config }) => {
const codeString = `const config = ${JSON.stringify(config, null, "\t")}\n\nconst script = document.createElement("script");\n\nscript.setAttribute("src", "${new URL(window.location).origin}/static/scripts/sdk/1.0.0/api.js");\nscript.onload = () => window.DocSpace.SDK.initFrame(config);\n\ndocument.body.appendChild(script);`;
const codeString = `const config = ${JSON.stringify(config, null, "\t")}\n\nconst script = document.createElement("script");\n\nscript.setAttribute("src", "${SDK_SCRIPT_URL}");\nscript.onload = () => window.DocSpace.SDK.initFrame(config);\n\ndocument.body.appendChild(script);`;
const extensions = [javascript({ jsx: true })];

View File

@ -74,7 +74,7 @@ const LDAP = ({
}
};
if (!isLoaded) return <LdapLoader />;
if (!isLoaded && isLdapAvailable) return <LdapLoader />;
return (
<StyledLdapPage
isSmallWindow={isSmallWindow}

View File

@ -60,7 +60,7 @@ const StorageManagement = ({
ready && setDocumentTitle(t("Settings:StorageManagement"));
}, [ready]);
if (!isInit || !ready) return <SettingsStorageManagementSkeleton />;
if (!ready || !isInit) return <SettingsStorageManagementSkeleton />;
return (
<StyledBody>

View File

@ -74,6 +74,10 @@ const StyledTableRow = styled(TableRow)`
margin-left: 8px;
`}
}
.remove-cell {
justify-content: flex-end;
}
`;
StyledTableRow.defaultProps = { theme: Base };
@ -137,15 +141,13 @@ const SessionsTableRow = (props) => {
</TableCell>
{showRemoveIcon && (
<TableCell>
<Box style={{ marginLeft: "8px" }}>
<IconButton
size={20}
iconName={RemoveSessionSvgUrl}
isClickable
onClick={onRemoveClick}
/>
</Box>
<TableCell className="remove-cell">
<IconButton
size={20}
iconName={RemoveSessionSvgUrl}
isClickable
onClick={onRemoveClick}
/>
</TableCell>
)}
</StyledTableRow>

View File

@ -102,7 +102,9 @@ const VersionRow = (props) => {
const versionDate = getCorrectDate(culture, info.updated, "L", "LTS");
const title = `${Encoder.htmlDecode(info.updatedBy?.displayName)}`;
const title = info.updatedBy?.isAnonim
? t("Common:Anonymous")
: `${Encoder.htmlDecode(info.updatedBy?.displayName)}`;
const onDownloadAction = () =>
openUrl(`${info.viewUrl}&version=${info.version}`, UrlActionType.Download);
@ -278,16 +280,27 @@ const VersionRow = (props) => {
>
{versionDate}
</Link>
<Link
onClick={onUserClick}
fontWeight={600}
fontSize="14px"
title={title}
isTextOverflow={true}
className="version-link-file"
>
{title}
</Link>
{info.updatedBy?.isAnonim ? (
<Text
fontWeight={600}
color={theme.filesVersionHistory.color}
fontSize="14px"
title={title}
>
{title}
</Text>
) : (
<Link
onClick={onUserClick}
fontWeight={600}
fontSize="14px"
title={title}
isTextOverflow={true}
className="version-link-file"
>
{title}
</Link>
)}
</Box>
{/*<Text

View File

@ -57,7 +57,7 @@ import MuteReactSvgUrl from "PUBLIC_DIR/images/icons/16/mute.react.svg?url";
import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url";
import InvitationLinkReactSvgUrl from "PUBLIC_DIR/images/invitation.link.react.svg?url";
import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import MailReactSvgUrl from "PUBLIC_DIR/images/mail.react.svg?url";
import RoomArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url";
import PluginActionsSvgUrl from "PUBLIC_DIR/images/plugin.actions.react.svg?url";
@ -80,6 +80,7 @@ import FormGalleryReactSvgUrl from "PUBLIC_DIR/images/form.gallery.react.svg?url
import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg?url";
import ActionsUploadReactSvgUrl from "PUBLIC_DIR/images/actions.upload.react.svg?url";
import PluginMoreReactSvgUrl from "PUBLIC_DIR/images/plugin.more.react.svg?url";
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
import { getCategoryUrl } from "@docspace/client/src/helpers/utils";
@ -443,6 +444,29 @@ class ContextOptionsStore {
toastr.success(t("Translations:LinkCopySuccess"));
};
onOpenEmbeddingSettings = async (item) => {
const { shared, navigationPath, getSelectedFolder } =
this.selectedFolderStore;
const { setLinkParams, setEmbeddingPanelData } = this.dialogsStore;
const sharedItem = shared
? getSelectedFolder()
: navigationPath.find((r) => r.shared);
if (!sharedItem) return;
const isPublicRoomType = sharedItem.roomType === RoomsType.PublicRoom;
const isFormRoom = sharedItem.roomType === RoomsType.FormRoom;
setLinkParams({
roomId: sharedItem?.id,
isPublic: isPublicRoomType,
isFormRoom,
});
setEmbeddingPanelData({ visible: true, fileId: item.id });
};
onCreateAndCopySharedLink = async (item, t) => {
const primaryLink = await this.filesStore.getPrimaryLink(item.id);
@ -1235,14 +1259,14 @@ class ContextOptionsStore {
item.roomType === RoomsType.FormRoom ||
item.roomType === RoomsType.CustomRoom;
const { shared, navigationPath } = this.selectedFolderStore;
if (item.isRoom && withOpen) {
withOpen =
this.selectedFolderStore.navigationPath.findIndex(
(f) => f.id === item.id,
) === -1;
withOpen = navigationPath.findIndex((f) => f.id === item.id) === -1;
}
const isArchive = item.rootFolderType === FolderType.Archive;
const isShared = shared || navigationPath.findIndex((r) => r.shared) > -1;
const optionsModel = [
{
@ -1449,6 +1473,14 @@ class ContextOptionsStore {
// icon: MailReactSvgUrl,
// disabled: emailSendIsDisabled,
// },
{
id: "option_embedding-setting",
key: "embedding-settings",
label: t("Files:Embed"),
icon: CodeReactSvgUrl,
onClick: () => this.onOpenEmbeddingSettings(item),
disabled: !item.security?.Embed,
},
{
id: "option_show-info",
key: "show-info",

View File

@ -103,7 +103,7 @@ class DialogsStore {
createRoomConfirmDialogVisible = false;
changeUserTypeDialogVisible = false;
editLinkPanelIsVisible = false;
embeddingPanelIsVisible = false;
embeddingPanelData = { visible: false, fileId: null };
submitToGalleryDialogVisible = false;
linkParams = null;
leaveRoomDialogVisible = false;
@ -486,8 +486,8 @@ class DialogsStore {
this.deleteLinkDialogVisible = visible;
};
setEmbeddingPanelIsVisible = (embeddingPanelIsVisible) => {
this.embeddingPanelIsVisible = embeddingPanelIsVisible;
setEmbeddingPanelData = (embeddingPanelData) => {
this.embeddingPanelData = embeddingPanelData;
};
setMoveToPublicRoomVisible = (visible, data = null) => {

View File

@ -2065,6 +2065,7 @@ class FilesStore {
"separator-SubmitToGallery",
"link-for-room-members",
"sharing-settings",
"embedding-settings",
// "external-link",
"owner-change",
// "link-for-portal-users",
@ -2192,7 +2193,10 @@ class FilesStore {
}
if (!canViewFile || isRecycleBinFolder) {
fileOptions = this.removeOptions(fileOptions, ["preview"]);
fileOptions = this.removeOptions(fileOptions, [
"preview",
"embedding-settings",
]);
}
if (!canOpenPlayer || isRecycleBinFolder) {
@ -2324,6 +2328,10 @@ class FilesStore {
]);
}
if (this.publicRoomStore.isPublicRoom) {
fileOptions = this.removeOptions(fileOptions, ["embedding-settings"]);
}
// if (isPrivacyFolder) {
// fileOptions = this.removeOptions(fileOptions, [
// "preview",

View File

@ -150,14 +150,12 @@ class OformsStore {
const formName = "&fields[0]=name_form";
const updatedAt = "&fields[1]=updatedAt";
const size = "&fields[2]=file_size";
const filePages = "&fields[3]=file_pages";
const defaultDescription = "&fields[4]=description_card";
const templateDescription = "&fields[5]=template_desc";
const cardPrewiew = "&populate[card_prewiew][fields][6]=url";
const templateImage = "&populate[template_image][fields][7]=formats";
const fields = `${formName}${updatedAt}${size}${filePages}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`;
const fields = `${formName}${updatedAt}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`;
const params = `?${fields}&${filter.toApiUrlParams()}`;
const apiUrl = combineUrl(domain, path, params);

View File

@ -102,6 +102,8 @@ class StorageManagement {
);
}
this.needRecalculating = false;
try {
if (isInit) this.needRecalculating = await checkRecalculateQuota();
@ -123,12 +125,16 @@ class StorageManagement {
);
if (!this.quotaSettings.lastRecalculateDate && isInit) {
this.setIsRecalculating(true);
await recalculateQuota();
this.getIntervalCheckRecalculate();
return;
}
if (this.needRecalculating) this.getIntervalCheckRecalculate();
if (this.needRecalculating) {
this.setIsRecalculating(true);
this.getIntervalCheckRecalculate();
}
} catch (e) {
toastr.error(e);
}
@ -180,6 +186,9 @@ class StorageManagement {
};
getIntervalCheckRecalculate = () => {
let isWaitRequest = false;
if (this.intervalId) return;
this.intervalId = setInterval(async () => {
try {
if (isWaitRequest) {

View File

@ -36,7 +36,7 @@ const StyledBackdrop = styled.div<BackdropProps & { needBackground: boolean }>`
${(props) =>
props.needBackground &&
css`
backdrop-filter: blur(3px);
backdrop-filter: ${`blur(${props.theme.modalDialog.backdrop.blur}px)`};
`};
display: ${(props) => (props.visible ? "block" : "none")};

View File

@ -53,6 +53,7 @@ const StyledPublicRoomBar = styled.div`
.text-container_header {
color: ${(props) => props.theme.infoBlock.headerColor};
overflow: hidden;
}
.text-container_body {

View File

@ -27,8 +27,8 @@
import React from "react";
export interface PublicRoomBarProps {
headerText: string;
bodyText: string;
headerText: string | React.ReactNode;
bodyText: string | React.ReactNode;
iconName?: string;
onClose?: () => void;
className?: string;

View File

@ -36,6 +36,9 @@ import { PublicRoomBarProps } from "./PublicRoomBar.types";
const PublicRoomBar = (props: PublicRoomBarProps) => {
const { headerText, bodyText, iconName, onClose, ...rest } = props;
const headerAs = typeof headerText !== "string" ? "div" : undefined;
const bodyAs = typeof bodyText !== "string" ? "div" : undefined;
return (
<StyledPublicRoomBar {...rest}>
<div className="text-container">
@ -43,11 +46,20 @@ const PublicRoomBar = (props: PublicRoomBarProps) => {
<div className="header-icon">
<ReactSVG src={iconName || PeopleIcon} />
</div>
<Text className="text-container_header" fontWeight={600}>
<Text
className="text-container_header"
fontWeight={600}
as={headerAs}
>
{headerText}
</Text>
</div>
<Text className="text-container_body" fontSize="12px" fontWeight={400}>
<Text
className="text-container_body"
fontSize="12px"
fontWeight={400}
as={bodyAs}
>
{bodyText}
</Text>
</div>

View File

@ -347,6 +347,9 @@ class TableHeader extends React.Component<
const storageSize =
!resetColumnsSize && localStorage.getItem(columnStorageName);
const storageInfoSize =
!resetColumnsSize && localStorage.getItem(columnInfoPanelStorageName);
// TODO: If defaultSize(75px) is less than defaultMinColumnSize(110px) the calculations work correctly
const defaultSize =
columns.find((col) => col.defaultSize && col.enable)?.defaultSize || 0;
@ -377,6 +380,10 @@ class TableHeader extends React.Component<
? storageSize.split(" ")
: containerGridTemplateColumns;
const tableInfoContainer = storageInfoSize
? storageInfoSize.split(" ")
: containerGridTemplateColumns;
const { hideColumns } = this.state;
if (
@ -406,9 +413,17 @@ class TableHeader extends React.Component<
.map((column) => getSubstring(column))
.reduce((x, y) => x + y);
const defaultInfoWidth = tableInfoContainer
.map((column) => getSubstring(column))
.reduce((x, y) => x + y);
const oldWidth = defaultWidth - defaultSize - settingsSize;
if (Math.round(defaultWidth) !== Math.round(containerWidth) && !isResized) {
const isDifferentWindowSize = infoPanelVisible
? Math.round(defaultInfoWidth) !== Math.round(containerWidth)
: Math.round(defaultWidth) !== Math.round(containerWidth);
if (isDifferentWindowSize && !isResized) {
if (infoPanelVisible) localStorage.removeItem(columnInfoPanelStorageName);
else localStorage.removeItem(columnStorageName);
this.onResize(true);

View File

@ -181,3 +181,9 @@ export const SYSTEM_THEME_KEY = "system_theme";
export const PRODUCT_NAME = "DocSpace";
export const BRAND_NAME = "ONLYOFFICE";
const SDK_VERSION = "1.0.0";
export const SDK_SCRIPT_URL =
typeof window !== "undefined"
? `${window.location.origin}/static/scripts/sdk/${SDK_VERSION}/api.js`
: "";

View File

@ -666,7 +666,7 @@ export const getBaseTheme = () => {
b: 38,
a: 0.2,
},
blur: 10,
blur: 9,
},
content: {
@ -3347,6 +3347,11 @@ export const getBaseTheme = () => {
colorClockIcon: "#657077",
},
embeddingPanel: {
descriptionTextColor: "#657077",
iconColor: "#657077",
},
completedForm: {
linkColor: "#4781D1",
descriptionColor: gray,

View File

@ -611,9 +611,9 @@ const Dark: TTheme = {
},
scrollbar: {
bgColor: "rgba(20, 20, 20, 0.4)",
hoverBgColor: "rgba(20, 20, 20, 0.64)",
pressBgColor: "rgba(20, 20, 20, 0.8)",
bgColor: "rgba(136, 136, 136, 0.4)",
hoverBgColor: "rgba(136, 136, 136, 0.64)",
pressBgColor: "rgba(136, 136, 136, 0.8)",
paddingInlineEnd: "17px !important",
paddingInlineEndMobile: "8px !important",
},
@ -637,7 +637,7 @@ const Dark: TTheme = {
b: 27,
a: 0.4,
},
blur: 10,
blur: 9,
},
content: {
@ -992,7 +992,7 @@ const Dark: TTheme = {
border: "none",
},
},
fieldContainer: {
horizontal: {
margin: "0 0 16px 0",
@ -3322,6 +3322,11 @@ const Dark: TTheme = {
dateTimePicker: {
colorClockIcon: "#ADADAD",
},
embeddingPanel: {
descriptionTextColor: "#ADADAD",
iconColor: "#ADADAD",
},
completedForm: {
linkColor: white,
descriptionColor: "#ADADAD",

View File

@ -1,9 +1,9 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_20597_65864)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.84646 0.979492L5.22299 14.5025L7.15485 15.0201L10.7783 1.49713L8.84646 0.979492ZM2.41419 7.99916L5.20702 5.20614L3.79276 3.79197L0.292868 7.2921C-0.0976332 7.68263 -0.0976212 8.31578 0.292895 8.7063L3.79278 12.2062L5.20699 10.7919L2.41419 7.99916ZM13.5857 8.00004L10.7928 5.20714L12.207 3.79292L15.707 7.29293C15.8945 7.48047 15.9999 7.73482 15.9999 8.00004C15.9999 8.26526 15.8945 8.51961 15.707 8.70715L12.2065 12.2076L10.7923 10.7934L13.5857 8.00004Z" fill="#333333"/>
<g clip-path="url(#clip0_309_1831)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.84658 0.979492L5.22312 14.5025L7.15497 15.0201L10.7784 1.49713L8.84658 0.979492ZM2.41431 7.99916L5.20714 5.20614L3.79288 3.79197L0.29299 7.2921C-0.0975112 7.68263 -0.0974991 8.31578 0.293017 8.7063L3.7929 12.2062L5.20711 10.7919L2.41431 7.99916ZM13.5858 8.00004L10.7929 5.20714L12.2071 3.79292L15.7071 7.29293C15.8947 7.48047 16 7.73482 16 8.00004C16 8.26526 15.8947 8.51961 15.7071 8.70715L12.2067 12.2076L10.7925 10.7934L13.5858 8.00004Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_20597_65864">
<clipPath id="clip0_309_1831">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB