Merge branch 'hotfix/v2.6.1' into feature/translations-quotas

This commit is contained in:
Alexey Safronov 2024-08-22 15:18:11 +04:00
commit 3cae2e01ae
50 changed files with 557 additions and 300 deletions

View File

@ -19,6 +19,7 @@
href="/logo.ashx?logotype=3"
/>
<link rel="mask-icon" href="/logo.ashx?logotype=3" />
<link rel="apple-touch-icon" sizes="32x32" href="/logo.ashx?logotype=3" />
<link rel="manifest" href="/manifest.json" />
<!-- Tell the browser it's a PWA -->

View File

@ -33,7 +33,7 @@ import { Provider as MobxProvider } from "mobx-react";
import ThemeProvider from "./components/ThemeProviderWrapper";
import ErrorBoundary from "./components/ErrorBoundaryWrapper";
import store from "client/store";
import store from "SRC_DIR/store";
import i18n from "./i18n";
import "@docspace/shared/polyfills/broadcastchannel";

View File

@ -160,7 +160,7 @@ export default function withFileActions(WrappedFileItem) {
if (
e.target?.tagName === "INPUT" ||
e.target?.tagName === "SPAN" ||
// e.target?.tagName === "SPAN" ||
e.target?.tagName === "A" ||
e.target.closest(".checkbox") ||
e.target.closest(".table-container_row-checkbox") ||

View File

@ -169,6 +169,10 @@ const withHotkeys = (Component) => {
};
const onPaste = async (e) => {
const someDialogIsOpen = checkDialogsOpen();
if (someDialogIsOpen) return;
uploadClipboardFiles(t, e);
};

View File

@ -170,7 +170,7 @@ const PureConnectDialogContainer = (props) => {
provider_id,
)
.then(async () => {
await setThirdPartyAccountsInfo();
await setThirdPartyAccountsInfo(t);
})
.catch((err) => {
toastr.error(err);

View File

@ -24,18 +24,23 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import React, { useEffect, useState, useRef } from "react";
import { useEffect, useState } from "react";
import styled from "styled-components";
import { ReactSVG } from "react-svg";
import { isMobileOnly, isMobile } from "react-device-detect";
import { Button } from "@docspace/shared/components/button";
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
import { Text } from "@docspace/shared/components/text";
import { Tooltip } from "@docspace/shared/components/tooltip";
import { connectedCloudsTypeTitleTranslation as ProviderKeyTranslation } from "@docspace/client/src/helpers/filesUtils";
import { Base } from "@docspace/shared/themes";
import { toastr } from "@docspace/shared/components/toast";
import { ComboBox } from "@docspace/shared/components/combobox";
import ExternalLinkReactSvgUrl from "PUBLIC_DIR/images/external.link.react.svg?url";
import { ThirdPartyServicesUrlName } from "../../../../../helpers/constants";
import { isDesktop } from "@docspace/shared/utils";
const StyledStorageLocation = styled.div`
display: flex;
@ -91,16 +96,29 @@ const StyledStorageLocation = styled.div`
StyledStorageLocation.defaultProps = { theme: Base };
const services = {
GoogleDrive: "google",
Box: "box",
Dropbox: "dropbox",
OneDrive: "skydrive",
Nextcloud: "nextcloud",
kDrive: "kdrive",
ownCloud: "owncloud",
WebDav: "webdav",
};
const StyledComboBoxItem = styled.div`
display: flex;
.drop-down-item_text {
color: ${({ theme, isDisabled }) =>
isDisabled ? theme.dropDownItem.disableColor : theme.dropDownItem.color};
}
.drop-down-item_icon {
display: flex;
align-items: center;
div {
display: flex;
}
margin-inline-start: auto;
svg {
min-height: 16px;
min-width: 16px;
}
}
`;
const ThirdPartyComboBox = ({
t,
@ -124,15 +142,16 @@ const ThirdPartyComboBox = ({
isDisabled,
setIsScrollLocked,
isAdmin,
}) => {
const deafultSelectedItem = {
const defaultSelectedItem = {
key: "length",
label:
storageLocation?.provider?.title ||
t("ThirdPartyStorageComboBoxPlaceholder"),
};
const [selectedItem, setSelectedItem] = useState(deafultSelectedItem);
const [selectedItem, setSelectedItem] = useState(defaultSelectedItem);
const thirdparties = connectItems.map((item) => ({
...item,
@ -142,7 +161,7 @@ const ThirdPartyComboBox = ({
const setStorageLocaiton = (thirparty, isConnected) => {
if (!isConnected) {
window.open(
`/portal-settings/integration/third-party-services?service=${services[thirparty.id]}`,
`/portal-settings/integration/third-party-services?service=${ThirdPartyServicesUrlName[thirparty.id]}`,
"_blank",
);
return;
@ -207,35 +226,79 @@ const ThirdPartyComboBox = ({
setSaveThirdpartyResponse(null);
}, [saveThirdpartyResponse]);
const options = thirdparties
.sort((storage) => (storage.isConnected ? -1 : 1))
.map((item) => ({
label:
item.title + (item.isConnected ? "" : ` (${t("ActivationRequired")})`),
title: item.title,
key: item.id,
icon: item.isConnected ? undefined : ExternalLinkReactSvgUrl,
className: item.isConnected ? "" : "storage-unavailable",
}));
const onSelect = (event) => {
const data = event.currentTarget.dataset;
const onSelect = (elem) => {
const thirdparty = thirdparties.find((t) => {
return elem.key === t.id;
return t.id === data.thirdPartyId;
});
thirdparty && setStorageLocaiton(thirdparty, thirdparty.isConnected);
thirdparty.isConnected
? setSelectedItem(elem)
: setSelectedItem({ ...deafultSelectedItem });
? setSelectedItem({ key: thirdparty.id, label: thirdparty.title })
: setSelectedItem({ ...defaultSelectedItem });
};
const getTextTooltip = () => {
return (
<Text fontSize="12px" noSelect>
{t("Common:EnableThirdPartyIntegration")}
</Text>
);
};
const advancedOptions = thirdparties
.sort((storage) => (storage.isConnected ? -1 : 1))
?.map((item) => {
const isDisabled = !item.isConnected && !isAdmin;
const itemLabel =
item.title + (item.isConnected ? "" : ` (${t("ActivationRequired")})`);
const disabledData = isDisabled
? { "data-tooltip-id": "file-links-tooltip", "data-tip": "tooltip" }
: {};
return (
<StyledComboBoxItem isDisabled={isDisabled} key={item.id}>
<DropDownItem
onClick={onSelect}
data-third-party-id={item.id}
disabled={isDisabled}
{...disabledData}
>
<Text className="drop-down-item_text" fontWeight={600}>
{itemLabel}
</Text>
{!isDisabled && !item.isConnected ? (
<ReactSVG
src={ExternalLinkReactSvgUrl}
className="drop-down-item_icon"
/>
) : (
<></>
)}
</DropDownItem>
{isDisabled && (
<Tooltip
float={isDesktop()}
id="file-links-tooltip"
getContent={getTextTooltip}
place="bottom"
/>
)}
</StyledComboBoxItem>
);
});
return (
<StyledStorageLocation>
<div className="set_room_params-thirdparty">
<ComboBox
className="thirdparty-combobox"
selectedOption={selectedItem}
options={options}
options={[]}
advancedOptions={advancedOptions}
scaled
withBackdrop={isMobile}
size="content"
@ -244,12 +307,12 @@ const ThirdPartyComboBox = ({
directionY="both"
displaySelectedOption
noBorder={false}
// fixedDirection
isDefaultMode={true}
hideMobileView={false}
forceCloseClickOutside
scaledOptions
onSelect={onSelect}
showDisabledItems
displayArrow
/>
<Button
id="shared_third-party-storage_connect"

View File

@ -71,6 +71,7 @@ const ThirdPartyStorage = ({
isDisabled,
currentColorScheme,
isRoomAdmin,
isAdmin,
createNewFolderIsChecked,
onCreateFolderChange,
@ -168,6 +169,7 @@ const ThirdPartyStorage = ({
setIsScrollLocked={setIsScrollLocked}
setIsOauthWindowOpen={setIsOauthWindowOpen}
isDisabled={isDisabled}
isAdmin={isAdmin}
/>
)}
@ -213,7 +215,7 @@ export default inject(
const connectItems = thirdPartyStore.connectingStorages;
const { isRoomAdmin } = authStore;
const { isRoomAdmin, isAdmin } = authStore;
return {
connectItems,
@ -232,6 +234,7 @@ export default inject(
getOAuthToken,
currentColorScheme,
isRoomAdmin,
isAdmin,
fetchConnectingStorages: thirdPartyStore.fetchConnectingStorages,
};
},

View File

@ -56,7 +56,6 @@ const StyledInvitePanel = styled.div`
height: auto;
width: auto;
background: ${(props) => props.theme.infoPanel.blurColor};
backdrop-filter: blur(3px);
z-index: 309;
position: fixed;
top: 0;

View File

@ -85,7 +85,7 @@ export const TableVersions = Object.freeze({
Files: "3",
People: "3",
Trash: "4",
Groups: "5",
Groups: "6",
InsideGroup: "6",
Recent: "1",
});
@ -169,3 +169,14 @@ export const SortByFieldName = Object.freeze({
LastOpened: "LastOpened",
UsedSpace: "usedspace",
});
export const ThirdPartyServicesUrlName = Object.freeze({
GoogleDrive: "google",
Box: "box",
Dropbox: "dropbox",
OneDrive: "skydrive",
Nextcloud: "nextcloud",
kDrive: "kdrive",
ownCloud: "owncloud",
WebDav: "webdav",
});

View File

@ -54,11 +54,9 @@ export const GreetingContainer = styled.div`
}
.tooltip {
.invitation-text {
display: flex;
flex-direction: column;
align-items: center;
p {
text-align: center;
overflow-wrap: break-word;
}
@media ${mobile} {

View File

@ -485,7 +485,7 @@ const CreateUserForm = (props) => {
<PortalLogo className="portal-logo" />
{linkData.type === "LinkInvite" && (
<div className="tooltip">
<Text fontSize="16px" as="div" className="invitation-text">
<Text fontSize="16px">
{roomName ? (
<Trans
t={t}

View File

@ -30,9 +30,9 @@ import { withTranslation } from "react-i18next";
import { TableHeader } from "@docspace/shared/components/table";
import { Events } from "@docspace/shared/enums";
import { TableVersions } from "SRC_DIR/helpers/constants";
const TABLE_VERSION = "5";
const TABLE_COLUMNS = `groupsTableColumns_ver-${TABLE_VERSION}`;
const TABLE_COLUMNS = `groupsTableColumns_ver-${TableVersions.Groups}`;
class GroupsTableHeader extends React.Component {
constructor(props) {
@ -49,6 +49,15 @@ class GroupsTableHeader extends React.Component {
minWidth: 210,
onClick: this.onFilter,
},
{
key: "People",
title: props.t("Common:People"),
enable: props.peopleAccountsGroupsColumnIsEnabled,
sortBy: "membersCount",
onClick: this.onFilter,
resizable: true,
onChange: this.onColumnChange,
},
{
key: "Head of Group",
title: props.t("Common:HeadOfGroup"),
@ -161,6 +170,8 @@ export default inject(
setColumnEnable: tableStore.setColumnEnable,
managerAccountsGroupsColumnIsEnabled:
tableStore.managerAccountsGroupsColumnIsEnabled,
peopleAccountsGroupsColumnIsEnabled:
tableStore.peopleAccountsGroupsColumnIsEnabled,
}),
)(
withTranslation(["People", "Common", "PeopleTranslations"])(

View File

@ -45,6 +45,7 @@ const GroupsTableItem = ({
getGroupContextOptions,
getModel,
openGroupAction,
peopleAccountsGroupsColumnIsEnabled,
managerAccountsGroupsColumnIsEnabled,
changeGroupSelection,
@ -139,6 +140,23 @@ const GroupsTableItem = ({
<Badges isLDAP={item.isLDAP} />
</TableCell>
{peopleAccountsGroupsColumnIsEnabled ? (
<TableCell className="table-container_group-people">
<Text
title={item.membersCount}
fontWeight="600"
fontSize="13px"
isTextOverflow
className="table-cell_group-people"
color={theme.filesSection.tableView.row.sideColor}
>
{item.membersCount}
</Text>
</TableCell>
) : (
<div />
)}
{managerAccountsGroupsColumnIsEnabled ? (
<TableCell className={"table-container_group-manager"}>
<Text

View File

@ -57,6 +57,7 @@ const GroupsTableView = ({
groupsIsFiltered,
groupsFilterTotal,
peopleAccountsGroupsColumnIsEnabled,
managerAccountsGroupsColumnIsEnabled,
}) => {
const ref = useRef(null);
@ -110,6 +111,9 @@ const GroupsTableView = ({
managerAccountsGroupsColumnIsEnabled={
managerAccountsGroupsColumnIsEnabled
}
peopleAccountsGroupsColumnIsEnabled={
peopleAccountsGroupsColumnIsEnabled
}
/>
))}
</TableBody>
@ -155,7 +159,10 @@ export default inject(
const { isVisible: infoPanelVisible } = infoPanelStore;
const { managerAccountsGroupsColumnIsEnabled } = tableStore;
const {
managerAccountsGroupsColumnIsEnabled,
peopleAccountsGroupsColumnIsEnabled,
} = tableStore;
return {
groups,
@ -177,6 +184,7 @@ export default inject(
groupsIsFiltered,
groupsFilterTotal,
peopleAccountsGroupsColumnIsEnabled,
managerAccountsGroupsColumnIsEnabled,
};
},

View File

@ -2021,6 +2021,13 @@ const SectionFilterContent = ({
default: true,
};
const people = {
id: "sort-by_people",
key: "membersCount",
label: t("Common:People"),
default: true,
};
const manager = {
id: "sort-by_manager",
key: "manager",
@ -2028,7 +2035,7 @@ const SectionFilterContent = ({
default: true,
};
groupsOptions.push(title, manager);
groupsOptions.push(title, people, manager);
return groupsOptions;
}

View File

@ -26,7 +26,7 @@
import React, { useEffect } from "react";
import { Provider as MobxProvider } from "mobx-react";
import store from "client/store";
import store from "SRC_DIR/store";
import CommonWhiteLabel from "./CommonWhiteLabel";
const { authStore } = store;

View File

@ -625,6 +625,12 @@ const StyledBackup = styled.div`
}
.backup_third-party-context {
margin-top: 4px;
svg {
width: 16px;
height: 16px;
padding: 7px;
}
}
`;
const StyledBackupList = styled.div`
@ -764,6 +770,31 @@ const StyledSettingsHeader = styled.div`
margin: auto 0;
}
`;
const StyledComboBoxItem = styled.div`
display: flex;
.drop-down-item_text {
color: ${({ theme, isDisabled }) =>
isDisabled ? theme.dropDownItem.disableColor : theme.dropDownItem.color};
}
.drop-down-item_icon {
display: flex;
align-items: center;
div {
display: flex;
}
margin-inline-start: auto;
svg {
min-height: 16px;
min-width: 16px;
}
}
`;
export {
StyledModules,
StyledRestoreBackup,
@ -774,4 +805,5 @@ export {
StyledAutoBackup,
StyledStoragesModule,
StyledSettingsHeader,
StyledComboBoxItem,
};

View File

@ -27,10 +27,15 @@
import VerticalDotsReactSvgUrl from "PUBLIC_DIR/images/vertical-dots.react.svg?url";
import RefreshReactSvgUrl from "PUBLIC_DIR/images/refresh.react.svg?url";
import AccessNoneReactSvgUrl from "PUBLIC_DIR/images/access.none.react.svg?url";
import React, { useEffect, useReducer } from "react";
import ExternalLinkReactSvgUrl from "PUBLIC_DIR/images/external.link.react.svg?url";
import { useEffect, useReducer } from "react";
import { ReactSVG } from "react-svg";
import { Button } from "@docspace/shared/components/button";
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
import { Text } from "@docspace/shared/components/text";
import { saveSettingsThirdParty } from "@docspace/shared/api/files";
import { StyledBackup } from "../StyledBackup";
import { StyledBackup, StyledComboBoxItem } from "../StyledBackup";
import { ComboBox } from "@docspace/shared/components/combobox";
import { toastr } from "@docspace/shared/components/toast";
import { inject, observer } from "mobx-react";
@ -39,6 +44,7 @@ import DeleteThirdPartyDialog from "../../../../../../components/dialogs/DeleteT
import { getOAuthToken } from "@docspace/shared/utils/common";
import FilesSelectorInput from "SRC_DIR/components/FilesSelectorInput";
import { useTranslation } from "react-i18next";
import { ThirdPartyServicesUrlName } from "../../../../../../helpers/constants";
const initialState = {
folderList: {},
@ -83,7 +89,7 @@ const DirectThirdPartyConnection = (props) => {
const onSetSettings = async () => {
try {
await setThirdPartyAccountsInfo();
await setThirdPartyAccountsInfo(t);
setState({
isLoading: false,
@ -157,7 +163,7 @@ const DirectThirdPartyConnection = (props) => {
provider_id,
);
await setThirdPartyAccountsInfo();
await setThirdPartyAccountsInfo(t);
} catch (e) {
toastr.error(e);
}
@ -165,9 +171,24 @@ const DirectThirdPartyConnection = (props) => {
setState({ isLoading: false, isUpdatingInfo: false });
};
const onSelectAccount = (options) => {
const key = options.key;
setSelectedThirdPartyAccount({ ...accounts[+key] });
const onSelectAccount = (event) => {
const data = event.currentTarget.dataset;
const account = accounts.find((t) => t.key === data.thirdPartyKey);
if (!account.connected) {
setSelectedThirdPartyAccount({
key: 0,
label: selectedThirdPartyAccount?.label,
});
return window.open(
`/portal-settings/integration/third-party-services?service=${ThirdPartyServicesUrlName[data.thirdPartyKey]}`,
"_blank",
);
}
setSelectedThirdPartyAccount(account);
};
const onDisconnect = () => {
@ -187,7 +208,7 @@ const DirectThirdPartyConnection = (props) => {
key: "Disconnect-settings",
label: t("Common:Disconnect"),
onClick: onDisconnect,
disabled: selectedThirdPartyAccount?.connected ? false : true,
disabled: selectedThirdPartyAccount?.storageIsConnected ? false : true,
icon: AccessNoneReactSvgUrl,
},
];
@ -201,6 +222,33 @@ const DirectThirdPartyConnection = (props) => {
const isDisabledSelector = isLoading || isDisabled;
const folderList = connectedThirdPartyAccount ?? {};
const advancedOptions = accounts?.map((item) => {
return (
<StyledComboBoxItem isDisabled={item.disabled} key={item.key}>
<DropDownItem
onClick={onSelectAccount}
className={item.className}
data-third-party-key={item.key}
disabled={item.disabled}
>
<Text className="drop-down-item_text" fontWeight={600}>
{item.title}
</Text>
{!item.disabled && !item.connected ? (
<ReactSVG
src={ExternalLinkReactSvgUrl}
className="drop-down-item_icon"
/>
) : (
<></>
)}
</DropDownItem>
</StyledComboBoxItem>
);
});
return (
<StyledBackup
isConnectedAccount={
@ -210,17 +258,25 @@ const DirectThirdPartyConnection = (props) => {
>
<div className="backup_connection">
<ComboBox
options={accounts}
className="thirdparty-combobox"
selectedOption={{
key: 0,
label: selectedThirdPartyAccount?.label,
}}
onSelect={onSelectAccount}
options={[]}
advancedOptions={advancedOptions}
scaled
size="content"
manualWidth={"auto"}
directionY="both"
displaySelectedOption
noBorder={false}
isDefaultMode={true}
hideMobileView={false}
forceCloseClickOutside
scaledOptions
dropDownMaxHeight={300}
tabIndex={1}
showDisabledItems
displayArrow
isDisabled={isDisabledComponent}
/>

View File

@ -28,7 +28,7 @@ import { makeAutoObservable } from "mobx";
import { isMobile } from "@docspace/shared/utils";
import { checkDialogsOpen } from "@docspace/shared/utils/checkDialogsOpen";
import { TUser, TUserGroup } from "@docspace/shared/api/people/types";
import { TABLE_HEADER_HEIGHT } from "@docspace/shared/utils/device";
import { TABLE_HEADER_HEIGHT } from "@docspace/shared/components/table/Table.constants";
type AccountsType = TUser | TUserGroup;

View File

@ -37,13 +37,16 @@ import { combineUrl } from "@docspace/shared/utils/combineUrl";
import config from "PACKAGE_FILE";
import {
getSettingsThirdParty,
getThirdPartyCapabilities,
uploadBackup,
} from "@docspace/shared/api/files";
import i18n from "../i18n";
import { connectedCloudsTypeTitleTranslation } from "../helpers/filesUtils.js";
const { EveryDayType, EveryWeekType } = AutoBackupPeriod;
class BackupStore {
authStore = null;
thirdPartyStore = null;
restoreResource = null;
backupSchedule = {};
@ -100,11 +103,13 @@ class BackupStore {
selectedThirdPartyAccount = null;
connectedThirdPartyAccount = null;
accounts = [];
capabilities = [];
connectedAccount = [];
constructor() {
constructor(authStore, thirdPartyStore) {
makeAutoObservable(this);
this.authStore = authStore;
this.thirdPartyStore = thirdPartyStore;
}
setConnectedThirdPartyAccount = (account) => {
@ -195,37 +200,20 @@ class BackupStore {
return false;
}
setThirdPartyAccountsInfo = async () => {
const [connectedAccount, capabilities] = await Promise.all([
setThirdPartyAccountsInfo = async (t) => {
const [connectedAccount, providers] = await Promise.all([
getSettingsThirdParty(),
getThirdPartyCapabilities(),
this.thirdPartyStore.fetchConnectingStorages(),
]);
this.setCapabilities(capabilities);
this.setConnectedThirdPartyAccount(connectedAccount);
const providerNames = [
["GoogleDrive", i18n.t("Translations:TypeTitleGoogle")],
["Box", i18n.t("Translations:TypeTitleBoxNet")],
["DropboxV2", i18n.t("Translations:TypeTitleDropBox")],
["SharePoint", i18n.t("Translations:TypeTitleSharePoint")],
["OneDrive", i18n.t("Translations:TypeTitleSkyDrive")],
["WebDav", "Nextcloud"],
["WebDav", "ownCloud"],
["kDrive", i18n.t("Translations:TypeTitlekDrive")],
["Yandex", i18n.t("Translations:TypeTitleYandex")],
["WebDav", i18n.t("Translations:TypeTitleWebDav")],
];
let accounts = [],
selectedAccount = {};
let index = 0;
providerNames.map((item) => {
const { account, isConnected } = this.getThirdPartyAccount(
item[0],
item[1],
index,
);
providers.map((item) => {
const { account, isConnected } = this.getThirdPartyAccount(item, t);
if (!account) return;
@ -237,51 +225,53 @@ class BackupStore {
index++;
});
accounts = accounts.sort((storage) => (storage.connected ? -1 : 1));
this.setThirdPartyAccounts(accounts);
console.log(selectedAccount, accounts);
const connectedThirdPartyAccount = accounts.findLast((a) => a.connected);
this.setSelectedThirdPartyAccount(
Object.keys(selectedAccount).length !== 0
? selectedAccount
: { ...accounts[0] },
: connectedThirdPartyAccount,
);
};
getThirdPartyAccount = (providerKey, serviceTitle, index) => {
const accountIndex =
this.capabilities &&
this.capabilities.findIndex((x) => x[0] === providerKey);
if (accountIndex === -1) return { account: null, isConnected: false };
getThirdPartyAccount = (provider, t) => {
const serviceTitle = connectedCloudsTypeTitleTranslation(provider.name, t);
const serviceLabel = provider.connected
? serviceTitle
: `${serviceTitle} (${t("CreateEditRoomDialog:ActivationRequired")})`;
const isConnected =
this.connectedThirdPartyAccount?.providerKey === "WebDav"
? serviceTitle === this.connectedThirdPartyAccount?.title
: this.capabilities[accountIndex][0] ===
this.connectedThirdPartyAccount?.providerKey;
: provider.key === this.connectedThirdPartyAccount?.providerKey;
const isDisabled = !provider.connected && !this.authStore.isAdmin;
const account = {
key: index.toString(),
label: serviceTitle,
title: serviceTitle,
provider_key: this.capabilities[accountIndex][0],
...(this.capabilities[accountIndex][1] && {
provider_link: this.capabilities[accountIndex][1],
key: provider.name,
label: serviceLabel,
title: serviceLabel,
provider_key: provider.key,
...(provider.clientId && {
provider_link: provider.clientId,
}),
connected: isConnected,
storageIsConnected: isConnected,
connected: provider.connected,
...(isConnected && {
provider_id: this.connectedThirdPartyAccount?.providerId,
id: this.connectedThirdPartyAccount.id,
}),
disabled: isDisabled,
};
return { account, isConnected };
};
setCapabilities = (capabilities) => {
this.capabilities = capabilities;
};
setThirdPartyAccounts = (accounts) => {
this.accounts = accounts;
};

View File

@ -37,7 +37,7 @@ import getFilesFromEvent from "@docspace/shared/components/drag-and-drop/get-fil
import config from "PACKAGE_FILE";
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
import { encryptionUploadDialog } from "../helpers/encryptionUploadDialog";
import { TABLE_HEADER_HEIGHT } from "@docspace/shared/utils/device";
import { TABLE_HEADER_HEIGHT } from "@docspace/shared/components/table/Table.constants";
class HotkeyStore {
filesStore;

View File

@ -432,10 +432,10 @@ class LdapFormStore {
scrollToField = () => {
for (let key in this.errors) {
const element = document.getElementsByName(key)[0];
const element = document.getElementsByName(key)?.[0];
element.focus();
element.blur();
element?.focus();
element?.blur();
return;
}
};

View File

@ -388,11 +388,11 @@ class SsoFormStore {
this.isSubmitLoading = true;
try {
await submitSsoForm(data);
const res = await submitSsoForm(data);
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
this.isSubmitLoading = false;
this.setSpMetadata(true);
this.setDefaultSettings(settings);
this.setDefaultSettings(res);
this.setIsSsoEnabled(settings.enableSso);
} catch (err) {
toastr.error(err);
@ -406,6 +406,7 @@ class SsoFormStore {
const config = await resetSsoForm();
this.setFields(config);
this.hideErrors();
} catch (err) {
toastr.error(err);
console.error(err);
@ -902,8 +903,14 @@ class SsoFormStore {
checkRequiredFields = () => {
this.setError("entityId", this.entityId);
this.setError("ssoUrlPost", this.ssoUrlPost);
this.setError("sloUrlPost", this.sloUrlPost);
this.ssoBinding === BINDING_POST &&
this.setError("ssoUrlPost", this.ssoUrlPost);
this.ssoBinding === BINDING_REDIRECT &&
this.setError("ssoUrlRedirect", this.ssoUrlRedirect);
this.sloBinding === BINDING_POST &&
this.setError("sloUrlPost", this.sloUrlPost);
this.sloBinding === BINDING_REDIRECT &&
this.setError("sloUrlRedirect", this.sloUrlRedirect);
this.setError("firstName", this.firstName);
this.setError("lastName", this.lastName);
this.setError("email", this.email);
@ -977,9 +984,9 @@ class SsoFormStore {
for (let key in this) {
if (key.includes("HasError") && this[key] !== false) {
const name = key.replace("HasError", "");
const element = document.getElementsByName(name)[0];
element.focus();
element.blur();
const element = document.getElementsByName(name)?.[0];
element?.focus();
element?.blur();
return;
}
}

View File

@ -80,6 +80,7 @@ class TableStore {
emailAccountsColumnIsEnabled = true;
storageAccountsColumnIsEnabled = true;
peopleAccountsGroupsColumnIsEnabled = true;
managerAccountsGroupsColumnIsEnabled = true;
typeAccountsInsideGroupColumnIsEnabled = true;
@ -163,6 +164,8 @@ class TableStore {
setAccountsColumnStorage = (enable) =>
(this.storageAccountsColumnIsEnabled = enable);
setAccountsGroupsColumnPeople = (enable) =>
(this.peopleAccountsGroupsColumnIsEnabled = enable);
setAccountsGroupsColumnManager = (enable) =>
(this.managerAccountsGroupsColumnIsEnabled = enable);
@ -210,6 +213,7 @@ class TableStore {
}
if (getIsAccountsGroups()) {
this.setAccountsGroupsColumnPeople(splitColumns.includes("People"));
this.setAccountsGroupsColumnManager(
splitColumns.includes("Head of Group"),
);
@ -349,6 +353,12 @@ class TableStore {
: this.setRoomColumnQuota(!this.roomQuotaColumnIsEnable);
return;
case "People":
this.setAccountsGroupsColumnPeople(
!this.peopleAccountsGroupsColumnIsEnabled,
);
return;
case "Head of Group":
this.setAccountsGroupsColumnManager(
!this.managerAccountsGroupsColumnIsEnabled,

View File

@ -84,7 +84,10 @@ class ThirdPartyStore {
oauthHref: storage.redirectUrl,
category: storage.name,
requiredConnectionUrl: storage.requiredConnectionUrl,
clientId: storage.clientId,
}));
return res;
};
saveThirdParty = (

View File

@ -98,7 +98,7 @@ const paymentStore = new PaymentStore(
);
const wizardStore = new WizardStore();
const confirmStore = new ConfirmStore();
const backupStore = new BackupStore();
const backupStore = new BackupStore(authStore, thirdPartyStore);
const commonStore = new CommonStore(settingsStore);
const ssoStore = new SsoFormStore();

View File

@ -324,16 +324,11 @@ module.exports = (env, argv) => {
};
}
const remotes = {
client: "client@/remoteEntry.js",
login: "login@/login/remoteEntry.js",
};
config.plugins.push(
new ModuleFederationPlugin({
name: "client",
filename: "remoteEntry.js",
remotes: remotes,
remotes: [],
exposes: {
"./shell": "./src/Shell",
"./store": "./src/store",

View File

@ -110,6 +110,11 @@ export default async function RootLayout({
<head>
<link rel="icon" type="image/x-icon" href="/logo.ashx?logotype=3" />
<link rel="mask-icon" href="/logo.ashx?logotype=3" />
<link
rel="apple-touch-icon"
sizes="32x32"
href="/logo.ashx?logotype=3"
/>
<meta charSet="utf-8" />
<meta
name="viewport"

View File

@ -13,6 +13,7 @@
-->
<link rel="icon" type="image/x-icon" href="/logo.ashx?logotype=3" />
<link rel="mask-icon" href="/logo.ashx?logotype=3" />
<link rel="apple-touch-icon" sizes="32x32" href="/logo.ashx?logotype=3" />
<!-- Tell the browser it's a PWA -->
<!-- <meta name="mobile-web-app-capable" content="yes" /> -->

View File

@ -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 styled, { css } from "styled-components";
import styled from "styled-components";
import { Base } from "../../themes";
import { BackdropProps } from "./Backdrop.types";
@ -33,11 +33,6 @@ const StyledBackdrop = styled.div<BackdropProps & { needBackground: boolean }>`
props.needBackground
? props.theme.backdrop.backgroundColor
: props.theme.backdrop.unsetBackgroundColor};
${(props) =>
props.needBackground &&
css`
backdrop-filter: ${`blur(${props.theme.modalDialog.backdrop.blur}px)`};
`};
display: ${(props) => (props.visible ? "block" : "none")};
height: 100vh;

View File

@ -173,6 +173,7 @@ const ComboBoxPure = (props: ComboboxProps) => {
optionStyle,
style,
withLabel = true,
displayArrow,
} = props;
const { tabIndex, onClickSelectedItem } = props;
@ -297,6 +298,7 @@ const ComboBoxPure = (props: ComboboxProps) => {
isLoading={isLoading}
type={type}
plusBadgeValue={plusBadgeValue}
displayArrow={displayArrow}
/>
{displayType !== "toggle" && (

View File

@ -167,6 +167,7 @@ export interface ComboboxProps {
title?: string;
plusBadgeValue?: number;
withLabel?: boolean;
displayArrow?: boolean;
}
export interface ComboButtonProps {
@ -189,6 +190,7 @@ export interface ComboButtonProps {
isLoading?: boolean;
type?: TCombobox;
plusBadgeValue?: number;
displayArrow?: boolean;
}
export interface ComboButtonThemeProps extends ComboButtonProps {

View File

@ -72,11 +72,12 @@ const ComboButton = (props: ComboButtonProps) => {
modernView = false,
tabIndex = -1,
isLoading = false,
displayArrow: displayArrowProp,
} = props;
const defaultOption = selectedOption?.default;
// const isSelected = selectedOption?.key !== 0;
const displayArrow = withOptions || withAdvancedOptions;
const displayArrow = withOptions || withAdvancedOptions || displayArrowProp;
const comboButtonClassName = `combo-button combo-button_${isOpen ? "open" : "closed"}`;

View File

@ -37,6 +37,7 @@ import { Row } from "./sub-components/Row";
import { DropDownProps } from "./DropDown.types";
import { DEFAULT_PARENT_HEIGHT } from "./DropDown.constants";
import { isIOS, isMobile } from "react-device-detect";
const DropDown = ({
directionY = "bottom",
@ -284,12 +285,25 @@ const DropDown = ({
};
window.addEventListener("resize", documentResizeListener.current);
if (isIOS && isMobile)
window.visualViewport?.addEventListener(
"resize",
documentResizeListener.current,
);
}
}, [checkPosition, checkPositionPortal, isDefaultMode, open]);
const unbindDocumentResizeListener = React.useCallback(() => {
if (documentResizeListener.current) {
window.removeEventListener("resize", documentResizeListener.current);
if (isIOS && isMobile)
window.visualViewport?.removeEventListener(
"resize",
documentResizeListener.current,
);
documentResizeListener.current = null;
}
}, []);

View File

@ -49,14 +49,6 @@ const StyledModal = styled.div<{ modalSwipeOffset?: number; blur?: number }>`
.loader-wrapper {
padding: 0 16px 16px;
}
.modal-backdrop-active {
${(props) =>
props.blur &&
css`
backdrop-filter: blur(${props.blur}px) !important;
`};
}
`;
const Dialog = styled.div`

View File

@ -31,17 +31,6 @@ import { TTheme } from "@docspace/shared/themes";
import { mobile } from "../../../utils";
import { ModalDialogBackdropProps } from "../ModalDialog.types";
const backdropFilter = (props: {
theme: TTheme;
modalSwipeOffset?: number;
}) => {
const blur = props.theme.modalDialog.backdrop.blur;
const swipeOffset = props.modalSwipeOffset;
if (!swipeOffset) return `blur(${blur}px)`;
return `blur(${blur + swipeOffset * (blur / 120)}px)`;
};
const backdropBackground = (props: {
theme: TTheme;
modalSwipeOffset?: number;
@ -56,8 +45,6 @@ const backdropBackground = (props: {
const StyledModalBackdrop = styled.div.attrs(
(props: { theme: TTheme; modalSwipeOffset?: number; zIndex?: number }) => ({
style: {
backdropFilter: backdropFilter(props),
WebkitBackdropFilter: backdropFilter(props),
background: backdropBackground(props),
},
}),

View File

@ -0,0 +1,72 @@
import styled, { css } from "styled-components";
import { Base } from "../../themes";
export const StyledIcon = styled.div<{
size: string;
radius: string;
isArchive?: boolean;
color?: string;
wrongImage: boolean;
}>`
display: flex;
justify-content: center;
align-items: center;
height: ${(props) => props.size};
width: ${(props) => props.size};
.room-background {
height: ${(props) => props.size};
width: ${(props) => props.size};
border-radius: ${(props) => props.radius};
vertical-align: middle;
background: ${(props) =>
props.isArchive
? props.theme.roomIcon.backgroundArchive
: `#${props.color}`};
position: absolute;
opacity: ${(props) => props.theme.roomIcon.opacityBackground};
}
.room-title {
font-size: 14px;
font-weight: 700;
line-height: 16px;
color: ${(props) =>
props.wrongImage && props.theme.isBase ? "#333333" : "#ffffff"};
position: relative;
${(props) =>
!props.theme.isBase &&
!props.isArchive &&
css`
color: ${`#${props.color}`};
`};
}
.room-icon_badge {
position: absolute;
margin-block: 24px 0;
margin-inline: 24px 0;
.room-icon-button {
width: 12px;
height: 12px;
border: ${(props) => `1px solid ${props.theme.backgroundColor}`};
border-radius: 50%;
svg {
path {
fill: ${(props) => props.theme.backgroundColor};
}
rect {
stroke: ${(props) => props.theme.backgroundColor};
}
}
}
}
`;
StyledIcon.defaultProps = { theme: Base };

View File

@ -0,0 +1,29 @@
type RoomIconDefault = {
title: string;
isArchive?: boolean;
size?: string;
radius?: string;
showDefault: boolean;
imgClassName?: string;
className?: string;
};
type RoomIconColor = {
color: string;
imgSrc?: undefined;
imgClassName?: undefined;
};
type RoomIconImage = {
color?: string | undefined;
imgSrc: string;
imgClassName?: string;
};
type RoomIconBadge = { badgeUrl?: string; onBadgeClick?: () => void };
type RoomIconNonBadge = { badgeUrl?: undefined; onBadgeClick?: undefined };
export type RoomIconProps = RoomIconDefault &
(RoomIconColor | RoomIconImage) &
(RoomIconBadge | RoomIconNonBadge);

View File

@ -0,0 +1,30 @@
function Compare(...fns: Array<Function>) {
return (arg: string) => {
return fns.reduce((composed, fn) => fn(composed), arg);
};
}
function removeSpecialSymbol(text: string): string {
return text.replace(/[-_[\]{}()*+!?.,&\\^$|#@%]/g, "");
}
function trim(text: string): string {
return text.replace(/\s+/g, " ").trim();
}
function getFirstAndLastChar(text: string): string {
const [first, ...other] = text.split(" ");
return (first.at(0) ?? "") + (other.at(-1)?.at(0) ?? "");
}
function toUpperCase(text: string) {
return text.toUpperCase();
}
export const getRoomTitle = Compare(
removeSpecialSymbol,
trim,
getFirstAndLastChar,
toUpperCase,
);

View File

@ -24,126 +24,17 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import React from "react";
import React, { useMemo } from "react";
import styled, { css } from "styled-components";
import { Base } from "../../themes";
import { Text } from "../text";
import { IconButton } from "../icon-button";
import { classNames } from "../../utils";
const StyledIcon = styled.div<{
size: string;
radius: string;
isArchive?: boolean;
color?: string;
wrongImage: boolean;
}>`
display: flex;
justify-content: center;
align-items: center;
import { Text } from "../text";
import { IconButton } from "../icon-button";
height: ${(props) => props.size};
import { getRoomTitle } from "./RoomIcon.utils";
import { StyledIcon } from "./RoomIcon.styled";
width: ${(props) => props.size};
.room-background {
height: ${(props) => props.size};
width: ${(props) => props.size};
border-radius: ${(props) => props.radius};
vertical-align: middle;
background: ${(props) =>
props.isArchive
? props.theme.roomIcon.backgroundArchive
: `#${props.color}`};
position: absolute;
opacity: ${(props) => props.theme.roomIcon.opacityBackground};
}
.room-title {
font-size: 14px;
font-weight: 700;
line-height: 16px;
color: ${(props) =>
props.wrongImage && props.theme.isBase ? "#333333" : "#ffffff"};
position: relative;
${(props) =>
!props.theme.isBase &&
!props.isArchive &&
css`
color: ${`#${props.color}`};
`};
}
.room-icon_badge {
position: absolute;
margin-block: 24px 0;
margin-inline: 24px 0;
.room-icon-button {
width: 12px;
height: 12px;
border: ${(props) => `1px solid ${props.theme.backgroundColor}`};
border-radius: 50%;
svg {
path {
fill: ${(props) => props.theme.backgroundColor};
}
rect {
stroke: ${(props) => props.theme.backgroundColor};
}
}
}
}
`;
StyledIcon.defaultProps = { theme: Base };
// interface RoomIconProps {
// title: string;
// isArchive?: boolean;
// color: string;
// size?: string;
// radius?: string;
// showDefault: boolean;
// imgClassName?: string;
// imgSrc?: string;
// }
type RoomIconDefault = {
title: string;
isArchive?: boolean;
size?: string;
radius?: string;
showDefault: boolean;
imgClassName?: string;
className?: string;
};
type RoomIconColor = {
color: string;
imgSrc?: undefined;
imgClassName?: undefined;
};
type RoomIconImage = {
color?: string | undefined;
imgSrc: string;
imgClassName?: string;
};
type RoomIconBadge = { badgeUrl?: string; onBadgeClick?: () => void };
type RoomIconNonBadge = { badgeUrl?: undefined; onBadgeClick?: undefined };
type RoomIconProps = RoomIconDefault &
(RoomIconColor | RoomIconImage) &
(RoomIconBadge | RoomIconNonBadge);
import type { RoomIconProps } from "./RoomIcon.types";
const RoomIcon = ({
title,
@ -160,17 +51,7 @@ const RoomIcon = ({
}: RoomIconProps) => {
const [correctImage, setCorrectImage] = React.useState(true);
const titleWithoutNumberDuplicate = title?.replace(/\(\d+\)/, "");
const titleWithoutSpaces = titleWithoutNumberDuplicate
?.replace(/\s+/g, " ")
?.trim();
const indexAfterLastSpace = titleWithoutSpaces?.lastIndexOf(" ");
const secondCharacter =
!titleWithoutSpaces || indexAfterLastSpace === -1
? ""
: titleWithoutSpaces[indexAfterLastSpace + 1];
const roomTitle = title && (title[0] + secondCharacter).toUpperCase();
const roomTitle = useMemo(() => getRoomTitle(title ?? ""), [title]);
const prefetchImage = React.useCallback(() => {
if (!imgSrc) return;

View File

@ -85,7 +85,6 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({
height: auto;
width: auto;
background: ${(props) => props.theme.infoPanel.blurColor};
backdrop-filter: blur(3px);
z-index: 300;
@media ${tablet} {
z-index: 309;

View File

@ -0,0 +1,30 @@
// (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 DEFAULT_MIN_COLUMN_SIZE = 110;
export const SETTINGS_SIZE = 24;
export const MIN_SIZE_FIRST_COLUMN = 210;
export const TABLE_HEADER_HEIGHT = 40;

View File

@ -24,10 +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
export const MIN_SIZE_FIRST_COLUMN = 210;
export const DEFAULT_MIN_COLUMN_SIZE = 110;
export const SETTINGS_SIZE = 24;
export const HANDLE_OFFSET = 8;
import { SETTINGS_SIZE } from "./Table.constants";
export const getSubstring = (str: string) => +str.substring(0, str.length - 2);

View File

@ -38,14 +38,12 @@ import {
import { TTableColumn, TableHeaderProps } from "./Table.types";
import { TableSettings } from "./sub-components/TableSettings";
import { TableHeaderCell } from "./sub-components/TableHeaderCell";
import { checkingForUnfixedSize, getSubstring } from "./Table.utils";
import {
DEFAULT_MIN_COLUMN_SIZE,
MIN_SIZE_FIRST_COLUMN,
SETTINGS_SIZE,
HANDLE_OFFSET,
checkingForUnfixedSize,
getSubstring,
} from "./Table.utils";
MIN_SIZE_FIRST_COLUMN,
} from "./Table.constants";
import { isDesktop } from "../../utils";
class TableHeaderComponent extends React.Component<

View File

@ -29,7 +29,6 @@ import AvatarBaseReactSvgUrl from "PUBLIC_DIR/images/avatar.base.react.svg?url";
import { globalColors } from "./globalColors";
import { CommonTheme } from "./commonTheme";
import { DEFAULT_FONT_FAMILY } from "../constants";
import { color } from "storybook-static/sb-manager/chunk-INSKDKQB";
export type TColorScheme = {
id: number;
@ -92,6 +91,8 @@ const {
darkRed,
lightErrorStatus,
blurLight,
} = globalColors;
export const getBaseTheme = () => {
@ -1337,7 +1338,7 @@ export const getBaseTheme = () => {
},
backdrop: {
backgroundColor: "rgba(6, 22, 38, 0.2)",
backgroundColor: blurLight,
unsetBackgroundColor: "unset",
},
@ -2069,7 +2070,7 @@ export const getBaseTheme = () => {
sectionHeaderToggleBgActive: grayLight,
backgroundColor: white,
blurColor: "rgba(6, 22, 38, 0.2)",
blurColor: blurLight,
borderColor: grayLightMid,
thumbnailBorderColor: grayLightMid,
textColor: black,
@ -2097,7 +2098,7 @@ export const getBaseTheme = () => {
roleSelectorColor: "#a3a9ae",
disabledRoleSelectorColor: "#a3a9ae",
roleSelectorArrowColor: "#a3a9ae",
createLink: "#a3a9ae",
createLink: black,
linkAccessComboboxExpired: "#a3a9ae",
},

View File

@ -65,6 +65,8 @@ const {
darkErrorStatus,
charlestonGreen,
outerSpace,
blurDark,
} = globalColors;
const Dark: TTheme = {
@ -635,7 +637,7 @@ const Dark: TTheme = {
r: 27,
g: 27,
b: 27,
a: 0.4,
a: 0.6,
},
blur: 9,
},
@ -1305,7 +1307,7 @@ const Dark: TTheme = {
},
backdrop: {
backgroundColor: "rgba(20, 20, 20, 0.8)",
backgroundColor: blurDark,
unsetBackgroundColor: "unset",
},
@ -2041,7 +2043,7 @@ const Dark: TTheme = {
sectionHeaderToggleBgActive: "#292929",
backgroundColor: black,
blurColor: "rgba(20, 20, 20, 0.8)",
blurColor: blurDark,
borderColor: "#474747",
thumbnailBorderColor: grayLightMid,
textColor: white,

View File

@ -47,6 +47,9 @@ export const globalColors = {
lightHover: "#F3F4F4",
veryDarkGrey: "#3D3D3D",
blurLight: "rgba(6, 22, 38, 0.2)",
blurDark: "rgba(27, 27, 27, 0.6)",
blueMain: "#2DA7DB",
blueHover: "#3DB8EC",
blueActive: "#1F97CA",

View File

@ -25,7 +25,6 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
export const INFO_PANEL_WIDTH = 400;
export const TABLE_HEADER_HEIGHT = 40;
export const MAX_INFINITE_LOADER_SHIFT = 800;
export function checkIsSSR() {

View File

@ -513,5 +513,6 @@
"Website": "Website",
"Yes": "Yes",
"Yesterday": "Yesterday",
"You": "You"
"You": "You",
"EnableThirdPartyIntegration": "Please ask a DocSpace owner or administrator to enable the corresponding service in the Integration section of the DocSpace Settings."
}

View File

@ -489,7 +489,7 @@
path = `/doceditor/?fileId=${config.id}&editorType=${config.editorType}&editorGoBack=${goBack}&customization=${customization}`;
if (config.requestToken) {
path = `${path}&share=${config.requestToken}`;
path = `${path}&share=${config.requestToken}&is_file=true`;
}
break;
@ -515,7 +515,7 @@
path = `/doceditor/?fileId=${config.id}&editorType=${config.editorType}&action=view&editorGoBack=${goBack}&customization=${customization}`;
if (config.requestToken) {
path = `${path}&share=${config.requestToken}`;
path = `${path}&share=${config.requestToken}&is_file=true`;
}
break;