diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index ab5da4d838..89167f14bb 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -10,6 +10,7 @@
"formulahendry.auto-complete-tag",
"formulahendry.auto-rename-tag",
"mrmlnc.vscode-duplicate",
- "ms-python.python"
+ "ms-python.python",
+ "wix.vscode-import-cost"
]
}
diff --git a/packages/client/src/Shell.jsx b/packages/client/src/Shell.jsx
index 9523d6901a..bbc0834a4a 100644
--- a/packages/client/src/Shell.jsx
+++ b/packages/client/src/Shell.jsx
@@ -88,6 +88,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
version,
pagesWithoutNavMenu,
isFrame,
+ barTypeInFrame,
} = rest;
const theme = useTheme();
@@ -457,7 +458,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
- {!isFrame && }
+ {barTypeInFrame !== "none" && }
@@ -565,6 +566,7 @@ const ShellWrapper = inject(
version,
pagesWithoutNavMenu,
isFrame,
+ barTypeInFrame: frameConfig?.showHeaderBanner,
};
},
)(observer(Shell));
diff --git a/packages/client/src/components/AccessSelector/index.tsx b/packages/client/src/components/AccessSelector/index.tsx
index f68d953ca8..127938ec6b 100644
--- a/packages/client/src/components/AccessSelector/index.tsx
+++ b/packages/client/src/components/AccessSelector/index.tsx
@@ -146,7 +146,7 @@ const AccessSelector: React.FC = ({
directionX="right"
directionY="top"
fixedDirection
- manualWidth="fit-content"
+ manualWidth="auto"
isDefaultMode
isAside={isMobileView}
setIsOpenItemAccess={setIsOpenItemAccess}
diff --git a/packages/client/src/components/MainBar/index.js b/packages/client/src/components/MainBar/index.js
index 1c264ce909..f7d4f03337 100644
--- a/packages/client/src/components/MainBar/index.js
+++ b/packages/client/src/components/MainBar/index.js
@@ -63,7 +63,7 @@ const MainBar = ({
snackbarExist,
setMaintenanceExist,
isNotPaidPeriod,
- isFrame,
+ barTypeInFrame,
}) => {
const { pathname } = useLocation();
@@ -72,7 +72,7 @@ const MainBar = ({
}, []);
const isVisibleBar =
- !isFrame &&
+ barTypeInFrame !== "none" &&
!isNotPaidPeriod &&
!pathname.includes("error") &&
!pathname.includes("confirm") &&
@@ -95,7 +95,7 @@ export default inject(
filesStore,
currentTariffStatusStore,
}) => {
- const { checkedMaintenance, setMaintenanceExist, snackbarExist, isFrame } =
+ const { checkedMaintenance, setMaintenanceExist, snackbarExist, frameConfig } =
settingsStore;
const { isNotPaidPeriod } = currentTariffStatusStore;
const { firstLoad } = clientLoadingStore;
@@ -107,7 +107,7 @@ export default inject(
snackbarExist,
setMaintenanceExist,
isNotPaidPeriod,
- isFrame,
+ barTypeInFrame: frameConfig?.showHeaderBanner
};
},
)(observer(MainBar));
diff --git a/packages/client/src/components/QuotaForm/index.js b/packages/client/src/components/QuotaForm/index.js
index 1305ef9e62..b34856cce8 100644
--- a/packages/client/src/components/QuotaForm/index.js
+++ b/packages/client/src/components/QuotaForm/index.js
@@ -218,7 +218,7 @@ const QuotaForm = ({
size="content"
onSelect={onSelectComboBox}
showDisabledItems
- manualWidth={"fit-content"}
+ manualWidth="auto"
directionY="both"
/>
diff --git a/packages/client/src/components/SpaceQuota/index.js b/packages/client/src/components/SpaceQuota/index.js
index 182b955112..34a6cd2663 100644
--- a/packages/client/src/components/SpaceQuota/index.js
+++ b/packages/client/src/components/SpaceQuota/index.js
@@ -196,7 +196,7 @@ const SpaceQuota = (props) => {
size="content"
modernView
isLoading={isLoading}
- manualWidth="fit-content"
+ manualWidth="auto"
directionY="both"
/>
diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js
index 41f5e19848..96c6867649 100644
--- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js
+++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js
@@ -239,7 +239,7 @@ const ThirdPartyComboBox = ({
scaled
withBackdrop={isMobile}
size="content"
- manualWidth={"fit-content"}
+ manualWidth={"auto"}
isMobileView={isMobileOnly}
directionY="both"
displaySelectedOption
diff --git a/packages/client/src/components/dialogs/DataReassignmentDialog/sub-components/Body/AccountInfo.js b/packages/client/src/components/dialogs/DataReassignmentDialog/sub-components/Body/AccountInfo.js
index 132b9aa0f8..be18dd934e 100644
--- a/packages/client/src/components/dialogs/DataReassignmentDialog/sub-components/Body/AccountInfo.js
+++ b/packages/client/src/components/dialogs/DataReassignmentDialog/sub-components/Body/AccountInfo.js
@@ -31,7 +31,7 @@ import { Avatar } from "@docspace/shared/components/avatar";
import CatalogSpamIcon from "PUBLIC_DIR/images/catalog.spam.react.svg";
import { commonIconsStyles } from "@docspace/shared/utils";
-import { capitalize } from "lodash";
+import capitalize from "lodash/capitalize";
const StyledCatalogSpamIcon = styled(CatalogSpamIcon)`
${commonIconsStyles}
diff --git a/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx b/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx
index 7925f15b08..52304481fe 100644
--- a/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx
+++ b/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx
@@ -174,7 +174,7 @@ const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => {
size="content"
modernView
title={t("Common:Role")}
- manualWidth={"fit-content"}
+ manualWidth="auto"
isMobileView={isMobileOnly}
directionY="both"
displaySelectedOption
diff --git a/packages/client/src/helpers/people-helpers.js b/packages/client/src/helpers/people-helpers.js
index 8e0534d72d..cf71235b6d 100644
--- a/packages/client/src/helpers/people-helpers.js
+++ b/packages/client/src/helpers/people-helpers.js
@@ -27,7 +27,8 @@
import React from "react";
import { Trans } from "react-i18next";
import MailReactSvgUrl from "PUBLIC_DIR/images/mail.react.svg?url";
-import { find, cloneDeep } from "lodash";
+import cloneDeep from "lodash/cloneDeep";
+import find from "lodash/find";
import {
EmployeeActivationStatus,
EmployeeStatus,
diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Accounts/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Accounts/index.js
index 9988810e25..48e7058160 100644
--- a/packages/client/src/pages/Home/InfoPanel/Body/views/Accounts/index.js
+++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Accounts/index.js
@@ -176,7 +176,7 @@ const Accounts = (props) => {
size="content"
displaySelectedOption
modernView
- manualWidth={"fit-content"}
+ manualWidth="auto"
isLoading={isLoading}
/>
);
diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js
index d54dcc0ea3..5ae7ecbc74 100644
--- a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js
+++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js
@@ -378,7 +378,7 @@ const User = ({
size="content"
modernView
title={t("Common:Role")}
- manualWidth={"fit-content"}
+ manualWidth="auto"
isLoading={isLoading}
isMobileView={isMobileOnly}
directionY="both"
diff --git a/packages/client/src/pages/Home/Section/AccountsBody/InsideGroup/TableView/TableRow.js b/packages/client/src/pages/Home/Section/AccountsBody/InsideGroup/TableView/TableRow.js
index bc198c6201..9c4ca6f5aa 100644
--- a/packages/client/src/pages/Home/Section/AccountsBody/InsideGroup/TableView/TableRow.js
+++ b/packages/client/src/pages/Home/Section/AccountsBody/InsideGroup/TableView/TableRow.js
@@ -399,7 +399,7 @@ const InsideGroupTableRow = (props) => {
directionY="both"
size="content"
modernView
- manualWidth={"fit-content"}
+ manualWidth="auto"
isLoading={isLoading}
optionStyle={{ maxWidth: "400px" }}
textOverflow
@@ -442,7 +442,7 @@ const InsideGroupTableRow = (props) => {
size="content"
displaySelectedOption
modernView
- manualWidth={"fit-content"}
+ manualWidth="auto"
isLoading={isLoading}
/>
);
diff --git a/packages/client/src/pages/Home/Section/AccountsBody/People/TableView/TableRow.js b/packages/client/src/pages/Home/Section/AccountsBody/People/TableView/TableRow.js
index 45c74f06fc..7352bb5612 100644
--- a/packages/client/src/pages/Home/Section/AccountsBody/People/TableView/TableRow.js
+++ b/packages/client/src/pages/Home/Section/AccountsBody/People/TableView/TableRow.js
@@ -438,7 +438,7 @@ const PeopleTableRow = (props) => {
size="content"
displaySelectedOption
modernView
- manualWidth={"fit-content"}
+ manualWidth={"auto"}
isLoading={isLoading}
/>
);
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/RowView/UsersTypeRowContent.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/RowView/UsersTypeRowContent.js
index 49978069f3..bec9750871 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/RowView/UsersTypeRowContent.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/RowView/UsersTypeRowContent.js
@@ -131,7 +131,7 @@ const UsersRowContent = ({
size="content"
displaySelectedOption
modernView
- manualWidth="fit-content"
+ manualWidth="auto"
/>
,
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
index 9cfb47cc25..4c59bdece7 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
@@ -126,7 +126,7 @@ const UsersTypeTableRow = ({
size="content"
displaySelectedOption
modernView
- manualWidth="fit-content"
+ manualWidth="auto"
/>
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js
index b84e8ce76a..e644d45ba3 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js
@@ -219,7 +219,7 @@ const GoogleWorkspace = ({
return clearCheckedAccounts;
}, []);
- if (isMobile || isMobileBreakpoint())
+ if (isMobileBreakpoint())
return (
,
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTableRow.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTableRow.js
index 9cfb47cc25..4c59bdece7 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTableRow.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTableRow.js
@@ -126,7 +126,7 @@ const UsersTypeTableRow = ({
size="content"
displaySelectedOption
modernView
- manualWidth="fit-content"
+ manualWidth="auto"
/>
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js
index da1a8f2a9f..ddde6ae9e1 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/index.js
@@ -133,7 +133,7 @@ const NextcloudWorkspace = (props) => {
return clearCheckedAccounts;
}, []);
- if (isMobile || isMobileBreakpoint())
+ if (isMobileBreakpoint())
return (
,
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
index 7382d83618..417e46d932 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/UsersTypeTableRow.js
@@ -126,7 +126,7 @@ const UsersTypeTableRow = ({
size="content"
displaySelectedOption
modernView
- manualWidth="fit-content"
+ manualWidth="auto"
/>
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js
index e56e709566..732dd33386 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/index.js
@@ -216,7 +216,7 @@ const OnlyofficeWorkspace = ({
return clearCheckedAccounts;
}, []);
- if (isMobile || isMobileBreakpoint()) {
+ if (isMobileBreakpoint()) {
return (
props.theme.dropDown.border};
border-radius: ${(props) => props.theme.dropDown.borderRadius};
-moz-border-radius: ${(props) => props.theme.dropDown.borderRadius};
- -webkit-border-radius: ${(props) => props.theme.dropDown.borderRadius};dropDownMaxHeight
+ -webkit-border-radius: ${(props) => props.theme.dropDown.borderRadius};
box-shadow: ${(props) => props.theme.dropDown.boxShadow};
-moz-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
-webkit-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
diff --git a/packages/shared/components/link-with-dropdown/LinkWithDropdown.styled.tsx b/packages/shared/components/link-with-dropdown/LinkWithDropdown.styled.tsx
index 186802cb30..adeaf4380f 100644
--- a/packages/shared/components/link-with-dropdown/LinkWithDropdown.styled.tsx
+++ b/packages/shared/components/link-with-dropdown/LinkWithDropdown.styled.tsx
@@ -24,7 +24,6 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
-import React from "react";
import styled, { css } from "styled-components";
import ExpanderDownReactSvg from "PUBLIC_DIR/images/expander-down.react.svg";
@@ -32,7 +31,6 @@ import { Base } from "../../themes";
import { Text } from "../text";
import { TextProps } from "../text/Text.types";
-// import { transform } from "lodash";
import {
SimpleLinkWithDropdownProps,
TDropdownType,
diff --git a/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx b/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx
index 388e668fae..1bbd458427 100644
--- a/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx
+++ b/packages/shared/components/media-viewer/sub-components/ImageViewer/index.tsx
@@ -988,7 +988,7 @@ export const ImageViewer = ({
window.ClientConfig?.imageThumbnails &&
thumbnailSrc &&
!showOriginSrc
- ? `${thumbnailSrc}&size=3840x2160`
+ ? `${thumbnailSrc}&size=3840x2160&view=true`
: src
}
ref={imgRef}
diff --git a/packages/shared/components/media-viewer/sub-components/ViewerPlayer/index.tsx b/packages/shared/components/media-viewer/sub-components/ViewerPlayer/index.tsx
index 7fc8eb919f..e908d44628 100644
--- a/packages/shared/components/media-viewer/sub-components/ViewerPlayer/index.tsx
+++ b/packages/shared/components/media-viewer/sub-components/ViewerPlayer/index.tsx
@@ -24,7 +24,7 @@
// 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 lodash from "lodash";
+import omit from "lodash/omit";
import { useGesture } from "@use-gesture/react";
import { useSpring, animated } from "@react-spring/web";
import {
@@ -640,7 +640,7 @@ export const ViewerPlayer = ({
ref={videoRef}
hidden={isAudio}
preload="metadata"
- style={lodash.omit(style, ["x", "y"])}
+ style={omit(style, ["x", "y"])}
src={thumbnailSrc ? src : `${src}#t=0.001`}
poster={posterUrl}
onError={hadleError}
diff --git a/packages/shared/components/selector/sub-components/AccessSelector.tsx b/packages/shared/components/selector/sub-components/AccessSelector.tsx
index a7dd834da5..e501090f6e 100644
--- a/packages/shared/components/selector/sub-components/AccessSelector.tsx
+++ b/packages/shared/components/selector/sub-components/AccessSelector.tsx
@@ -63,7 +63,7 @@ const AccessSelector = (props: AccessSelectorProps) => {
options={accessRights as TOption[]}
size={ComboBoxSize.content}
scaled={false}
- manualWidth="fit-content"
+ manualWidth="auto"
selectedOption={selectedAccessRight as TOption}
showDisabledItems
directionX="right"
@@ -81,7 +81,7 @@ const AccessSelector = (props: AccessSelectorProps) => {
directionX="right"
directionY="top"
fixedDirection={isMobileView}
- manualWidth={isMobileView ? "fit-content" : `${width}px`}
+ manualWidth={isMobileView ? "auto" : `${width}px`}
isAside={isMobileView}
manualY={isMobileView ? "0px" : undefined}
withoutBackground={isMobileView}
diff --git a/packages/shared/components/share/sub-components/LinkRow.tsx b/packages/shared/components/share/sub-components/LinkRow.tsx
index bf05ee7c76..a5e1cc4964 100644
--- a/packages/shared/components/share/sub-components/LinkRow.tsx
+++ b/packages/shared/components/share/sub-components/LinkRow.tsx
@@ -153,7 +153,7 @@ const LinkRow = ({
modernView
type="onlyIcon"
isDisabled={isExpiredLink || isLoaded}
- manualWidth="fit-content"
+ manualWidth="auto"
withBackdrop={false}
/>
diff --git a/packages/shared/constants/index.ts b/packages/shared/constants/index.ts
index 568f8437bf..bf45a089ea 100644
--- a/packages/shared/constants/index.ts
+++ b/packages/shared/constants/index.ts
@@ -171,7 +171,8 @@ export const HTML_EXST = [".htm", ".mht", ".html"];
export const SYSTEM_THEME_KEY = "system_theme";
-const SDK_VERSION = "1.0.0";
+const SDK_VERSION = "1.0.1";
+
export const SDK_SCRIPT_URL =
typeof window !== "undefined"
? `${window.location.origin}/static/scripts/sdk/${SDK_VERSION}/api.js`
diff --git a/public/scripts/sdk/1.0.1/api.js b/public/scripts/sdk/1.0.1/api.js
new file mode 100644
index 0000000000..ae265191e0
--- /dev/null
+++ b/public/scripts/sdk/1.0.1/api.js
@@ -0,0 +1,1353 @@
+// (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
+
+(function () {
+ const FRAME_NAME = "frameDocSpace";
+
+ const defaultConfig = {
+ src: new URL(document.currentScript.src).origin,
+ rootPath: "/rooms/shared/",
+ requestToken: null,
+ width: "100%",
+ height: "100%",
+ name: FRAME_NAME,
+ type: "desktop", // TODO: ["desktop", "mobile"]
+ frameId: "ds-frame",
+ mode: "manager", //TODO: ["manager", "editor", "viewer","room-selector", "file-selector", "system"]
+ id: null,
+ locale: null,
+ theme: "System",
+ editorType: "desktop", //TODO: ["desktop", "embedded"]
+ editorGoBack: true,
+ selectorType: "exceptPrivacyTrashArchiveFolders", //TODO: ["roomsOnly", "userFolderOnly", "exceptPrivacyTrashArchiveFolders", "exceptSortedByTagsFolders"]
+ showSelectorCancel: false,
+ showSelectorHeader: false,
+ showHeader: false,
+ showHeaderBanner: "none", //TODO: ["none", "info", "all"]
+ showTitle: true,
+ showMenu: false,
+ showFilter: false,
+ showSignOut: true,
+ destroyText: "",
+ viewAs: "row", //TODO: ["row", "table", "tile"]
+ viewTableColumns: "Name,Type,Tags",
+ checkCSP: true,
+ disableActionButton: false,
+ showSettings: false,
+ waiting: false,
+ withSearch: true,
+ withBreadCrumbs: true,
+ withSubtitle: true,
+ filterParam: "ALL",
+ buttonColor: "#5299E0",
+ infoPanelVisible: true,
+ downloadToEvent: false,
+ filter: {
+ // filterType: 0,
+ // type: 0,
+ count: 100,
+ page: 1,
+ sortorder: "descending", //TODO: ["descending", "ascending"]
+ sortby: "DateAndTime", //TODO: ["DateAndTime", "AZ", "Type", "Size", "DateAndTimeCreation", "Author"]
+ search: "",
+ withSubfolders: false,
+ },
+ editorCustomization: {},
+ keysForReload: [
+ "src",
+ "rootPath",
+ "width",
+ "height",
+ "name",
+ "frameId",
+ "id",
+ "type",
+ "editorType",
+ "mode",
+ ],
+ events: {
+ onSelectCallback: null,
+ onCloseCallback: null,
+ onAppReady: null,
+ onAppError: (e) => console.log("onAppError", e),
+ onEditorCloseCallback: null,
+ onAuthSuccess: null,
+ onSignOut: null,
+ onDownload: null,
+ },
+ };
+
+ const lt = //g;
+ const rgt = "&rt;";
+
+ const cspErrorText =
+ "The current domain is not set in the Content Security Policy (CSP) settings.";
+
+ const validateCSP = async (targetSrc) => {
+ let currentSrc = window.location.origin;
+
+ if (currentSrc.indexOf(targetSrc) !== -1) return; // skip check for the same domain
+
+ const response = await fetch(`${targetSrc}/api/2.0/security/csp`);
+ const res = await response.json();
+
+ currentSrc = window.location.host || new URL(window.location.origin).host; // more flexible way to check
+
+ const domains = [...res.response.domains].map((d) => {
+ try {
+ const domain = new URL(d.toLowerCase());
+ const domainFull =
+ domain.host + (domain.pathname !== "/" ? domain.pathname : "");
+
+ return domainFull;
+ } catch {
+ return d;
+ }
+ });
+
+ const passed = domains.includes(currentSrc.toLowerCase());
+
+ if (!passed) throw new Error(cspErrorText);
+
+ return;
+ };
+
+ const getConfigFromParams = () => {
+ const src = decodeURIComponent(document.currentScript.src);
+
+ if (!src || !src.length) return null;
+
+ const searchUrl = src.split("?")[1];
+ let object = {};
+
+ if (searchUrl && searchUrl.length) {
+ object = JSON.parse(
+ `{"${searchUrl.replace(/&/g, '","').replace(/=/g, '":"')}"}`,
+ (k, v) => (v === "true" ? true : v === "false" ? false : v)
+ );
+
+ object.filter = defaultConfig.filter;
+
+ for (prop in object) {
+ if (prop in defaultConfig.filter) {
+ object.filter[prop] = object[prop];
+ delete object[prop];
+ }
+ }
+ }
+
+ return { ...defaultConfig, ...object };
+ };
+
+ /**
+ * Represents the DocSpace class.
+ * @class
+ */
+ class DocSpace {
+ #isConnected = false;
+ #frameOpacity = 0;
+ #callbacks = [];
+ #tasks = [];
+ #classNames = "";
+
+ constructor(config) {
+ this.config = config;
+ }
+
+ /**
+ * Checks if any of the keys in the given array exist in the provided object.
+ *
+ * @param {Array} array - The array of keys to check.
+ * @param {Object} object - The object to check against.
+ * @returns {boolean} - Returns true if any of the keys exist in the object, otherwise false.
+ */
+ #oneOfExistInObject = (array, object) => {
+ return Object.keys(object).some((k) => array.includes(k));
+ };
+
+ /**
+ * Creates a loader element with the specified configuration.
+ *
+ * @param {Object} config - The configuration object for the loader.
+ * @param {string} config.width - The width of the loader container.
+ * @param {string} config.height - The height of the loader container.
+ * @param {string} config.src - The source path for the loader image.
+ * @param {string} config.theme - The theme of the loader (e.g., "Dark", "System").
+ * @param {string} config.frameId - The ID of the loader frame.
+ * @returns {HTMLElement} The loader container element.
+ */
+ #createLoader = (config) => {
+ const container = document.createElement("div");
+ container.style.width = config.width;
+ container.style.height = config.height;
+ container.style.display = "flex";
+ container.style.justifyContent = "center";
+ container.style.alignItems = "center";
+
+ // const loader = document.createElement("img");
+ // loader.setAttribute("src", `${config.src}/static/images/loader.svg`);
+ // loader.setAttribute("width", `64px`);
+ // loader.setAttribute("height", `64px`);
+
+ // if (
+ // config.theme === "Dark" ||
+ // (config.theme === "System" &&
+ // window.matchMedia("(prefers-color-scheme: dark)"))
+ // ) {
+ // container.style.backgroundColor = "#333333";
+ // loader.style.filter =
+ // "invert(100%) sepia(100%) saturate(0%) hue-rotate(288deg) brightness(102%) contrast(102%)";
+ // }
+
+ const loader = document.createElement("div");
+ const loaderClass = `${config.frameId}-loader__element`;
+ loader.setAttribute("class", loaderClass);
+
+ container.appendChild(loader);
+
+ const style = document.createElement("style");
+ style.innerHTML = `
+ @keyframes rotate {
+ 0%{
+ transform: rotate(-45deg);
+ }
+ 15%{
+ transform: rotate(45deg);
+ }
+ 30%{
+ transform: rotate(135deg);
+ }
+ 45%{
+ transform: rotate(225deg);
+ }
+ 60%, 100%{
+ transform: rotate(315deg);
+ }
+ }
+
+ .${loaderClass} {
+ width: 74px;
+ height: 74px;
+
+ border: 4px solid rgba(51,51,51, 0.1);
+ border-top-color: #333333;
+ border-radius: 50%;
+
+ transform: rotate(-45deg);
+
+ position: relative;
+
+ box-sizing: border-box;
+
+ animation: 1s linear infinite rotate;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .${loaderClass} {
+ border-color: rgba(204, 204, 204, 0.1);
+ border-top-color: #CCCCCC;
+ }
+ }
+ `;
+
+ container.appendChild(style);
+
+ container.setAttribute("id", config.frameId + "-loader");
+
+ return container;
+ };
+
+ /**
+ * Creates a button view based on the provided configuration.
+ *
+ * @param {Object} config - The configuration object for the button view.
+ * @param {string} config.buttonColor - The background color of the button. Defaults to "#5299E0".
+ * @param {boolean} config.buttonWithLogo - Determines whether the button should include a logo. Defaults to false.
+ * @param {string} config.buttonText - The text to display on the button. Defaults to "Select to DocSpace".
+ * @param {string} config.src - The source URL for the logo image.
+ * @param {string} config.frameId - The ID of the container element for the button.
+ * @param {Object} config.events - The event callbacks for the button.
+ * @param {Function} config.events.onSelectCallback - The callback function to be executed when an item is selected.
+ * @param {Function} config.events.onCloseCallback - The callback function to be executed when the button view is closed.
+ * @param {Function} config.events.onAppReady - The callback function to be executed when the DocSpace app is ready.
+ * @param {Function} config.events.onAppError - The callback function to be executed when an error occurs in the DocSpace app.
+ * @param {Function} config.events.onEditorCloseCallback - The callback function to be executed when the editor is closed.
+ * @param {Function} config.events.onAuthSuccess - The callback function to be executed when authentication is successful.
+ * @param {Function} config.events.onSignOut - The callback function to be executed when the user signs out.
+ * @returns {HTMLButtonElement} The created button element.
+ */
+ #createButtonView = (config) => {
+ const button = document.createElement("button");
+ button.style.backgroundColor = config?.buttonColor || "#5299E0";
+ button.style.color = "#fff";
+ button.style.padding = "0 28px";
+ button.style.borderRadius = "3px";
+ button.style.border = `1px solid #5299E0`;
+ button.style.height = "32px";
+ button.style.fontWeight = "600";
+ button.style.fontFamily = "Open Sans";
+ button.style.cursor = "pointer";
+ button.style.display = "flex";
+ button.style.alignItems = "center";
+ button.style.gap = "10px";
+ button.style.userSelect = "none";
+ button.style.borderColor = config?.buttonColor || "#5299E0";
+
+ const logoSrc = `${config.src}/static/images/light_small_logo.react.svg`;
+
+ button.innerHTML = `${config?.buttonWithLogo ? `` : ""}${config?.buttonText || "Select to DocSpace"}`;
+ const url = new URL(document.currentScript.src);
+ const scriptUrl = `${url.origin}${url.pathname}`;
+
+ const configStringify = JSON.stringify(config, function (key, val) {
+ return typeof val === "function" ? "" + val : val;
+ })
+ .replace(lt, rlt)
+ .replace(gt, rgt);
+
+ const windowHeight = 778,
+ windowWidth = 610;
+
+ button.addEventListener("click", () => {
+ const winHtml = `
+
+
+
+ DocSpace
+
+
+
+
+
+
+
+ `;
+
+ const winUrl = URL.createObjectURL(
+ new Blob([winHtml], { type: "text/html" })
+ );
+
+ window.open(
+ winUrl,
+ "_blank",
+ `width=${windowWidth},height=${windowHeight}`
+ );
+ });
+
+ button.setAttribute("id", config.frameId + "-container");
+
+ return button;
+ };
+
+ /**
+ * Creates an iframe element based on the provided configuration.
+ *
+ * @param {Object} config - The configuration object for creating the iframe.
+ * @param {string} config.mode - The mode of the iframe.
+ * @param {Object} config.filter - The filter object for the iframe.
+ * @param {string} config.id - The ID of the iframe.
+ * @param {string} config.requestToken - The request token for the iframe.
+ * @param {boolean} config.withSubfolders - Indicates whether to include subfolders in the iframe.
+ * @param {string} config.rootPath - The root path for the iframe.
+ * @param {string} config.editorGoBack - The go back option for the editor iframe.
+ * @param {Object} config.editorCustomization - The customization object for the editor iframe.
+ * @param {string} config.theme - The theme for the editor iframe.
+ * @param {Function} config.events.onEditorCloseCallback - The callback function for the editor close event.
+ * @param {string} config.editorType - The type of the editor iframe.
+ * @param {string} config.action - The action for the viewer iframe.
+ * @param {string} config.src - The source URL for the iframe.
+ * @param {string} config.width - The width of the iframe.
+ * @param {string} config.height - The height of the iframe.
+ * @param {string} config.name - The name of the iframe.
+ * @param {string} config.frameId - The ID of the iframe.
+ * @param {string} config.type - The type of the iframe.
+ * @param {boolean} config.checkCSP - Indicates whether to check the Content Security Policy.
+ * @returns {HTMLIFrameElement} The created iframe element.
+ */
+ #createIframe = (config) => {
+ const iframe = document.createElement("iframe");
+
+ let path = "";
+
+ switch (config.mode) {
+ case "manager": {
+ if (config.filter) {
+ if (config.id) config.filter.folder = config.id;
+
+ const params = config.requestToken
+ ? { key: config.requestToken, ...config.filter }
+ : config.filter;
+
+ if (!params.withSubfolders) {
+ delete params.withSubfolders;
+ }
+
+ const urlParams = new URLSearchParams(params).toString();
+
+ path = `${config.rootPath}${
+ config.requestToken
+ ? `?${urlParams}`
+ : `${config.id ? config.id + "/" : ""}filter?${urlParams}`
+ }`;
+ }
+ break;
+ }
+
+ case "room-selector": {
+ path = `/sdk/room-selector`;
+ break;
+ }
+
+ case "file-selector": {
+ path = `/sdk/file-selector?selectorType=${config.selectorType}`;
+ break;
+ }
+
+ case "system": {
+ path = `/sdk/system`;
+ break;
+ }
+
+ case "editor": {
+ let goBack = config.editorGoBack;
+ config.editorCustomization.uiTheme = config.theme;
+
+ if (!config.id || config.id === "undefined" || config.id === "null") {
+ config.id = -1; //editor default wrong file id error
+ }
+
+ const customization = JSON.stringify(config.editorCustomization);
+
+ if (
+ config.events.onEditorCloseCallback &&
+ typeof config.events.onEditorCloseCallback === "function"
+ ) {
+ goBack = "event";
+ }
+
+ path = `/doceditor/?fileId=${config.id}&editorType=${config.editorType}&editorGoBack=${goBack}&customization=${customization}`;
+
+ if (config.requestToken) {
+ path = `${path}&share=${config.requestToken}`;
+ }
+
+ break;
+ }
+
+ case "viewer": {
+ let goBack = config.editorGoBack;
+ config.editorCustomization.uiTheme = config.theme;
+
+ if (!config.id || config.id === "undefined" || config.id === "null") {
+ config.id = -1; //editor default wrong file id error
+ }
+
+ const customization = JSON.stringify(config.editorCustomization);
+
+ if (
+ config.events.onEditorCloseCallback &&
+ typeof config.events.onEditorCloseCallback === "function"
+ ) {
+ goBack = "event";
+ }
+
+ path = `/doceditor/?fileId=${config.id}&editorType=${config.editorType}&action=view&editorGoBack=${goBack}&customization=${customization}`;
+
+ if (config.requestToken) {
+ path = `${path}&share=${config.requestToken}`;
+ }
+
+ break;
+ }
+
+ default:
+ path = config.rootPath;
+ }
+
+ iframe.src = config.src + path;
+ iframe.style.width = config.width;
+ iframe.style.height = config.height;
+ iframe.name = `${FRAME_NAME}__#${config.frameId}`;
+ iframe.id = config.frameId;
+
+ iframe.frameBorder = 0;
+ iframe.allowFullscreen = true;
+ iframe.setAttribute("allow", "storage-access *");
+
+ if (config.type == "mobile") {
+ iframe.style.position = "fixed";
+ iframe.style.overflow = "hidden";
+ document.body.style.overscrollBehaviorY = "contain";
+ }
+
+ if (this.config.checkCSP) {
+ validateCSP(this.config.src).catch((e) => {
+ const html = `
+
+
+
+
+
+
+
+
+ `;
+ iframe.srcdoc = html;
+ e.message && config.events.onAppError(e.message);
+
+ this.setIsLoaded();
+ });
+ }
+
+ return iframe;
+ };
+
+ /**
+ * Sends a message to the specified frame.
+ * @param {any} message - The message to be sent.
+ */
+ #sendMessage = (message) => {
+ let mes = {
+ frameId: this.config.frameId,
+ type: "",
+ data: message,
+ };
+
+ const targetFrame = document.getElementById(this.config.frameId);
+
+ if (targetFrame && !!targetFrame.contentWindow) {
+ targetFrame.contentWindow.postMessage(
+ JSON.stringify(mes, (key, value) =>
+ typeof value === "function" ? value.toString() : value
+ ),
+ this.config.src
+ );
+ }
+ };
+
+ /**
+ * Handles incoming messages from the server.
+ *
+ * @param {MessageEvent} e - The message event object.
+ */
+ #onMessage = (e) => {
+ if (typeof e.data == "string") {
+ let data = {};
+
+ try {
+ data = JSON.parse(e.data);
+ } catch (err) {
+ data = {};
+ }
+
+ if (this.config.frameId !== data.frameId) {
+ return;
+ }
+
+ switch (data.type) {
+ case "onMethodReturn": {
+ if (this.#callbacks.length > 0) {
+ const callback = this.#callbacks.shift();
+ callback && callback(data.methodReturnData);
+ }
+
+ if (this.#tasks.length > 0) {
+ this.#sendMessage(this.#tasks.shift());
+ }
+ break;
+ }
+ case "onEventReturn": {
+ if (Object.keys(this.config).length === 0) return;
+ if (
+ data?.eventReturnData?.event in this.config.events &&
+ typeof this.config.events[data?.eventReturnData.event] ===
+ "function"
+ ) {
+ this.config.events[data?.eventReturnData.event](
+ data?.eventReturnData?.data
+ );
+ }
+ break;
+ }
+ case "onCallCommand": {
+ this[data.commandName].call(this, data.commandData);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ };
+
+ /**
+ * Executes a method on the message bus.
+ *
+ * @param {string} methodName - The name of the method to execute.
+ * @param {any} params - The parameters to pass to the method.
+ * @param {Function} callback - The callback function to be called after the method execution.
+ * @returns {void}
+ */
+ #executeMethod = (methodName, params, callback) => {
+ if (!this.#isConnected) {
+ this.config.events.onAppError(
+ "Message bus is not connected with frame"
+ );
+ return;
+ }
+
+ this.#callbacks.push(callback);
+
+ const message = {
+ type: "method",
+ methodName,
+ data: params,
+ };
+
+ if (this.#callbacks.length !== 1) {
+ this.#tasks.push(message);
+ return;
+ }
+
+ this.#sendMessage(message);
+ };
+
+ /**
+ * Initializes the button with the provided configuration.
+ *
+ * @param {Object} config - The configuration object for the button.
+ * @returns {HTMLElement} - The initialized button element.
+ */
+ initButton(config) {
+ const configFull = { ...defaultConfig, ...config };
+ this.config = {
+ ...this.config,
+ ...configFull,
+ events: { ...defaultConfig.events },
+ };
+
+ const target = document.getElementById(this.config.frameId);
+
+ let button = null;
+
+ if (target) {
+ button = this.#createButtonView(this.config);
+
+ this.#classNames = target.className;
+
+ const isSelfReplace = target.parentNode.isEqualNode(
+ document.getElementById(this.config.frameId + "-container")
+ );
+
+ target && isSelfReplace
+ ? target.parentNode.replaceWith(button)
+ : target.replaceWith(button);
+
+ window.addEventListener("message", this.#onMessage, false);
+
+ this.#isConnected = true;
+ }
+
+ window.DocSpace.SDK.frames = window.DocSpace.SDK.frames || [];
+
+ window.DocSpace.SDK.frames[this.config.frameId] = this;
+
+ return button;
+ }
+
+ /**
+ * Initializes the frame with the provided configuration.
+ *
+ * @param {Object} config - The configuration object for the frame.
+ * @returns {HTMLIFrameElement} - The created iframe element.
+ */
+ initFrame(config) {
+ const configFull = { ...defaultConfig, ...config };
+ Object.entries(configFull).map(([key, value]) => {
+ if (typeof value === "string")
+ configFull[key] = value.replaceAll(rlt, "<").replaceAll(rgt, ">");
+ });
+ this.config = { ...this.config, ...configFull };
+
+ const target = document.getElementById(this.config.frameId);
+
+ let iframe = null;
+
+ if (target) {
+ iframe = this.#createIframe(this.config);
+
+ iframe.style.opacity = this.#frameOpacity;
+ iframe.style.zIndex = 2;
+ iframe.style.position = "absolute";
+ iframe.style.width = "100%";
+ iframe.style.height = "100%";
+ iframe.style.top = 0;
+ iframe.style.left = 0;
+
+ const frameLoader = this.#createLoader(this.config);
+
+ this.#classNames = target.className;
+
+ const renderContainer = document.createElement("div");
+ renderContainer.id = this.config.frameId + "-container";
+ renderContainer.classList = ["frame-container"];
+ renderContainer.style.position = "relative";
+ renderContainer.style.width = "100%";
+ renderContainer.style.height = "100%";
+
+ if (!this.config.waiting || this.config.mode === "system") {
+ renderContainer.appendChild(iframe);
+ }
+
+ renderContainer.appendChild(frameLoader);
+
+ const isSelfReplace = target.parentNode.isEqualNode(
+ document.getElementById(this.config.frameId + "-container")
+ );
+
+ target && isSelfReplace
+ ? target.parentNode.replaceWith(renderContainer)
+ : target.replaceWith(renderContainer);
+
+ window.addEventListener("message", this.#onMessage, false);
+
+ this.#isConnected = true;
+ }
+
+ window.DocSpace.SDK.frames = window.DocSpace.SDK.frames || {};
+
+ window.DocSpace.SDK.frames[this.config.frameId] = this;
+
+ return iframe;
+ }
+
+ /**
+ * Initializes the manager mode.
+ * @param {Object} config - The configuration object.
+ * @returns {Promise} A promise that resolves when the frame is initialized.
+ */
+ initManager(config = {}) {
+ config.mode = "manager";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Sets the loaded state of the target frame and removes the loader element.
+ */
+ setIsLoaded() {
+ const targetFrame = document.getElementById(this.config.frameId);
+ const loader = document.getElementById(this.config.frameId + "-loader");
+
+ if (targetFrame) {
+ targetFrame.style.opacity = 1;
+ targetFrame.style.position = "relative";
+ targetFrame.style.width = this.config.width;
+ targetFrame.style.height = this.config.height;
+ targetFrame.parentNode.style.height = "inherit";
+
+ if (loader) loader.remove();
+ }
+ }
+
+ /**
+ * Initializes the editor.
+ * @param {Object} config - The configuration object for the editor.
+ * @returns {Object} - The initialized frame object.
+ */
+ initEditor(config = {}) {
+ config.mode = "editor";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Initializes the viewer mode.
+ * @param {Object} config - The configuration object.
+ * @returns {Promise} A promise that resolves when the viewer is initialized.
+ */
+ initViewer(config = {}) {
+ config.mode = "viewer";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Initializes the room selector.
+ *
+ * @param {Object} config - The configuration object.
+ * @returns {Object} - The initialized frame.
+ */
+ initRoomSelector(config = {}) {
+ config.mode = "room-selector";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Initializes the file selector mode.
+ * @param {Object} config - The configuration object.
+ * @returns {Object} - The initialized frame.
+ */
+ initFileSelector(config = {}) {
+ config.mode = "file-selector";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Initializes the system with the given configuration.
+ * @param {Object} config - The configuration object.
+ * @returns {Promise} A promise that resolves when the system is initialized.
+ */
+ initSystem(config = {}) {
+ config.mode = "system";
+
+ return this.initFrame(config);
+ }
+
+ /**
+ * Destroys the frame and cleans up associated resources.
+ */
+ destroyFrame() {
+ const target = document.createElement("div");
+
+ target.setAttribute("id", this.config.frameId);
+ target.innerHTML = this.config.destroyText;
+ target.className = this.#classNames;
+
+ const targetFrame = document.getElementById(
+ this.config.frameId + "-container"
+ );
+
+ window.removeEventListener("message", this.#onMessage, false);
+ this.#isConnected = false;
+
+ delete window.DocSpace.SDK.frames[this.config.frameId];
+
+ targetFrame?.parentNode?.replaceChild(target, targetFrame);
+
+ this.config = {};
+ }
+
+ /**
+ * Retrieves a method promise.
+ *
+ * @param {string} methodName - The name of the method.
+ * @param {Object|null} params - The parameters for the method (optional).
+ * @param {boolean} withReload - Indicates whether to reload the configuration (optional).
+ * @returns {Promise} A promise that resolves with the method data.
+ */
+ #getMethodPromise = (methodName, params = null, withReload = false) => {
+ return new Promise((resolve) => {
+ if (withReload) {
+ this.initFrame(this.config);
+ resolve(this.config);
+ } else {
+ this.#executeMethod(methodName, params, (data) => resolve(data));
+ }
+ });
+ };
+
+ /**
+ * Retrieves folder information.
+ * @returns {Promise} A promise that resolves with the folder information.
+ */
+ getFolderInfo() {
+ return this.#getMethodPromise("getFolderInfo");
+ }
+
+ /**
+ * Retrieves the current selection.
+ * @returns {Promise} A promise that resolves with the current selection.
+ */
+ getSelection() {
+ return this.#getMethodPromise("getSelection");
+ }
+
+ /**
+ * Retrieves the files from the server.
+ * @returns {Promise} A promise that resolves with the files.
+ */
+ getFiles() {
+ return this.#getMethodPromise("getFiles");
+ }
+
+ /**
+ * Retrieves the folders from the server.
+ * @returns {Promise} A promise that resolves with the folders data.
+ */
+ getFolders() {
+ return this.#getMethodPromise("getFolders");
+ }
+
+ /**
+ * Retrieves a list of items.
+ * @returns {Promise} A promise that resolves with the list of items.
+ */
+ getList() {
+ return this.#getMethodPromise("getList");
+ }
+
+ /**
+ * Retrieves rooms based on the provided filter.
+ *
+ * @param {Object} filter - The filter object to apply when retrieving rooms.
+ * @returns {Promise} A promise that resolves with the retrieved rooms.
+ */
+ getRooms(filter) {
+ return this.#getMethodPromise("getRooms", filter);
+ }
+
+ /**
+ * Retrieves user information.
+ * @returns {Promise} A promise that resolves with the user information.
+ */
+ getUserInfo() {
+ return this.#getMethodPromise("getUserInfo");
+ }
+
+ /**
+ * Retrieves the configuration object.
+ * @returns {Object} The configuration object.
+ */
+ getConfig() {
+ return this.config;
+ }
+
+ /**
+ * Retrieves the hash settings.
+ * @returns {Promise} A promise that resolves with the hash settings.
+ */
+ getHashSettings() {
+ return this.#getMethodPromise("getHashSettings");
+ }
+
+ /**
+ * Sets the configuration for the API.
+ *
+ * @param {Object} newConfig - The new configuration object.
+ * @param {boolean} [reload=false] - Indicates whether to reload the API after setting the configuration.
+ * @returns {Promise} A promise that resolves when the configuration is set.
+ */
+ setConfig(newConfig = {}, reload = false) {
+ if (this.#oneOfExistInObject(this.config.keysForReload, newConfig))
+ reload = true;
+
+ this.config = { ...this.config, ...newConfig };
+
+ return this.#getMethodPromise("setConfig", this.config, reload);
+ }
+
+ /**
+ * Opens a modal with the specified type and options.
+ *
+ * @param {string} type - The type of the modal.
+ * @param {object} options - The options for the modal.
+ * @returns {Promise} A promise that resolves when the modal is opened.
+ */
+ openModal(type, options) {
+ return this.#getMethodPromise("openModal", { type, options });
+ }
+
+ /**
+ * Creates a file with the specified parameters.
+ *
+ * @param {string} folderId - The ID of the folder where the file will be created.
+ * @param {string} title - The title of the file.
+ * @param {string} templateId - The ID of the template to be used for the file.
+ * @param {string} formId - The ID of the form associated with the file.
+ * @returns {Promise} A promise that resolves with the created file.
+ */
+ createFile(folderId, title, templateId, formId) {
+ return this.#getMethodPromise("createFile", {
+ folderId,
+ title,
+ templateId,
+ formId,
+ });
+ }
+
+ /**
+ * Creates a new folder with the given parent folder ID and title.
+ *
+ * @param {string} parentFolderId - The ID of the parent folder.
+ * @param {string} title - The title of the new folder.
+ * @returns {Promise} A promise that resolves with the result of the createFolder operation.
+ */
+ createFolder(parentFolderId, title) {
+ return this.#getMethodPromise("createFolder", {
+ parentFolderId,
+ title,
+ });
+ }
+
+ /**
+ * Creates a new room with the specified title and room type.
+ * @param {string} title - The title of the room.
+ * @param {string} roomType - The type of the room.
+ * @returns {Promise} A promise that resolves with the created room.
+ */
+ createRoom(title, roomType) {
+ return this.#getMethodPromise("createRoom", {
+ title,
+ roomType,
+ });
+ }
+
+ /**
+ * Sets the view type for the list of items.
+ *
+ * @param {string} type - The type of view to set.
+ * @returns {Promise} - A promise that resolves when the view type is set.
+ */
+ setListView(type) {
+ return this.#getMethodPromise("setItemsView", type);
+ }
+
+ /**
+ * Creates a hash for the given password using the specified hash settings.
+ *
+ * @param {string} password - The password to be hashed.
+ * @param {object} hashSettings - The settings for the hash algorithm.
+ * @returns {Promise} A promise that resolves to the generated hash.
+ */
+ createHash(password, hashSettings) {
+ return this.#getMethodPromise("createHash", { password, hashSettings });
+ }
+
+ /**
+ * Logs in a user with the provided email and password hash.
+ * @param {string} email - The user's email address.
+ * @param {string} passwordHash - The hashed password.
+ * @returns {Promise} A promise that resolves with the login response.
+ */
+ login(email, passwordHash) {
+ return this.#getMethodPromise("login", { email, passwordHash });
+ }
+
+ /**
+ * Logs out the user.
+ * @returns {Promise} A promise that resolves when the user is logged out.
+ */
+ logout() {
+ return this.#getMethodPromise("logout");
+ }
+
+ /**
+ * Creates a new tag with the given name.
+ *
+ * @param {string} name - The name of the tag.
+ * @returns {Promise} A promise that resolves when the tag is created.
+ */
+ createTag(name) {
+ return this.#getMethodPromise("createTag", name);
+ }
+
+ /**
+ * Adds tags to a room.
+ *
+ * @param {string} roomId - The ID of the room.
+ * @param {string[]} tags - An array of tags to add.
+ * @returns {Promise} A promise that resolves when the tags are added successfully.
+ */
+ addTagsToRoom(roomId, tags) {
+ return this.#getMethodPromise("addTagsToRoom", { roomId, tags });
+ }
+
+ /**
+ * Removes tags from a room.
+ *
+ * @param {string} roomId - The ID of the room.
+ * @param {string[]} tags - An array of tags to be removed.
+ * @returns {Promise} A promise that resolves when the tags are successfully removed.
+ */
+ removeTagsFromRoom(roomId, tags) {
+ return this.#getMethodPromise("removeTagsFromRoom", { roomId, tags });
+ }
+ }
+
+ /**
+ * Represents the DocSpace SDK.
+ * @class
+ */
+ class DocSpaceSDK {
+ frames = {};
+ instances = [];
+
+ /**
+ * Initializes a new instance of the DocSpace class and initializes the frame.
+ * @param {Object} config - The configuration object for initializing the DocSpace instance.
+ * @returns {DocSpace} The initialized DocSpace instance.
+ */
+ initFrame = (config) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initFrame(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initFrame(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes a button with the provided configuration.
+ * @param {Object} config - The configuration object for the button.
+ * @returns {DocSpace} - An instance of the DocSpace class.
+ */
+ initButton = (config) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initButton(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initButton(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the editor.
+ *
+ * @param {Object} config - The configuration object for the editor.
+ * @returns {DocSpace} The initialized DocSpace instance.
+ */
+ initEditor = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initEditor(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initEditor(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the viewer.
+ * @param {Object} config - The configuration object for the viewer.
+ * @returns {DocSpace} - The initialized DocSpace instance.
+ */
+ initViewer = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initViewer(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initViewer(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the room selector.
+ *
+ * @param {Object} config - The configuration object.
+ * @returns {DocSpace} The instance of the DocSpace class.
+ */
+ initRoomSelector = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initRoomSelector(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initRoomSelector(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the file selector.
+ *
+ * @param {Object} config - The configuration object.
+ * @returns {DocSpace} The initialized DocSpace instance.
+ */
+ initFileSelector = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initFileSelector(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initFileSelector(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the manager for DocSpace.
+ * @param {Object} config - The configuration object for the manager.
+ * @returns {DocSpace} The initialized DocSpace instance.
+ */
+ initManager = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initManager(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initManager(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+
+ /**
+ * Initializes the DocSpace system.
+ *
+ * @param {Object} config - The configuration object for initializing the system.
+ * @returns {DocSpace} - The initialized DocSpace instance.
+ */
+ initSystem = (config = {}) => {
+ const existInstance = this.instances.find(
+ (i) => i.config.frameId === config.frameId
+ );
+
+ if (existInstance) {
+ existInstance.initSystem(config);
+ return existInstance;
+ }
+
+ const instance = new DocSpace(config);
+
+ instance.initSystem(config);
+
+ this.instances.push(instance);
+
+ return instance;
+ };
+ }
+
+ window.DocSpace = window.DocSpace || {};
+
+ const config = getConfigFromParams();
+
+ window.DocSpace.SDK = window.DocSpace.SDK || new DocSpaceSDK();
+
+ if (config.init) {
+ config?.isButtonMode
+ ? window.DocSpace.SDK.initButton(config)
+ : window.DocSpace.SDK.initFrame(config);
+ }
+})();