Merge branch 'develop' into feature/templates

This commit is contained in:
Nikita Gopienko 2024-05-21 12:19:05 +03:00
commit 088f132c66
27 changed files with 1611 additions and 2203 deletions

View File

@ -0,0 +1,39 @@
// (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
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" },
];
export const defaultWidthDimension = dataDimensions[0];
export const defaultHeightDimension = dataDimensions[0];
export const defaultWidth = "100";
export const defaultHeight = "100";

View File

@ -26,39 +26,32 @@
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { PreviewBlock } from "../sub-components/PreviewBlock";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { Button } from "@docspace/shared/components/button";
const showPreviewThreshold = 720;
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
Frame,
Container,
RowContainer,
Preview,
GetCodeButtonWrapper,
ControlsSection,
CodeWrapper,
} from "./StyledPresets";
const DocSpace = (props) => {
@ -66,26 +59,10 @@ const DocSpace = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [config, setConfig] = useState({
mode: "manager",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
showHeader: true,
showTitle: true,
@ -104,33 +81,19 @@ const DocSpace = (props) => {
},
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
useEffect(() => {
const scroll = document.getElementsByClassName("section-scroll")[0];
if (scroll) {
@ -138,208 +101,57 @@ const DocSpace = (props) => {
}
}, []);
const onChangeTab = () => {
loadFrame();
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const preview = (
<Frame
width={
widthDimension.label === "px" ? width + widthDimension.label : undefined
}
height={
heightDimension.label === "px"
? height + heightDimension.label
: undefined
}
width={config.width.includes("px") ? config.width : undefined}
height={config.height.includes("px") ? config.height : undefined}
targetId={frameId}
>
<Box id={frameId}></Box>
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("DocspaceDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleDocSpace")}</CategoryHeader>
<PresetWrapper
description={t("DocspaceDescription")}
header={t("CreateSampleDocSpace")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer onSelect={onChangeTab} elements={dataTabs} />
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -26,46 +26,42 @@
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import FilesSelectorInput from "SRC_DIR/components/FilesSelectorInput";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { FilesSelectorFilterTypes } from "@docspace/shared/enums";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import EmptyIframeContainer from "../sub-components/EmptyIframeContainer";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { Button } from "@docspace/shared/components/button";
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { PreviewBlock } from "../sub-components/PreviewBlock";
const showPreviewThreshold = 720;
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
LabelGroup,
ControlsSection,
Frame,
Container,
RowContainer,
Preview,
GetCodeButtonWrapper,
FilesSelectorInputWrapper,
CodeWrapper,
} from "./StyledPresets";
const Editor = (props) => {
@ -73,57 +69,27 @@ const Editor = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [config, setConfig] = useState({
mode: "editor",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
init: false,
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
useEffect(() => {
const scroll = document.getElementsByClassName("section-scroll")[0];
if (scroll) {
@ -131,26 +97,6 @@ const Editor = (props) => {
}
}, []);
const onChangeTab = () => {
loadFrame();
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFileId = async (file) => {
const newConfig = {
id: file.id,
@ -170,65 +116,22 @@ const Editor = (props) => {
});
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const preview = (
<Frame
width={
config.id !== undefined && widthDimension.label === "px"
? width + widthDimension.label
config.id !== undefined && config.width.includes("px")
? config.width
: undefined
}
height={
config.id !== undefined && heightDimension.label === "px"
? height + heightDimension.label
config.id !== undefined && config.height.includes("px")
? config.height
: undefined
}
targetId={frameId}
>
{config.id !== undefined ? (
<>
<Box id={frameId}></Box>
</>
<Box id={frameId}></Box>
) : (
<EmptyIframeContainer
text={t("FilePreview")}
@ -239,54 +142,22 @@ const Editor = (props) => {
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("EditorDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleEditor")}</CategoryHeader>
<PresetWrapper
description={t("EditorDescription")}
header={t("CreateSampleEditor")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer
isDisabled={config?.id === undefined}
onSelect={onChangeTab}
elements={dataTabs}
/>
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
isDisabled={config?.id === undefined}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("FileId")}</CategorySubHeader>
@ -307,58 +178,25 @@ const Editor = (props) => {
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
{/* <InterfaceElements>
@ -367,48 +205,26 @@ const Editor = (props) => {
className="checkbox"
label={t("RightPanelCollapsed")}
onChange={() => {}}
isChecked={true}
isChecked
/>
<Checkbox
className="checkbox"
label={t("TabPlugins")}
onChange={() => {}}
isChecked={true}
isChecked
/>
<RowContainer>
<Checkbox label={t("Chat")} onChange={() => {}} isChecked={true} />
<Checkbox label={t("Chat")} onChange={() => {}} isChecked />
<Text color="gray">({t("InLeftPanel")})</Text>
</RowContainer>
<RowContainer>
<Checkbox label={t("FeedbackAndSupport")} onChange={() => {}} isChecked={true} />
<Checkbox label={t("FeedbackAndSupport")} onChange={() => {}} isChecked />
<Text color="gray">({t("InLeftPanel")})</Text>
</RowContainer>
</InterfaceElements> */}
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -26,30 +26,18 @@
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import FilesSelectorInput from "SRC_DIR/components/FilesSelectorInput";
import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group";
import { ColorInput } from "@docspace/shared/components/color-input";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import { HelpButton } from "@docspace/shared/components/help-button";
import { Button } from "@docspace/shared/components/button";
import { FilterType } from "@docspace/shared/enums";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { FilesSelectorFilterTypes } from "@docspace/shared/enums";
import { TooltipContent } from "../sub-components/TooltipContent";
@ -60,24 +48,35 @@ import SearchUrlDark from "PUBLIC_DIR/images/sdk-presets_files-search_dark.png?u
import { toastr } from "@docspace/shared/components/toast";
const showPreviewThreshold = 720;
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { SelectTextInput } from "../sub-components/SelectTextInput";
import { CancelTextInput } from "../sub-components/CancelTextInput";
import { MainElementParameter } from "../sub-components/MainElementParameter";
import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
LabelGroup,
ControlsSection,
Frame,
Container,
RowContainer,
Preview,
GetCodeButtonWrapper,
FilesSelectorInputWrapper,
CodeWrapper,
} from "./StyledPresets";
const FileSelector = (props) => {
@ -85,26 +84,6 @@ const FileSelector = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const elementDisplayOptions = [
{ value: "element", label: t("ElementItself") },
{
value: "button",
label: (
<RowContainer>
{t("Common:Button")}
<Text color="gray">{`(${t("ElementCalledAfterClicking")})`}</Text>
</RowContainer>
),
},
];
const fileTypeDisplay = [
{ value: FilesSelectorFilterTypes.ALL, label: t("AllTypes") },
{ value: "EditorSupportedTypes", label: t("AllTypesSupportedByEditor") },
@ -154,25 +133,14 @@ const FileSelector = (props) => {
},
];
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [sharedLinks, setSharedLinks] = useState(null);
const [selectedElementType, setSelectedElementType] = useState(
elementDisplayOptions[1].value,
);
const [typeDisplay, setTypeDisplay] = useState(fileTypeDisplay[0].value);
const [selectedType, setSelectedType] = useState(fileOptions[0]);
const [config, setConfig] = useState({
mode: "file-selector",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
init: true,
showSelectorCancel: true,
@ -180,10 +148,9 @@ const FileSelector = (props) => {
withSearch: true,
acceptButtonLabel: t("Common:SelectAction"),
cancelButtonLabel: t("Common:CancelButton"),
// withBreadCrumbs: true,
withSubtitle: true,
filterParam: FilesSelectorFilterTypes.ALL,
isButtonMode: selectedElementType === "button",
isButtonMode: true,
buttonWithLogo: true,
events: {
onSelectCallback: (items) => {
@ -198,30 +165,16 @@ const FileSelector = (props) => {
},
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
@ -232,43 +185,6 @@ const FileSelector = (props) => {
}
}, []);
const toggleButtonMode = (e) => {
setSelectedElementType(e.target.value);
setConfig((config) => ({
...config,
isButtonMode: e.target.value === "button",
}));
};
const onChangeTab = (tab) => {
if (tab.key === "preview" && selectedElementType === "button") {
setConfig((config) => ({ ...config, isButtonMode: true }));
} else if (tab.key === "selector-preview") {
setConfig((config) => ({ ...config, isButtonMode: false }));
} else if (tab.key === "code") {
setConfig((config) => ({
...config,
isButtonMode: selectedElementType === "button",
}));
}
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFolderId = async (id, publicInPath) => {
let newConfig = { id, requestToken: null, rootPath: "/rooms/shared/" };
@ -306,12 +222,6 @@ const FileSelector = (props) => {
});
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const changeColumnsOption = (e) => {
setTypeDisplay(e.target.value);
setConfig((config) => {
@ -325,26 +235,6 @@ const FileSelector = (props) => {
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onTypeSelect = (option) => {
setSelectedType(option);
setConfig((config) => {
@ -356,223 +246,68 @@ const FileSelector = (props) => {
setConfig((config) => ({ ...config, withSearch: !config.withSearch }));
};
// const toggleBreadCrumbs = () => {
// setConfig((config) => ({ ...config, withBreadCrumbs: !config.withBreadCrumbs }));
// };
const toggleWithSubtitle = () => {
setConfig((config) => ({ ...config, withSubtitle: !config.withSubtitle }));
};
const onChangeAcceptLabel = (e) => {
setConfig((config) => {
return { ...config, acceptButtonLabel: e.target.value };
});
};
const onChangeCancelLabel = (e) => {
setConfig((config) => {
return { ...config, cancelButtonLabel: e.target.value };
});
};
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
const setButtonColor = (color) => {
setConfig((config) => ({ ...config, buttonColor: color }));
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const preview = (
<Frame
width={
widthDimension.label === "px" ? width + widthDimension.label : undefined
}
height={
heightDimension.label === "px"
? height + heightDimension.label
: undefined
}
width={config.width.includes("px") ? config.width : undefined}
height={config.height.includes("px") ? config.height : undefined}
targetId={frameId}
>
<Box id={frameId}></Box>
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("FileSelectorDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleFileSelector")}</CategoryHeader>
<PresetWrapper
description={t("FileSelectorDescription")}
header={t("CreateSampleFileSelector")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer onSelect={onChangeTab} elements={dataTabs} />
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("MainElementParameter")}</CategorySubHeader>
<RadioButtonGroup
orientation="vertical"
options={elementDisplayOptions}
name="elementDisplayInput"
selected={selectedElementType}
onClick={toggleButtonMode}
spacing="8px"
/>
{config.isButtonMode && (
<>
<CategorySubHeader>
{t("ButtonCustomization")}
</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("ButtonColor")} />
<ColorInput
scale
handleChange={setButtonColor}
defaultColor={"#5299E0"}
/>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("ButtonText")} />
<TextInput
scale
onChange={(e) => {
setConfig((config) => ({
...config,
buttonText: e.target.value,
}));
}}
placeholder={t("SelectToDocSpace")}
value={config.buttonText}
tabIndex={3}
/>
<Checkbox
className="checkbox"
label={t("Logo")}
onChange={() => {
setConfig((config) => ({
...config,
buttonWithLogo: !config.buttonWithLogo,
}));
}}
isChecked={config.buttonWithLogo}
/>
</ControlsGroup>
</>
)}
</ControlsSection>
<MainElementParameter
t={t}
config={config}
setConfig={setConfig}
isButtonMode={config.isButtonMode}
/>
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
<ControlsSection>
<Label className="label">{t("InterfaceElements")}</Label>
{/* <Checkbox
className="checkbox"
label={t("Common:Title")}
onChange={toggleBreadCrumbs}
isChecked={config.withBreadCrumbs}
/> */}
<LabelGroup>
<Checkbox
@ -614,22 +349,8 @@ const FileSelector = (props) => {
}
/>
</LabelGroup>
<Label className="label" text={t("SelectButtonText")} />
<TextInput
scale={true}
onChange={onChangeAcceptLabel}
placeholder={t("Common:SelectAction")}
value={config.acceptButtonLabel}
tabIndex={4}
/>
<Label className="label" text={t("CancelButtonText")} />
<TextInput
scale={true}
onChange={onChangeCancelLabel}
placeholder={t("Common:CancelButton")}
value={config.cancelButtonLabel}
tabIndex={4}
/>
<SelectTextInput t={t} config={config} setConfig={setConfig} />
<CancelTextInput t={t} config={config} setConfig={setConfig} />
</ControlsSection>
<ControlsSection>
@ -670,7 +391,7 @@ const FileSelector = (props) => {
/>
</LabelGroup>
<ComboBox
scaled={true}
scaled
onSelect={onChangeSharedLink}
options={sharedLinks}
selectedOption={sharedLinks[0]}
@ -702,7 +423,7 @@ const FileSelector = (props) => {
label: t("Common:SelectAction"),
}
}
scaled={true}
scaled
directionY="top"
selectedOption={selectedType}
/>
@ -711,29 +432,7 @@ const FileSelector = (props) => {
</ControlsSection>
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -24,31 +24,22 @@
// 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, useRef, useCallback } from "react";
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ComboBox } from "@docspace/shared/components/combobox";
import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import { SelectedItem } from "@docspace/shared/components/selected-item";
import FilesSelectorInput from "SRC_DIR/components/FilesSelectorInput";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { HelpButton } from "@docspace/shared/components/help-button";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { Button } from "@docspace/shared/components/button";
import { TooltipContent } from "../sub-components/TooltipContent";
import { useNavigate } from "react-router-dom";
import { Link } from "@docspace/shared/components/link";
import FilesFilter from "@docspace/shared/api/files/filter";
import LeftMenuUrl from "PUBLIC_DIR/images/sdk-presets_left-menu.react.svg?url";
@ -64,29 +55,40 @@ import ActionButtonDarkUrl from "PUBLIC_DIR/images/sdk-presets_action-button_dar
import SearchDarkUrl from "PUBLIC_DIR/images/sdk-presets_search_dark.png?url";
import HeaderDarkUrl from "PUBLIC_DIR/images/sdk-presets_header_dark.png?url";
const showPreviewThreshold = 720;
import { FilterBlock } from "../sub-components/FilterBlock";
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { SharedLinkHint } from "../sub-components/SharedLinkHint";
import { SearchTerm } from "../sub-components/SearchTerm";
import { ItemsCountBlock } from "../sub-components/ItemsCountBlock";
import { DisplayPageBlock } from "../sub-components/DisplayPageBlock";
import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
LabelGroup,
ControlsSection,
Frame,
Container,
RowContainer,
ColumnContainer,
Preview,
GetCodeButtonWrapper,
FilesSelectorInputWrapper,
SelectedItemsContainer,
CheckboxGroup,
CodeWrapper,
} from "./StyledPresets";
const Manager = (props) => {
@ -96,8 +98,6 @@ const Manager = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataSortBy = [
{ key: "DateAndTime", label: t("Common:LastModifiedDate"), default: true },
{ key: "AZ", label: t("Common:Title") },
@ -112,11 +112,6 @@ const Manager = (props) => {
{ key: "ascending", label: t("Ascending") },
];
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const columnDisplayOptions = [
{ value: "default", label: t("DefaultColumnsOption") },
{ value: "custom", label: t("SetItUp") },
@ -127,23 +122,8 @@ const Manager = (props) => {
{ key: "Activity", label: t("Files:ByLastModified") },
]);
const settingsTranslations = {
password: t("Common:Password").toLowerCase(),
denyDownload: t("FileContentCopy").toLowerCase(),
expirationDate: t("LimitByTime").toLowerCase(),
};
const [sortBy, setSortBy] = useState(dataSortBy[0]);
const [sortOrder, setSortOrder] = useState(dataSortOrder[0]);
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [withSubfolders, setWithSubfolders] = useState(false);
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [sharedLinks, setSharedLinks] = useState(null);
const [columnDisplay, setColumnDisplay] = useState(
columnDisplayOptions[0].value,
@ -158,8 +138,8 @@ const Manager = (props) => {
const [config, setConfig] = useState({
mode: "manager",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
showHeader: true,
showTitle: true,
@ -178,33 +158,19 @@ const Manager = (props) => {
},
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
useEffect(() => {
const scroll = document.getElementsByClassName("section-scroll")[0];
if (scroll) {
@ -212,26 +178,6 @@ const Manager = (props) => {
}
}, []);
const onChangeTab = () => {
loadFrame();
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFolderId = async (id, publicInPath) => {
let newConfig = { id, requestToken: null, rootPath: "/rooms/shared/" };
@ -284,20 +230,6 @@ const Manager = (props) => {
});
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const onChangeWithSubfolders = (e) => {
setConfig((config) => {
return { ...config, withSubfolders: !withSubfolders };
});
setWithSubfolders(!withSubfolders);
};
const onChangeSortBy = (item) => {
setConfig((config) => {
return { ...config, filter: { ...config.filter, sortby: item.key } };
@ -314,22 +246,6 @@ const Manager = (props) => {
setSortOrder(item);
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const onChangeShowHeader = (e) => {
setConfig((config) => {
return { ...config, showHeader: !config.showHeader };
@ -366,27 +282,6 @@ const Manager = (props) => {
});
};
const onChangeCount = (e) => {
setConfig((config) => {
return { ...config, filter: { ...config.filter, count: e.target.value } };
});
};
const onChangePage = (e) => {
setConfig((config) => {
return { ...config, filter: { ...config.filter, page: e.target.value } };
});
};
const onChangeSearch = (e) => {
setConfig((config) => {
return {
...config,
filter: { ...config.filter, filterValue: e.target.value },
};
});
};
const changeColumnsOption = (e) => {
if (e.target.value === "default") {
setConfig((config) => ({
@ -402,10 +297,6 @@ const Manager = (props) => {
setColumnDisplay(e.target.value);
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onColumnSelect = (option) => {
setColumnsOptions((prevColumnsOptions) =>
prevColumnsOptions.filter((column) => column.key !== option.key),
@ -442,138 +333,55 @@ const Manager = (props) => {
navigate(`/rooms/shared/${id}/filter?${filter.toUrlParams()}`);
};
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const redirectToSelectedRoom = () => navigateRoom(config.id);
const preview = (
<Frame
width={
config.id !== undefined && widthDimension.label === "px"
? width + widthDimension.label
: undefined
}
height={
config.id !== undefined && heightDimension.label === "px"
? height + heightDimension.label
: undefined
}
width={config.width.includes("px") ? config.width : undefined}
height={config.height.includes("px") ? config.height : undefined}
targetId={frameId}
>
<Box id={frameId}></Box>
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("CustomDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleDocSpace")}</CategoryHeader>
<PresetWrapper
description={t("CustomDescription")}
header={t("CreateSampleDocSpace")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer onSelect={onChangeTab} elements={dataTabs} />
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
<ControlsSection>
@ -742,7 +550,7 @@ const Manager = (props) => {
/>
</LabelGroup>
<ComboBox
scaled={true}
scaled
onSelect={onChangeSharedLink}
options={sharedLinks}
selectedOption={selectedLink}
@ -750,80 +558,13 @@ const Manager = (props) => {
directionY="bottom"
/>
{selectedLink && selectedLink.settings.length === 1 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription", {
parameter:
settingsTranslations[selectedLink.settings[0]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : selectedLink.settings.length === 2 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription2", {
parameter1:
settingsTranslations[selectedLink.settings[0]],
parameter2:
settingsTranslations[selectedLink.settings[1]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : selectedLink.settings.length === 3 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription3", {
parameter1:
settingsTranslations[selectedLink.settings[0]],
parameter2:
settingsTranslations[selectedLink.settings[1]],
parameter3:
settingsTranslations[selectedLink.settings[2]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : (
<></>
{selectedLink && (
<SharedLinkHint
t={t}
linkSettings={selectedLink.settings}
redirectToSelectedRoom={redirectToSelectedRoom}
currentColorScheme={currentColorScheme}
/>
)}
</ControlsGroup>
)}
@ -834,29 +575,14 @@ const Manager = (props) => {
<FilterBlock t={t} config={config} setConfig={setConfig} />
</ColumnContainer>
<ControlsGroup>
<Label className="label" text={t("SearchTerm")} />
<ColumnContainer>
<TextInput
scale={true}
onChange={onChangeSearch}
placeholder={t("Common:Search")}
value={config.filter.filterValue}
tabIndex={5}
/>
<Checkbox
className="checkbox"
label={t("Files:WithSubfolders")}
onChange={onChangeWithSubfolders}
isChecked={withSubfolders}
/>
</ColumnContainer>
<SearchTerm t={t} config={config} setConfig={setConfig} />
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("Common:SortBy")} />
<ComboBox
onSelect={onChangeSortBy}
options={dataSortBy}
scaled={true}
scaled
selectedOption={sortBy}
displaySelectedOption
directionY="top"
@ -867,42 +593,18 @@ const Manager = (props) => {
<ComboBox
onSelect={onChangeSortOrder}
options={dataSortOrder}
scaled={true}
scaled
selectedOption={sortOrder}
displaySelectedOption
directionY="top"
/>
</ControlsGroup>
<ControlsGroup>
<LabelGroup>
<Label className="label" text={t("ItemsCount")} />
<HelpButton
offsetRight={0}
size={12}
tooltipContent={
<Text fontSize="12px">{t("ItemsCountDescription")}</Text>
}
/>
</LabelGroup>
<TextInput
scale={true}
onChange={onChangeCount}
placeholder={t("EnterCount")}
value={config.filter.count}
tabIndex={6}
/>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("Page")} />
<TextInput
scale={true}
onChange={onChangePage}
placeholder={t("EnterPage")}
value={config.filter.page}
isDisabled={!config.filter.count}
tabIndex={7}
/>
</ControlsGroup>
<ItemsCountBlock
t={t}
count={config.filter.count}
setConfig={setConfig}
/>
<DisplayPageBlock t={t} config={config} setConfig={setConfig} />
<Label className="label" text={t("DisplayColumns")} />
<RadioButtonGroup
orientation="vertical"
@ -922,7 +624,7 @@ const Manager = (props) => {
label: t("Common:SelectAction"),
}
}
scaled={true}
scaled
directionY="top"
selectedOption={{
key: "Select",
@ -946,29 +648,7 @@ const Manager = (props) => {
</ControlsSection>
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -28,44 +28,41 @@ import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group";
import { ColorInput } from "@docspace/shared/components/color-input";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { Button } from "@docspace/shared/components/button";
import { RoomsType } from "@docspace/shared/enums";
import { toastr } from "@docspace/shared/components/toast";
const showPreviewThreshold = 720;
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { SelectTextInput } from "../sub-components/SelectTextInput";
import { CancelTextInput } from "../sub-components/CancelTextInput";
import { MainElementParameter } from "../sub-components/MainElementParameter";
import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
ControlsSection,
Frame,
Container,
RowContainer,
Preview,
GetCodeButtonWrapper,
CodeWrapper,
} from "./StyledPresets";
const RoomSelector = (props) => {
@ -73,26 +70,6 @@ const RoomSelector = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const elementDisplayOptions = [
{ value: "element", label: t("ElementItself") },
{
value: "button",
label: (
<RowContainer>
{t("Common:Button")}
<Text color="gray">{`(${t("ElementCalledAfterClicking")})`}</Text>
</RowContainer>
),
},
];
const roomTypeOptions = [
{
key: "room-type-all",
@ -122,17 +99,6 @@ const RoomSelector = (props) => {
},
];
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [selectedElementType, setSelectedElementType] = useState(
elementDisplayOptions[0].value,
);
const [roomType, setRoomType] = useState(roomTypeOptions[0]);
const debouncedOnSelect = debounce((items) => {
@ -141,8 +107,8 @@ const RoomSelector = (props) => {
const [config, setConfig] = useState({
mode: "room-selector",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
init: true,
showSelectorCancel: true,
@ -163,30 +129,16 @@ const RoomSelector = (props) => {
},
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return destroyFrame;
});
@ -197,119 +149,25 @@ const RoomSelector = (props) => {
}
}, []);
const toggleButtonMode = (e) => {
setSelectedElementType(e.target.value);
setConfig((config) => ({
...config,
isButtonMode: e.target.value === "button",
}));
};
const changeRoomType = (option) => {
setRoomType(option);
setConfig((config) => ({ ...config, roomType: option.roomType }));
};
const onChangeTab = (tab) => {
if (tab.key === "preview" && selectedElementType === "button") {
setConfig((config) => ({ ...config, isButtonMode: true }));
} else if (tab.key === "selector-preview") {
setConfig((config) => ({ ...config, isButtonMode: false }));
} else if (tab.key === "code") {
setConfig((config) => ({
...config,
isButtonMode: selectedElementType === "button",
}));
}
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const toggleWithSearch = () => {
setConfig((config) => ({ ...config, withSearch: !config.withSearch }));
};
const onChangeAcceptLabel = (e) => {
setConfig((config) => {
return { ...config, acceptButtonLabel: e.target.value };
});
};
const onChangeCancelLabel = (e) => {
setConfig((config) => {
return { ...config, cancelButtonLabel: e.target.value };
});
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
const setButtonColor = (color) => {
setConfig((config) => ({ ...config, buttonColor: color }));
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const preview = (
<Frame
width={
config.id !== undefined && widthDimension.label === "px"
? width + widthDimension.label
config.id !== undefined && config.width.includes("px")
? config.width
: undefined
}
height={
config.id !== undefined && heightDimension.label === "px"
? height + heightDimension.label
config.id !== undefined && config.height.includes("px")
? config.height
: undefined
}
targetId={frameId}
@ -318,158 +176,50 @@ const RoomSelector = (props) => {
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("RoomSelectorDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleRoomSelector")}</CategoryHeader>
<PresetWrapper
description={t("RoomSelectorDescription")}
header={t("CreateSampleRoomSelector")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer onSelect={onChangeTab} elements={dataTabs} />
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("MainElementParameter")}</CategorySubHeader>
<RadioButtonGroup
orientation="vertical"
options={elementDisplayOptions}
name="elementDisplayInput"
selected={selectedElementType}
onClick={toggleButtonMode}
spacing="8px"
/>
{config.isButtonMode && (
<>
<CategorySubHeader>
{t("ButtonCustomization")}
</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("ButtonColor")} />
<ColorInput
scale
handleChange={setButtonColor}
defaultColor={"#5299E0"}
/>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("ButtonText")} />
<TextInput
scale
onChange={(e) => {
setConfig((config) => ({
...config,
buttonText: e.target.value,
}));
}}
placeholder={t("SelectToDocSpace")}
value={config.buttonText}
tabIndex={3}
/>
<Checkbox
className="checkbox"
label={t("Logo")}
onChange={() => {
setConfig((config) => ({
...config,
buttonWithLogo: !config.buttonWithLogo,
}));
}}
isChecked={config.buttonWithLogo}
/>
</ControlsGroup>
</>
)}
</ControlsSection>
<MainElementParameter
t={t}
config={config}
setConfig={setConfig}
isButtonMode={config.isButtonMode}
/>
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={4}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={5}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={6}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
<ControlsSection>
@ -480,22 +230,8 @@ const RoomSelector = (props) => {
onChange={toggleWithSearch}
isChecked={config.withSearch}
/>
<Label className="label" text={t("SelectButtonText")} />
<TextInput
scale={true}
onChange={onChangeAcceptLabel}
placeholder={t("Common:SelectAction")}
value={config.acceptButtonLabel}
tabIndex={7}
/>
<Label className="label" text={t("CancelButtonText")} />
<TextInput
scale={true}
onChange={onChangeCancelLabel}
placeholder={t("Common:CancelButton")}
value={config.cancelButtonLabel}
tabIndex={8}
/>
<SelectTextInput t={t} config={config} setConfig={setConfig} />
<CancelTextInput t={t} config={config} setConfig={setConfig} />
</ControlsSection>
<ControlsSection>
@ -505,7 +241,7 @@ const RoomSelector = (props) => {
<ComboBox
onSelect={changeRoomType}
options={roomTypeOptions}
scaled={true}
scaled
selectedOption={roomType}
displaySelectedOption
directionY="top"
@ -513,29 +249,7 @@ const RoomSelector = (props) => {
</ControlsSection>
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -26,32 +26,20 @@
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import RoomsSelectorInput from "SRC_DIR/components/RoomsSelectorInput";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import { HelpButton } from "@docspace/shared/components/help-button";
import { Checkbox } from "@docspace/shared/components/checkbox";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import { Button } from "@docspace/shared/components/button";
import EmptyIframeContainer from "../sub-components/EmptyIframeContainer";
import CodeBlock from "../sub-components/CodeBlock";
import { TooltipContent } from "../sub-components/TooltipContent";
import { useNavigate } from "react-router-dom";
import { Link } from "@docspace/shared/components/link";
import FilesFilter from "@docspace/shared/api/files/filter";
import { RoomsType } from "@docspace/shared/enums";
@ -62,24 +50,33 @@ import SearchUrl from "PUBLIC_DIR/images/sdk-presets_search.react.svg?url";
import TitleDarkUrl from "PUBLIC_DIR/images/sdk-presets_title_dark.png?url";
import SearchDarkUrl from "PUBLIC_DIR/images/sdk-presets_search_dark.png?url";
const showPreviewThreshold = 720;
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { SharedLinkHint } from "../sub-components/SharedLinkHint";
import { PreviewBlock } from "../sub-components/PreviewBlock";
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
LabelGroup,
Frame,
Container,
RowContainer,
Preview,
GetCodeButtonWrapper,
FilesSelectorInputWrapper,
ControlsSection,
CodeWrapper,
CheckboxGroup,
} from "./StyledPresets";
@ -90,35 +87,14 @@ const SimpleRoom = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const settingsTranslations = {
password: t("Common:Password").toLowerCase(),
denyDownload: t("FileContentCopy").toLowerCase(),
expirationDate: t("LimitByTime").toLowerCase(),
};
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [sharedLinks, setSharedLinks] = useState(null);
const [selectedLink, setSelectedLink] = useState(null);
const [config, setConfig] = useState({
mode: "manager",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
showHeader: false,
showTitle: true,
@ -137,33 +113,19 @@ const SimpleRoom = (props) => {
},
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
useEffect(() => {
const scroll = document.getElementsByClassName("section-scroll")[0];
if (scroll) {
@ -171,26 +133,6 @@ const SimpleRoom = (props) => {
}
}, []);
const onChangeTab = () => {
loadFrame();
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFolderId = async (rooms) => {
const publicRoom = rooms[0];
@ -244,28 +186,6 @@ const SimpleRoom = (props) => {
});
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value };
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const onChangeShowTitle = () => {
setConfig((config) => {
return { ...config, showTitle: !config.showTitle };
@ -278,49 +198,30 @@ const SimpleRoom = (props) => {
});
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
const navigateRoom = (id) => {
const filter = FilesFilter.getDefault();
filter.folder = id;
navigate(`/rooms/shared/${id}/filter?${filter.toUrlParams()}`);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const redirectToSelectedRoom = () => navigateRoom(config.id);
const preview = (
<Frame
width={
config.id !== undefined && widthDimension.label === "px"
? width + widthDimension.label
config.id !== undefined && config.width.includes("px")
? config.width
: undefined
}
height={
config.id !== undefined && heightDimension.label === "px"
? height + heightDimension.label
config.id !== undefined && config.height.includes("px")
? config.height
: undefined
}
targetId={frameId}
>
{config.id !== undefined ? (
<>
<Box id={frameId}></Box>
</>
<Box id={frameId}></Box>
) : (
<EmptyIframeContainer
text={t("RoomPreview")}
@ -331,54 +232,22 @@ const SimpleRoom = (props) => {
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("PublicRoomDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSamplePublicRoom")}</CategoryHeader>
<PresetWrapper
description={t("PublicRoomDescription")}
header={t("CreateSamplePublicRoom")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer
isDisabled={config?.id === undefined}
onSelect={onChangeTab}
elements={dataTabs}
/>
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
isDisabled={config?.id === undefined}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("DataDisplay")}</CategorySubHeader>
@ -422,87 +291,20 @@ const SimpleRoom = (props) => {
/>
</LabelGroup>
<ComboBox
scaled={true}
scaled
onSelect={onChangeSharedLink}
options={sharedLinks}
selectedOption={selectedLink}
displaySelectedOption
directionY="bottom"
/>
{selectedLink && selectedLink.settings.length === 1 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription", {
parameter:
settingsTranslations[selectedLink.settings[0]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : selectedLink.settings.length === 2 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription2", {
parameter1:
settingsTranslations[selectedLink.settings[0]],
parameter2:
settingsTranslations[selectedLink.settings[1]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : selectedLink.settings.length === 3 ? (
<div>
<Text
className="linkHelp"
fontSize="12px"
lineHeight="16px"
>
{t("LinkSetDescription3", {
parameter1:
settingsTranslations[selectedLink.settings[0]],
parameter2:
settingsTranslations[selectedLink.settings[1]],
parameter3:
settingsTranslations[selectedLink.settings[2]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={() => navigateRoom(config.id)}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
) : (
<></>
{selectedLink && (
<SharedLinkHint
t={t}
linkSettings={selectedLink.settings}
redirectToSelectedRoom={redirectToSelectedRoom}
currentColorScheme={currentColorScheme}
/>
)}
</ControlsGroup>
)}
@ -510,58 +312,25 @@ const SimpleRoom = (props) => {
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
<ControlsSection>
@ -612,29 +381,7 @@ const SimpleRoom = (props) => {
</ControlsSection>
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -289,6 +289,7 @@ export const GetCodeButtonWrapper = styled.div`
bottom: 0;
margin-top: 32px;
background-color: ${({ theme }) => theme.backgroundColor};
z-index: 1;
@media ${mobile} {
position: fixed;

View File

@ -26,48 +26,44 @@
import { useState, useEffect } from "react";
import { withTranslation } from "react-i18next";
import debounce from "lodash.debounce";
import { Box } from "@docspace/shared/components/box";
import { TextInput } from "@docspace/shared/components/text-input";
import { Textarea } from "@docspace/shared/components/textarea";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ComboBox } from "@docspace/shared/components/combobox";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import FilesSelectorInput from "SRC_DIR/components/FilesSelectorInput";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
import { inject, observer } from "mobx-react";
import { ImageEditor } from "@docspace/shared/components/image-editor";
import { FilesSelectorFilterTypes } from "@docspace/shared/enums";
import { isTablet, isMobile } from "@docspace/shared/utils/device";
import EmptyIframeContainer from "../sub-components/EmptyIframeContainer";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import CodeBlock from "../sub-components/CodeBlock";
import { Button } from "@docspace/shared/components/button";
import { WidthSetter } from "../sub-components/WidthSetter";
import { HeightSetter } from "../sub-components/HeightSetter";
import { FrameIdSetter } from "../sub-components/FrameIdSetter";
import { PresetWrapper } from "../sub-components/PresetWrapper";
import { PreviewBlock } from "../sub-components/PreviewBlock";
const showPreviewThreshold = 720;
import { loadFrame } from "../utils";
import {
scriptUrl,
dataDimensions,
defaultWidthDimension,
defaultHeightDimension,
defaultWidth,
defaultHeight,
} from "../constants";
import {
SDKContainer,
Controls,
CategoryHeader,
CategorySubHeader,
CategoryDescription,
ControlsGroup,
LabelGroup,
ControlsSection,
Frame,
Container,
RowContainer,
ColumnContainer,
Preview,
GetCodeButtonWrapper,
FilesSelectorInputWrapper,
CodeWrapper,
} from "./StyledPresets";
const Viewer = (props) => {
@ -75,58 +71,28 @@ const Viewer = (props) => {
setDocumentTitle(t("JavascriptSdk"));
const scriptUrl = `${window.location.origin}/static/scripts/sdk/1.0.0/api.js`;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
{ key: "pixel", label: "px" },
];
const [widthDimension, setWidthDimension] = useState(dataDimensions[0]);
const [heightDimension, setHeightDimension] = useState(dataDimensions[0]);
const [width, setWidth] = useState("100");
const [height, setHeight] = useState("100");
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const [config, setConfig] = useState({
mode: "viewer",
editorType: "embedded",
width: `${width}${widthDimension.label}`,
height: `${height}${heightDimension.label}`,
width: `${defaultWidth}${defaultWidthDimension.label}`,
height: `${defaultHeight}${defaultHeightDimension.label}`,
frameId: "ds-frame",
init: false,
});
const params = objectToGetParams(config);
const frameId = config.frameId || "ds-frame";
const destroyFrame = () => {
window.DocSpace?.SDK?.frames[frameId]?.destroyFrame();
};
const loadFrame = debounce(() => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);
const loadCurrentFrame = () => loadFrame(config, scriptUrl);
useEffect(() => {
loadFrame();
loadCurrentFrame();
return () => destroyFrame();
});
useEffect(() => {
const scroll = document.getElementsByClassName("section-scroll")[0];
if (scroll) {
@ -134,26 +100,6 @@ const Viewer = (props) => {
}
}, []);
const onChangeTab = () => {
loadFrame();
};
const onChangeWidth = (e) => {
setConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
setWidth(e.target.value);
};
const onChangeHeight = (e) => {
setConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
setHeight(e.target.value);
};
const onChangeFileId = async (file) => {
const newConfig = {
id: file.id,
@ -173,65 +119,22 @@ const Viewer = (props) => {
});
};
const onChangeFrameId = (e) => {
setConfig((config) => {
return { ...config, frameId: e.target.value, init: true };
});
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const preview = (
<Frame
width={
config.id !== undefined && widthDimension.label === "px"
? width + widthDimension.label
config.id !== undefined && config.width.includes("px")
? config.width
: undefined
}
height={
config.id !== undefined && heightDimension.label === "px"
? height + heightDimension.label
config.id !== undefined && config.height.includes("px")
? config.height
: undefined
}
targetId={frameId}
>
{config.id !== undefined ? (
<>
<Box id={frameId}></Box>
</>
<Box id={frameId}></Box>
) : (
<EmptyIframeContainer
text={t("FilePreview")}
@ -242,54 +145,22 @@ const Viewer = (props) => {
</Frame>
);
const code = (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{t("ViewerDescription")}</Text>
</CategoryDescription>
<CategoryHeader>{t("CreateSampleViewer")}</CategoryHeader>
<PresetWrapper
description={t("ViewerDescription")}
header={t("CreateSampleViewer")}
>
<Container>
{showPreview && (
<Preview>
<TabsContainer
isDisabled={config?.id === undefined}
onSelect={onChangeTab}
elements={dataTabs}
/>
</Preview>
)}
<PreviewBlock
t={t}
loadCurrentFrame={loadCurrentFrame}
preview={preview}
theme={theme}
frameId={frameId}
scriptUrl={scriptUrl}
config={config}
isDisabled={config?.id === undefined}
/>
<Controls>
<ControlsSection>
<CategorySubHeader>{t("FileId")}</CategorySubHeader>
@ -310,58 +181,25 @@ const Viewer = (props) => {
<ControlsSection>
<CategorySubHeader>{t("CustomizingDisplay")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale={true}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
value={config.frameId}
tabIndex={4}
/>
</ControlsGroup>
<WidthSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultWidthDimension}
defaultWidth={defaultWidth}
/>
<HeightSetter
t={t}
setConfig={setConfig}
dataDimensions={dataDimensions}
defaultDimension={defaultHeightDimension}
defaultHeight={defaultHeight}
/>
<FrameIdSetter
t={t}
defaultFrameId={config.frameId}
setConfig={setConfig}
/>
</ControlsSection>
{/* <InterfaceElements>
@ -370,14 +208,14 @@ const Viewer = (props) => {
className="checkbox"
label={t("TabPlugins")}
onChange={() => {}}
isChecked={true}
isChecked
/>
<RowContainer>
<Checkbox label={t("Chat")} onChange={() => {}} isChecked={true} />
<Checkbox label={t("Chat")} onChange={() => {}} isChecked />
<Text color="gray">({t("InLeftPanel")})</Text>
</RowContainer>
<RowContainer>
<Checkbox label={t("FeedbackAndSupport")} onChange={() => {}} isChecked={true} />
<Checkbox label={t("FeedbackAndSupport")} onChange={() => {}} isChecked />
<Text color="gray">({t("InLeftPanel")})</Text>
</RowContainer>
</InterfaceElements>
@ -398,7 +236,7 @@ const Viewer = (props) => {
{ key: "2", label: "50%" },
{ key: "3", label: "25%" },
]}
scaled={true}
scaled
selectedOption={{ key: "1", label: "100%", default: true }}
displaySelectedOption
directionY="top"
@ -412,7 +250,7 @@ const Viewer = (props) => {
{ key: "3", label: "90%" },
{ key: "4", label: "180%" },
]}
scaled={true}
scaled
selectedOption={{ key: "1", label: "45%", default: true }}
displaySelectedOption
directionY="top"
@ -428,29 +266,7 @@ const Viewer = (props) => {
/> */}
</Controls>
</Container>
{!showPreview && (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
)}
</SDKContainer>
</PresetWrapper>
);
};

View File

@ -0,0 +1,61 @@
// (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, useCallback } from "react";
import { Label } from "@docspace/shared/components/label";
import { TextInput } from "@docspace/shared/components/text-input";
import debounce from "lodash.debounce";
export const CancelTextInput = ({ t, config, setConfig }) => {
const [value, setValue] = useState(config.cancelButtonLabel);
const debouncedSetConfig = useCallback(
debounce((value) => {
setConfig((config) => {
return { ...config, cancelButtonLabel: value };
});
}, 500),
[setConfig],
);
const onChangeCancelLabel = (e) => {
setValue(e.target.value);
debouncedSetConfig(e.target.value);
};
return (
<>
<Label className="label" text={t("CancelButtonText")} />
<TextInput
scale
onChange={onChangeCancelLabel}
placeholder={t("Common:CancelButton")}
value={value}
tabIndex={8}
/>
</>
);
};

View File

@ -0,0 +1,53 @@
// (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 { Textarea } from "@docspace/shared/components/textarea";
import { Text } from "@docspace/shared/components/text";
import CodeBlock from "../sub-components/CodeBlock";
import {
CategorySubHeader,
CodeWrapper,
} from "../presets/StyledPresets";
export const CodeToInsert = ({ t, theme, codeBlock, config }) => (
<CodeWrapper height="fit-content">
<CategorySubHeader className="copy-window-code">
{`HTML ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("HtmlCodeDescription")}
</Text>
<Textarea value={codeBlock} heightTextArea={153} />
<CategorySubHeader className="copy-window-code">
{`JavaScript ${t("CodeTitle")}`}
</CategorySubHeader>
<Text lineHeight="20px" color={theme.isBase ? "#657077" : "#ADADAD"}>
{t("JavaScriptCodeDescription")}
</Text>
<CodeBlock config={config} />
</CodeWrapper>
);

View File

@ -0,0 +1,65 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { TextInput } from "@docspace/shared/components/text-input";
import { Label } from "@docspace/shared/components/label";
import { ControlsGroup } from "../presets/StyledPresets";
export const DisplayPageBlock = ({ t, config, setConfig }) => {
const [value, setValue] = useState(config.filter.page);
const debouncedSetConfig = useCallback(
debounce((value) => {
setConfig((config) => ({
...config,
filter: { ...config.filter, page: value },
}));
}, 500),
[setConfig],
);
const onChangePage = (e) => {
setValue(e.target.value);
debouncedSetConfig(e.target.page);
};
return (
<ControlsGroup>
<Label className="label" text={t("Page")} />
<TextInput
scale
onChange={onChangePage}
placeholder={t("EnterPage")}
value={value}
isDisabled={!config.filter.count}
tabIndex={7}
/>
</ControlsGroup>
);
};

View File

@ -0,0 +1,65 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { TextInput } from "@docspace/shared/components/text-input";
import { Label } from "@docspace/shared/components/label";
import { ControlsGroup } from "../presets/StyledPresets";
export const FrameIdSetter = (props) => {
const { t, defaultFrameId, setConfig } = props;
const [frameId, setFrameId] = useState(defaultFrameId);
const debouncedSetConfig = useCallback(
debounce((frameId) => {
setConfig((config) => {
return { ...config, frameId };
});
}, 500),
[setConfig],
);
const onChangeFrameId = (e) => {
setFrameId(e.target.value);
debouncedSetConfig(e.target.value);
};
return (
<ControlsGroup>
<Label className="label" text={t("FrameId")} />
<TextInput
scale
value={frameId}
onChange={onChangeFrameId}
placeholder={t("EnterId")}
tabIndex={4}
/>
</ControlsGroup>
);
};

View File

@ -0,0 +1,60 @@
// (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 } from "react";
import GetCodeDialog from "../sub-components/GetCodeDialog";
import { Button } from "@docspace/shared/components/button";
import { GetCodeButtonWrapper } from "../presets/StyledPresets";
export const GetCodeBlock = ({ t, codeBlock, isDisabled }) => {
const [isGetCodeDialogOpened, setIsGetCodeDialogOpened] = useState(false);
const openGetCodeModal = () => setIsGetCodeDialogOpened(true);
const closeGetCodeModal = () => setIsGetCodeDialogOpened(false);
return (
<>
<GetCodeButtonWrapper>
<Button
id="get-sdk-code-button"
primary
size="normal"
scale
label={t("GetCode")}
onClick={openGetCodeModal}
isDisabled={isDisabled}
/>
</GetCodeButtonWrapper>
<GetCodeDialog
t={t}
visible={isGetCodeDialogOpened}
codeBlock={codeBlock}
onClose={closeGetCodeModal}
/>
</>
);
};

View File

@ -0,0 +1,87 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { TextInput } from "@docspace/shared/components/text-input";
import { Label } from "@docspace/shared/components/label";
import { ComboBox } from "@docspace/shared/components/combobox";
import { ControlsGroup, RowContainer } from "../presets/StyledPresets";
export const HeightSetter = (props) => {
const { t, setConfig, dataDimensions, defaultDimension, defaultHeight } =
props;
const [heightDimension, setHeightDimension] = useState(defaultDimension);
const [height, setHeight] = useState(defaultHeight);
const debouncedSetConfig = useCallback(
debounce((value, dimension) => {
setConfig((config) => {
return { ...config, height: `${value}${dimension}` };
});
}, 500),
[setConfig],
);
const onChangeHeight = (e) => {
setHeight(e.target.value);
debouncedSetConfig(e.target.value, heightDimension.label);
};
const onChangeHeightDimension = (item) => {
setConfig((config) => {
return { ...config, height: `${height}${item.label}` };
});
setHeightDimension(item);
};
return (
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Height")} />
<RowContainer combo>
<TextInput
onChange={onChangeHeight}
placeholder={t("EnterHeight")}
value={height}
tabIndex={3}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeHeightDimension}
options={dataDimensions}
selectedOption={heightDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
);
};

View File

@ -0,0 +1,74 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { TextInput } from "@docspace/shared/components/text-input";
import { HelpButton } from "@docspace/shared/components/help-button";
import { Label } from "@docspace/shared/components/label";
import { LabelGroup, ControlsGroup } from "../presets/StyledPresets";
export const ItemsCountBlock = ({ t, count, setConfig }) => {
const [value, setValue] = useState(count);
const debouncedSetConfig = useCallback(
debounce((value) => {
setConfig((config) => ({
...config,
filter: { ...config.filter, count: value },
}));
}, 500),
[setConfig],
);
const onChangeCount = (e) => {
debouncedSetConfig(e.target.value);
setValue(e.target.value);
};
return (
<ControlsGroup>
<LabelGroup>
<Label className="label" text={t("ItemsCount")} />
<HelpButton
offsetRight={0}
size={12}
tooltipContent={
<Text fontSize="12px">{t("ItemsCountDescription")}</Text>
}
/>
</LabelGroup>
<TextInput
scale
onChange={onChangeCount}
placeholder={t("EnterCount")}
value={value}
tabIndex={6}
/>
</ControlsGroup>
);
};

View File

@ -0,0 +1,143 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group";
import { ColorInput } from "@docspace/shared/components/color-input";
import { TextInput } from "@docspace/shared/components/text-input";
import { Label } from "@docspace/shared/components/label";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import {
CategorySubHeader,
ControlsGroup,
ControlsSection,
RowContainer,
} from "../presets/StyledPresets";
export const MainElementParameter = ({
t,
config,
setConfig,
isButtonMode = false,
}) => {
const elementDisplayOptions = [
{ value: "element", label: t("ElementItself") },
{
value: "button",
label: (
<RowContainer>
{t("Common:Button")}
<Text color="gray">{`(${t("ElementCalledAfterClicking")})`}</Text>
</RowContainer>
),
},
];
const [selectedElementType, setSelectedElementType] = useState(
elementDisplayOptions[Number(isButtonMode)].value,
);
const [buttonValue, setButtonValue] = useState(config.buttonText);
const debouncedSetConfig = useCallback(
debounce((key, value) => {
setConfig((config) => {
return { ...config, [key]: value };
});
}, 500),
[setConfig],
);
const toggleButtonMode = (e) => {
setSelectedElementType(e.target.value);
setConfig((config) => ({
...config,
isButtonMode: e.target.value === "button",
}));
};
const setButtonColor = (color) => {
debouncedSetConfig("buttonColor", color);
};
const setButtonText = (e) => {
setButtonValue(e.target.value);
debouncedSetConfig("buttonText", e.target.value);
};
const toggleWithLogo = () => {
setConfig((config) => ({
...config,
buttonWithLogo: !config.buttonWithLogo,
}));
};
return (
<ControlsSection>
<CategorySubHeader>{t("MainElementParameter")}</CategorySubHeader>
<RadioButtonGroup
orientation="vertical"
options={elementDisplayOptions}
name="elementDisplayInput"
selected={selectedElementType}
onClick={toggleButtonMode}
spacing="8px"
/>
{config.isButtonMode && (
<>
<CategorySubHeader>{t("ButtonCustomization")}</CategorySubHeader>
<ControlsGroup>
<Label className="label" text={t("ButtonColor")} />
<ColorInput
scale
handleChange={setButtonColor}
defaultColor={"#5299E0"}
/>
</ControlsGroup>
<ControlsGroup>
<Label className="label" text={t("ButtonText")} />
<TextInput
scale
onChange={setButtonText}
placeholder={t("SelectToDocSpace")}
value={buttonValue}
tabIndex={3}
/>
<Checkbox
className="checkbox"
label={t("Logo")}
onChange={toggleWithLogo}
isChecked={config.buttonWithLogo}
/>
</ControlsGroup>
</>
)}
</ControlsSection>
);
};

View File

@ -0,0 +1,46 @@
// (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 {
SDKContainer,
CategoryHeader,
CategoryDescription,
} from "../presets/StyledPresets";
export const PresetWrapper = (props) => {
const { children, description, header } = props;
return (
<SDKContainer>
<CategoryDescription>
<Text className="sdk-description">{description}</Text>
</CategoryDescription>
<CategoryHeader>{header}</CategoryHeader>
{children}
</SDKContainer>
);
};

View File

@ -0,0 +1,94 @@
// (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 } from "react";
import { objectToGetParams } from "@docspace/shared/utils/common";
import { TabsContainer } from "@docspace/shared/components/tabs-container";
import { CodeToInsert } from "./CodeToInsert";
import { GetCodeBlock } from "./GetCodeBlock";
import { Preview } from "../presets/StyledPresets";
import { showPreviewThreshold } from "../constants";
export const PreviewBlock = ({
t,
loadCurrentFrame,
preview,
theme,
frameId,
scriptUrl,
config,
isDisabled = false,
}) => {
const [showPreview, setShowPreview] = useState(
window.innerWidth > showPreviewThreshold,
);
const params = objectToGetParams(config);
const codeBlock = `<div id="${frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
const code = (
<CodeToInsert t={t} theme={theme} codeBlock={codeBlock} config={config} />
);
const dataTabs = [
{
key: "preview",
title: t("Common:Preview"),
content: preview,
},
{
key: "code",
title: t("Code"),
content: code,
},
];
const onResize = () => {
const isEnoughWidthForPreview = window.innerWidth > showPreviewThreshold;
if (isEnoughWidthForPreview !== showPreview)
setShowPreview(isEnoughWidthForPreview);
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, [showPreview]);
return showPreview ? (
<Preview>
<TabsContainer
onSelect={loadCurrentFrame}
elements={dataTabs}
isDisabled={isDisabled}
/>
</Preview>
) : (
<GetCodeBlock t={t} codeBlock={codeBlock} isDisabled={isDisabled} />
);
};

View File

@ -0,0 +1,81 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { Label } from "@docspace/shared/components/label";
import { TextInput } from "@docspace/shared/components/text-input";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { ColumnContainer } from "../presets/StyledPresets";
export const SearchTerm = ({ t, config, setConfig }) => {
const [value, setValue] = useState(config.filter.filterValue);
const debouncedSetConfig = useCallback(
debounce((value) => {
setConfig((config) => ({
...config,
filter: { ...config.filter, filterValue: value },
}));
}, 500),
[setConfig],
);
const onChangeSearch = (e) => {
setValue(e.target.value);
debouncedSetConfig(e.target.value);
};
const onChangeWithSubfolders = () => {
setConfig((config) => ({
...config,
withSubfolders: !config.withSubfolders,
}));
};
return (
<>
<Label className="label" text={t("SearchTerm")} />
<ColumnContainer>
<TextInput
scale
onChange={onChangeSearch}
placeholder={t("Common:Search")}
value={value}
tabIndex={5}
/>
<Checkbox
className="checkbox"
label={t("Files:WithSubfolders")}
onChange={onChangeWithSubfolders}
isChecked={config.withSubfolders}
/>
</ColumnContainer>
</>
);
};

View File

@ -0,0 +1,61 @@
// (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, useCallback } from "react";
import { Label } from "@docspace/shared/components/label";
import { TextInput } from "@docspace/shared/components/text-input";
import debounce from "lodash.debounce";
export const SelectTextInput = ({ t, config, setConfig }) => {
const [value, setValue] = useState(config.acceptButtonLabel);
const debouncedSetConfig = useCallback(
debounce((value) => {
setConfig((config) => {
return { ...config, acceptButtonLabel: value };
});
}, 500),
[setConfig],
);
const onChangeAcceptLabel = (e) => {
setValue(e.target.value);
debouncedSetConfig(e.target.value);
};
return (
<>
<Label className="label" text={t("SelectButtonText")} />
<TextInput
scale
onChange={onChangeAcceptLabel}
placeholder={t("Common:SelectAction")}
value={value}
tabIndex={7}
/>
</>
);
};

View File

@ -0,0 +1,73 @@
// (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 { Link } from "@docspace/shared/components/link";
import { Text } from "@docspace/shared/components/text";
export const SharedLinkHint = ({
t,
linkSettings,
redirectToSelectedRoom,
currentColorScheme,
}) => {
const settingsTranslations = {
password: t("Common:Password").toLowerCase(),
denyDownload: t("FileContentCopy").toLowerCase(),
expirationDate: t("LimitByTime").toLowerCase(),
};
return (
linkSettings.length > 0 && (
<div>
<Text className="linkHelp" fontSize="12px" lineHeight="16px">
{linkSettings.length === 2
? t("LinkSetDescription2", {
parameter1: settingsTranslations[linkSettings[0]],
parameter2: settingsTranslations[linkSettings[1]],
})
: linkSettings.length === 3
? t("LinkSetDescription3", {
parameter1: settingsTranslations[linkSettings[0]],
parameter2: settingsTranslations[linkSettings[1]],
parameter3: settingsTranslations[linkSettings[2]],
})
: t("LinkSetDescription", {
parameter: settingsTranslations[linkSettings[0]],
})}
</Text>
<Link
color={currentColorScheme?.main?.accent}
fontSize="12px"
lineHeight="16px"
onClick={redirectToSelectedRoom}
>
{" "}
{t("GoToRoom")}.
</Link>
</div>
)
);
};

View File

@ -0,0 +1,87 @@
// (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, useCallback } from "react";
import debounce from "lodash.debounce";
import { TextInput } from "@docspace/shared/components/text-input";
import { Label } from "@docspace/shared/components/label";
import { ComboBox } from "@docspace/shared/components/combobox";
import { ControlsGroup, RowContainer } from "../presets/StyledPresets";
export const WidthSetter = (props) => {
const { t, setConfig, dataDimensions, defaultDimension, defaultWidth } =
props;
const [widthDimension, setWidthDimension] = useState(defaultDimension);
const [width, setWidth] = useState(defaultWidth);
const debouncedSetConfig = useCallback(
debounce((value, dimension) => {
setConfig((config) => {
return { ...config, width: `${value}${dimension}` };
});
}, 500),
[setConfig],
);
const onChangeWidth = (e) => {
setWidth(e.target.value);
debouncedSetConfig(e.target.value, widthDimension.label);
};
const onChangeWidthDimension = (item) => {
setConfig((config) => {
return { ...config, width: `${width}${item.label}` };
});
setWidthDimension(item);
};
return (
<ControlsGroup>
<Label className="label" text={t("EmbeddingPanel:Width")} />
<RowContainer combo>
<TextInput
onChange={onChangeWidth}
placeholder={t("EnterWidth")}
value={width}
tabIndex={2}
/>
<ComboBox
size="content"
scaled={false}
scaledOptions={true}
onSelect={onChangeWidthDimension}
options={dataDimensions}
selectedOption={widthDimension}
displaySelectedOption
directionY="bottom"
/>
</RowContainer>
</ControlsGroup>
);
};

View File

@ -0,0 +1,41 @@
// (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 debounce from "lodash.debounce";
import { objectToGetParams, loadScript } from "@docspace/shared/utils/common";
export const loadFrame = debounce((config, scriptUrl) => {
const script = document.getElementById("integration");
if (script) {
script.remove();
}
const params = objectToGetParams(config);
loadScript(`${scriptUrl}${params}`, "integration", () =>
window.DocSpace.SDK.initFrame(config),
);
}, 500);

View File

@ -36,7 +36,6 @@ import TickSvgUrl from "PUBLIC_DIR/images/tick.svg?url";
const SessionsRow = (props) => {
const {
item,
standalone,
sectionWidth,
currentSession,
setPlatformModalData,
@ -88,19 +87,16 @@ const SessionsRow = (props) => {
ip={item.ip}
sectionWidth={sectionWidth}
showTickIcon={showTickIcon}
standalone={standalone}
/>
</Row>
);
};
export default inject(({ setup, settingsStore }) => {
const { standalone } = settingsStore;
export default inject(({ setup }) => {
const { currentSession, setLogoutDialogVisible, setPlatformModalData } =
setup;
return {
standalone,
currentSession,
setLogoutDialogVisible,
setPlatformModalData,

View File

@ -47,7 +47,6 @@ const StyledRowContent = styled(RowContent)`
const SessionsRowContent = ({
id,
standalone,
platform,
browser,
date,
@ -70,10 +69,11 @@ const SessionsRowContent = ({
<IconButton size={12} iconName={TickSvgUrl} color="#20D21F" />
)}
<Text truncate>{convertTime(date)}</Text>
{!standalone && (
{(country || city) && (
<Text truncate>
{country}
{` ${city}`}
{country && city && ", "}
{city}
</Text>
)}
<Text truncate containerWidth="160px">

View File

@ -82,7 +82,6 @@ const SessionsTableRow = (props) => {
const {
item,
hideColumns,
standalone,
currentSession,
setPlatformModalData,
setLogoutDialogVisible,
@ -125,15 +124,15 @@ const SessionsTableRow = (props) => {
<TableCell>
<Text className="session-info" truncate>
{!standalone ? (
{(country || city) && (
<>
{country}, {city}
{country}
{country && city && ", "}
{city}
<span className="divider"></span>
{ip}
</>
) : (
<>{ip}</>
)}
{ip}
</Text>
</TableCell>
@ -153,13 +152,11 @@ const SessionsTableRow = (props) => {
);
};
export default inject(({ setup, settingsStore }) => {
const { standalone } = settingsStore;
export default inject(({ setup }) => {
const { currentSession, setLogoutDialogVisible, setPlatformModalData } =
setup;
return {
standalone,
currentSession,
setLogoutDialogVisible,
setPlatformModalData,