Merge pull request #529 from ONLYOFFICE/feature/room-embedding

Web: Files: added embedding settings to the room context menu
This commit is contained in:
Ilya Oleshko 2024-06-27 11:19:22 +03:00 committed by GitHub
commit 24e12cd8e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 85 additions and 78 deletions

View File

@ -6,7 +6,6 @@
"Width": "Width",
"Link": "Link",
"DisplaySettings": "Display settings",
"EmbeddingDescription": "Embed Public room into your website or blog. Apply additional display settings for customizing the embedded content.",
"CodeSuccessfullyCopied": "Code to insert successfully copied to clipboard",
"LinkProtectedWithPassword": "The link is protected with a password.",
"ContentRestricted": "Content copying, file downloading and printing are restricted.",

View File

@ -57,11 +57,6 @@ const StyledBody = styled.div`
}
.embedding-panel_body {
.embedding-panel_description {
color: ${({ theme }) => theme.embeddingPanel.descriptionTextColor};
margin: 18px 0;
}
.embedding-panel_bar {
.embedding-panel_bar-header {
display: flex;

View File

@ -26,11 +26,12 @@
import { useState, useEffect, useCallback, useRef } from "react";
import { inject, observer } from "mobx-react";
import { useNavigate } from "react-router-dom";
import { withTranslation, Trans } from "react-i18next";
import copy from "copy-to-clipboard";
import isEqual from "lodash/isEqual";
import { objectToGetParams } from "@docspace/shared/utils/common";
import { combineUrl } from "@docspace/shared/utils/combineUrl";
import config from "PACKAGE_FILE";
import { Text } from "@docspace/shared/components/text";
import { toastr } from "@docspace/shared/components/toast";
@ -103,7 +104,7 @@ type EmbeddingPanelProps = {
visible: boolean;
setEmbeddingPanelData: (value: {
visible: boolean;
fileId?: string | number;
itemId?: string | number;
}) => void;
setEditLinkPanelIsVisible: (value: boolean) => void;
currentColorScheme: TColorScheme;
@ -111,7 +112,8 @@ type EmbeddingPanelProps = {
setLinkParams: (linkParams: LinkParamsType) => void;
fetchExternalLinks: (roomId: string | number) => LinkParamsLinkType[];
isAdmin: boolean;
fileId?: string | number;
itemId?: string | number;
isRoom: boolean;
};
type TOptionType = TOption & {
@ -130,18 +132,17 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
setLinkParams,
fetchExternalLinks,
isAdmin,
fileId,
itemId,
isRoom,
} = props;
const { roomId, link } = linkParams;
const navigate = useNavigate();
const [sharedLinksOptions, setSharedLinksOptions] = useState<TOptionType[]>(
[],
);
const [selectedLink, setSelectedLink] = useState<TOptionType>();
const [barIsVisible, setBarIsVisible] = useState(!!fileId);
const [barIsVisible, setBarIsVisible] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const dataDimensions = [
@ -164,7 +165,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
height: `${heightValue}${dataDimensions[1].label}`,
frameId: "ds-frame",
init: true,
id: fileId,
id: itemId,
};
const roomConfig = {
@ -190,10 +191,14 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
},
};
const [config, setConfig] = useState(fileId ? fileConfig : roomConfig);
const isFile = itemId && !isRoom;
const params = objectToGetParams(config);
const codeBlock = `<div id="${config.frameId}">Fallback text</div>\n<script src="${SDK_SCRIPT_URL}${params}"></script>`;
const [embeddingConfig, setEmbeddingConfig] = useState(
isFile ? fileConfig : roomConfig,
);
const params = objectToGetParams(embeddingConfig);
const codeBlock = `<div id="${embeddingConfig.frameId}">Fallback text</div>\n<script src="${SDK_SCRIPT_URL}${params}"></script>`;
const currentLink = selectedLink ?? link;
@ -217,7 +222,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
}
const showLinkBar =
selectedLink?.sharedTo?.password || selectedLink?.sharedTo?.denyDownload;
currentLink?.sharedTo?.password || currentLink?.sharedTo?.denyDownload;
const onClose = () => {
setEmbeddingPanelData({ visible: false });
@ -225,28 +230,28 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
const onChangeWidth = (e: React.ChangeEvent<HTMLInputElement>) => {
setWidthValue(e.target.value);
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, width: `${e.target.value}${widthDimension.label}` };
});
};
const onChangeHeight = (e: React.ChangeEvent<HTMLInputElement>) => {
setHeightValue(e.target.value);
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, height: `${e.target.value}${heightDimension.label}` };
});
};
const onChangeWidthDimension = (item: TOption) => {
setWidthDimension(item);
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, width: `${widthValue}${item.label}` };
});
};
const onChangeHeightDimension = (item: TOption) => {
setHeightDimension(item);
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, height: `${heightValue}${item.label}` };
});
};
@ -257,13 +262,13 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
};
const onHeaderChange = () => {
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, showTitle: !config.showTitle };
});
};
const onTitleChange = () => {
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, showFilter: !config.showFilter };
});
};
@ -280,7 +285,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
const onChangeSharedLink = (item: TOptionType) => {
setSelectedLink(item);
setConfig((config) => {
setEmbeddingConfig((config) => {
return { ...config, requestToken: item?.sharedTo?.requestToken };
});
};
@ -290,8 +295,14 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
};
const onOpenDevTools = () => {
navigate("/portal-settings/developer-tools");
onClose();
const url = combineUrl(
window.location.origin,
window.ClientConfig?.proxy?.url,
config.homepage,
"/portal-settings/developer-tools",
);
window.open(url, "_blank");
};
const onKeyPress = (e: KeyboardEvent) => {
@ -332,10 +343,10 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
}, [roomId, fetchExternalLinks]);
useEffect(() => {
if (fileId) {
if (itemId) {
getLinks();
}
}, [fileId, getLinks]);
}, [itemId, getLinks]);
const usePrevious = (value: LinkParamsLinkType | null) => {
const ref = useRef<LinkParamsLinkType | null>();
@ -431,12 +442,6 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
</div>
)}
<div className="embedding-panel_body">
{!fileId && (
<Text fontSize="12px" className="embedding-panel_description">
{t("EmbeddingPanel:EmbeddingDescription")}
</Text>
)}
{sharedLinksOptions && sharedLinksOptions.length > 1 && (
<>
<Text
@ -492,7 +497,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
/>
</div>
{!fileId && (
{!isFile && (
<>
<Text
className="embedding-panel_header-text"
@ -506,7 +511,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
<CheckboxElement
label={t("Common:Title")}
onChange={onHeaderChange}
isChecked={config.showTitle}
isChecked={embeddingConfig.showTitle}
img={theme.isBase ? HeaderUrl : HeaderDarkUrl}
title={t("JavascriptSdk:Header")}
description={t("JavascriptSdk:HeaderDescription")}
@ -514,7 +519,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
<CheckboxElement
label={t("JavascriptSdk:SearchFilterAndSort")}
onChange={onTitleChange}
isChecked={config.showFilter}
isChecked={embeddingConfig.showFilter}
img={theme.isBase ? SearchUrl : SearchDarkUrl}
title={t("JavascriptSdk:SearchBlock")}
description={t(
@ -567,18 +572,8 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
);
};
export default inject(
({
dialogsStore,
settingsStore,
userStore,
publicRoomStore,
}: {
dialogsStore: DialogsStore;
settingsStore: SettingsStore;
userStore: UserStore;
publicRoomStore: PublicRoomStore;
}) => {
export default inject<TStore>(
({ dialogsStore, settingsStore, userStore, publicRoomStore }) => {
const {
embeddingPanelData,
setEmbeddingPanelData,
@ -594,7 +589,8 @@ export default inject(
theme,
currentColorScheme,
visible: embeddingPanelData.visible,
fileId: embeddingPanelData.fileId,
itemId: embeddingPanelData.item?.id,
isRoom: embeddingPanelData.item?.isRoom,
setEmbeddingPanelData,
setEditLinkPanelIsVisible,
linkParams,

View File

@ -27,7 +27,6 @@
import ClearTrashReactSvgUrl from "PUBLIC_DIR/images/clear.trash.react.svg?url";
import ReconnectSvgUrl from "PUBLIC_DIR/images/reconnect.svg?url";
import SettingsReactSvgUrl from "PUBLIC_DIR/images/catalog.settings.react.svg?url";
import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url";
import DownloadReactSvgUrl from "PUBLIC_DIR/images/download.react.svg?url";
import MoveReactSvgUrl from "PUBLIC_DIR/images/move.react.svg?url";
import RenameReactSvgUrl from "PUBLIC_DIR/images/rename.react.svg?url";
@ -45,6 +44,7 @@ import PublicRoomIconUrl from "PUBLIC_DIR/images/public-room.react.svg?url";
import LeaveRoomSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
import React from "react";
import { inject, observer } from "mobx-react";
@ -290,6 +290,7 @@ const SectionHeaderContent = (props) => {
startUpload,
getFolderModel,
onCreateRoom,
onOpenEmbeddingSettings,
} = props;
const navigate = useNavigate();
@ -589,11 +590,20 @@ const SectionHeaderContent = (props) => {
onClick: () => onClickEditRoom(selectedFolder),
disabled: !isRoom || !security?.EditRoom,
},
{
id: "header_option_invite-users-to-room",
key: "invite-users-to-room",
label: t("Common:InviteUsers"),
icon: PersonReactSvgUrl,
onClick: () =>
onClickInviteUsers(selectedFolder.id, selectedFolder.roomType),
disabled: !isRoom || !security?.EditAccess,
},
{
id: "header_option_copy-external-link",
key: "copy-external-link",
label: t("Files:CopySharedLink"),
icon: CopyToReactSvgUrl,
icon: TabletLinkReactSvgUrl,
onClick: async () => {
if (primaryLink) {
copyShareLink(primaryLink.sharedTo.shareLink);
@ -613,13 +623,12 @@ const SectionHeaderContent = (props) => {
isArchive,
},
{
id: "header_option_invite-users-to-room",
key: "invite-users-to-room",
label: t("Common:InviteUsers"),
icon: PersonReactSvgUrl,
onClick: () =>
onClickInviteUsers(selectedFolder.id, selectedFolder.roomType),
disabled: !isRoom || !security?.EditAccess,
id: "header_option_room-embed",
key: "room-embed",
label: t("Files:Embed"),
icon: CodeReactSvgUrl,
onClick: () => onOpenEmbeddingSettings(selectedFolder),
disabled: !security?.Embed,
},
{
id: "header_option_room-info",
@ -635,6 +644,14 @@ const SectionHeaderContent = (props) => {
isSeparator: true,
disabled: isRecycleBinFolder,
},
{
id: "header_option_download",
key: "download",
label: t("Common:Download"),
onClick: onDownloadAction,
disabled: !security?.Download,
icon: DownloadReactSvgUrl,
},
{
id: "header_option_archive-room",
key: "archive-room",
@ -663,14 +680,6 @@ const SectionHeaderContent = (props) => {
onClick: onLeaveRoom,
disabled: isArchive || !inRoom || isPublicRoom,
},
{
id: "header_option_download",
key: "download",
label: t("Common:Download"),
onClick: onDownloadAction,
disabled: !security?.Download,
icon: DownloadReactSvgUrl,
},
{
id: "header_option_unarchive-room",
key: "unarchive-room",
@ -1178,6 +1187,7 @@ export default inject(
onCreateAndCopySharedLink,
getFolderModel,
onCreateRoom,
onOpenEmbeddingSettings,
} = contextOptionsStore;
const canRestoreAll = isArchiveFolder && roomsForRestore.length > 0;
@ -1361,6 +1371,7 @@ export default inject(
onClickReconnectStorage,
getFolderModel,
onCreateRoom,
onOpenEmbeddingSettings,
};
},
)(

View File

@ -449,9 +449,11 @@ class ContextOptionsStore {
this.selectedFolderStore;
const { setLinkParams, setEmbeddingPanelData } = this.dialogsStore;
const sharedItem = shared
? getSelectedFolder()
: navigationPath.find((r) => r.shared);
const sharedItem = item.isRoom
? item
: shared
? getSelectedFolder()
: navigationPath.find((r) => r.shared);
if (!sharedItem) return;
@ -464,7 +466,7 @@ class ContextOptionsStore {
isFormRoom,
});
setEmbeddingPanelData({ visible: true, fileId: item.id });
setEmbeddingPanelData({ visible: true, item });
};
onCreateAndCopySharedLink = async (item, t) => {

View File

@ -103,7 +103,7 @@ class DialogsStore {
createRoomConfirmDialogVisible = false;
changeUserTypeDialogVisible = false;
editLinkPanelIsVisible = false;
embeddingPanelData = { visible: false, fileId: null };
embeddingPanelData = { visible: false, item: null };
submitToGalleryDialogVisible = false;
linkParams = null;
leaveRoomDialogVisible = false;

View File

@ -1606,6 +1606,7 @@ class FilesStore {
folders: data.folders,
...data.current,
inRoom: !!data.current.inRoom,
isRoom: !!data.current.roomType,
pathParts: data.pathParts,
navigationPath,
...{ new: data.new },
@ -2029,6 +2030,7 @@ class FilesStore {
const canCopy = item.security?.Copy;
const canDuplicate = item.security?.Duplicate;
const canDownload = item.security?.Download;
const canEmbed = item.security?.Embed;
if (isFile) {
const shouldFillForm = item.viewAccessibility.WebRestrictedEditing;
@ -2193,10 +2195,7 @@ class FilesStore {
}
if (!canViewFile || isRecycleBinFolder) {
fileOptions = this.removeOptions(fileOptions, [
"preview",
"embedding-settings",
]);
fileOptions = this.removeOptions(fileOptions, ["preview"]);
}
if (!canOpenPlayer || isRecycleBinFolder) {
@ -2328,7 +2327,7 @@ class FilesStore {
]);
}
if (this.publicRoomStore.isPublicRoom) {
if (this.publicRoomStore.isPublicRoom || !canEmbed) {
fileOptions = this.removeOptions(fileOptions, ["embedding-settings"]);
}
@ -2375,6 +2374,7 @@ class FilesStore {
"edit-room",
"invite-users-to-room",
"external-link",
"embedding-settings",
"room-info",
"pin-room",
"unpin-room",
@ -2443,6 +2443,10 @@ class FilesStore {
: (roomOptions = this.removeOptions(roomOptions, ["unmute-room"]));
}
if (this.publicRoomStore.isPublicRoom || !canEmbed) {
roomOptions = this.removeOptions(roomOptions, ["embedding-settings"]);
}
if (!canViewRoomInfo) {
roomOptions = this.removeOptions(roomOptions, ["room-info"]);
}