Web: Files: added document embedding

This commit is contained in:
Nikita Gopienko 2024-05-30 18:35:14 +03:00
parent 7d8cb75c93
commit 2779f4c0b8
9 changed files with 170 additions and 116 deletions

View File

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

View File

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

View File

@ -40,7 +40,6 @@ import LinkBlock from "./LinkBlock";
import ToggleBlock from "./ToggleBlock";
import PasswordAccessBlock from "./PasswordAccessBlock";
import LimitTimeBlock from "./LimitTimeBlock";
import { RoomsType } from "@docspace/shared/enums";
import { DeviceType } from "@docspace/shared/enums";
import moment from "moment";
@ -130,7 +129,7 @@ const EditLinkPanel = (props) => {
editExternalLink(roomId, newLink)
.then((link) => {
setExternalLink(link);
setLinkParams({ link, roomId });
setLinkParams({ link, roomId, isPublic });
if (isEdit) {
copy(linkValue);
@ -299,14 +298,7 @@ const EditLinkPanel = (props) => {
};
export default inject(
({
authStore,
settingsStore,
dialogsStore,
publicRoomStore,
infoPanelStore,
}) => {
const { infoPanelSelection } = infoPanelStore;
({ authStore, settingsStore, dialogsStore, publicRoomStore }) => {
const {
editLinkPanelIsVisible,
setEditLinkPanelIsVisible,
@ -317,13 +309,12 @@ export default inject(
} = dialogsStore;
const { externalLinks, editExternalLink, setExternalLink } =
publicRoomStore;
const { isEdit } = linkParams;
const { isEdit, roomId, isPublic } = linkParams;
const linkId = linkParams?.link?.sharedTo?.id;
const link = externalLinks.find((l) => l?.sharedTo?.id === linkId);
const shareLink = link?.sharedTo?.shareLink;
const isPublic = infoPanelSelection?.roomType === RoomsType.PublicRoom;
return {
visible: editLinkPanelIsVisible,
@ -331,7 +322,7 @@ export default inject(
isEdit,
linkId: link?.sharedTo?.id,
editExternalLink,
roomId: infoPanelSelection.id,
roomId,
setExternalLink,
isLocked: !!link?.sharedTo?.password,
password: link?.sharedTo?.password ?? "",

View File

@ -73,7 +73,7 @@ const StyledBody = styled.div`
}
.embedding-panel_bar {
margin: 23px 0px 21px 0px;
margin-bottom: 21px;
.embedding-panel_bar-header {
display: flex;

View File

@ -85,12 +85,13 @@ type LinkParamsLinkType = {
canEditAccess: boolean;
isLocked: boolean;
isOwner: boolean;
sharedTo: LinkParamsLinkShareToType;
sharedTo?: LinkParamsLinkShareToType;
subjectType: number;
};
type LinkParamsType = {
roomId?: number;
roomId?: number | string;
fileId?: number | string;
isEdit?: boolean;
link: LinkParamsLinkType;
};
@ -123,13 +124,14 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
setLinkParams,
} = props;
const { roomId, link } = linkParams;
const {
requestToken,
title: linkTitle,
password: withPassword,
denyDownload,
} = link.sharedTo;
const { roomId, link, fileId } = linkParams;
const requestToken = link?.sharedTo?.requestToken;
const linkTitle = link?.sharedTo?.title;
const withPassword = link?.sharedTo?.password;
const denyDownload = link?.sharedTo?.denyDownload;
const withToken = !!requestToken;
const dataDimensions = [
{ key: "percent", label: "%", default: true },
@ -140,25 +142,32 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
const [widthDimension, setWidthDimension] = useState<TOption>(
dataDimensions[0],
);
const [heightValue, setHeightValue] = useState("820");
const [heightValue, setHeightValue] = useState("100");
const [heightDimension, setHeightDimension] = useState<TOption>(
dataDimensions[1],
);
const [config, setConfig] = useState({
const fileConfig = {
mode: "manager",
width: "100%",
height: "100%",
frameId: "ds-frame",
init: true,
id: fileId,
requestToken: withToken ? requestToken : null,
};
const roomConfig = {
width: `${widthValue}${dataDimensions[0].label}`,
height: `${heightValue}${dataDimensions[1].label}`,
height: `${heightValue}${dataDimensions[0].label}`,
frameId: "ds-frame",
showHeader: true,
showTitle: true,
showMenu: false,
showFilter: true,
//
mode: "manager",
init: true,
requestToken,
//
rootPath: "/rooms/share",
id: roomId,
filter: {
@ -169,7 +178,9 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
search: "",
withSubfolders: false,
},
});
};
const [config, setConfig] = useState(fileId ? fileConfig : roomConfig);
const scriptUrl = `${window.location.origin}/static/scripts/api.js`;
const params = objectToGetParams(config);
@ -230,8 +241,8 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
};
const onEditLink = () => {
setLinkParams({ ...linkParams, isEdit: true });
setEditLinkPanelIsVisible(true);
setLinkParams({ isEdit: true, link });
};
const onKeyPress = (e: KeyboardEvent) =>
@ -239,14 +250,13 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
useEffect(() => {
if (scrollRef.current) scrollRef.current?.contentElement?.focus();
}, []);
useEffect(() => {
document.addEventListener("keyup", onKeyPress);
return () => document.removeEventListener("keyup", onKeyPress);
});
console.log("Embedding config", config);
const barTitle = (
<div className="embedding-panel_bar-header">
<Link
@ -280,7 +290,7 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
barSubTitle = contentRestrictedTitle;
}
const showLinkBar = withPassword || denyDownload;
const showLinkBar = (withPassword || denyDownload) && !fileId;
const embeddingPanelComponent = (
<StyledEmbeddingPanel>
@ -299,9 +309,11 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
<StyledScrollbar ref={scrollRef}>
<StyledBody>
<div className="embedding-panel_body">
<Text className="embedding-panel_description">
{t("EmbeddingPanel:EmbeddingDescription")}
</Text>
{!fileId && (
<Text className="embedding-panel_description">
{t("EmbeddingPanel:EmbeddingDescription")}
</Text>
)}
{showLinkBar && (
<PublicRoomBar
@ -337,32 +349,38 @@ const EmbeddingPanelComponent = (props: EmbeddingPanelProps) => {
/>
</div>
<Text
className="embedding-panel_header-text"
fontSize="15px"
fontWeight={600}
>
{t("JavascriptSdk:InterfaceElements")}:
</Text>
{!fileId && (
<>
<Text
className="embedding-panel_header-text"
fontSize="15px"
fontWeight={600}
>
{t("JavascriptSdk:InterfaceElements")}:
</Text>
<div className="embedding-panel_checkbox-container">
<CheckboxElement
label={t("Common:Title")}
onChange={onHeaderChange}
isChecked={config.showHeader}
img={theme.isBase ? HeaderUrl : HeaderDarkUrl}
title={t("JavascriptSdk:Header")}
description={t("JavascriptSdk:HeaderDescription")}
/>
<CheckboxElement
label={t("JavascriptSdk:SearchFilterAndSort")}
onChange={onTitleChange}
isChecked={config.showTitle}
img={theme.isBase ? SearchUrl : SearchDarkUrl}
title={t("JavascriptSdk:SearchBlock")}
description={t("JavascriptSdk:ManagerSearchBlockDescription")}
/>
</div>
<div className="embedding-panel_checkbox-container">
<CheckboxElement
label={t("Common:Title")}
onChange={onHeaderChange}
isChecked={config.showHeader}
img={theme.isBase ? HeaderUrl : HeaderDarkUrl}
title={t("JavascriptSdk:Header")}
description={t("JavascriptSdk:HeaderDescription")}
/>
<CheckboxElement
label={t("JavascriptSdk:SearchFilterAndSort")}
onChange={onTitleChange}
isChecked={config.showTitle}
img={theme.isBase ? SearchUrl : SearchDarkUrl}
title={t("JavascriptSdk:SearchBlock")}
description={t(
"JavascriptSdk:ManagerSearchBlockDescription",
)}
/>
</div>
</>
)}
<div className="embedding-panel_code-container">
<Text
@ -439,8 +457,6 @@ export default inject(
} = dialogsStore;
const { theme, currentColorScheme, currentDeviceType } = settingsStore;
console.log("linkParams", linkParams);
return {
theme,
currentDeviceType,

View File

@ -90,33 +90,33 @@ const LinkRow = (props) => {
const onEditLink = () => {
setEditLinkPanelIsVisible(true);
setLinkParams({ isEdit: true, link });
setLinkParams({ isEdit: true, link, roomId, isPublic: isPublicRoomType });
onCloseContextMenu();
};
const onDisableLink = () => {
if (isExpired) {
setEditLinkPanelIsVisible(true);
setLinkParams({ isEdit: true, link });
return;
}
// const onDisableLink = () => {
// if (isExpired) {
// setEditLinkPanelIsVisible(true);
// setLinkParams({ isEdit: true, link, roomId, isPublic: isPublicRoomType });
// return;
// }
setIsLoading(true);
// setIsLoading(true);
const newLink = JSON.parse(JSON.stringify(link));
newLink.sharedTo.disabled = !newLink.sharedTo.disabled;
// const newLink = JSON.parse(JSON.stringify(link));
// newLink.sharedTo.disabled = !newLink.sharedTo.disabled;
editExternalLink(roomId, newLink)
.then((link) => {
setExternalLink(link);
// editExternalLink(roomId, newLink)
// .then((link) => {
// setExternalLink(link);
disabled
? toastr.success(t("Files:LinkEnabledSuccessfully"))
: toastr.success(t("Files:LinkDisabledSuccessfully"));
})
.catch((err) => toastr.error(err?.message))
.finally(() => setIsLoading(false));
};
// disabled
// ? toastr.success(t("Files:LinkEnabledSuccessfully"))
// : toastr.success(t("Files:LinkDisabledSuccessfully"));
// })
// .catch((err) => toastr.error(err?.message))
// .finally(() => setIsLoading(false));
// };
const onCopyPassword = () => {
copy(password);
@ -124,13 +124,13 @@ const LinkRow = (props) => {
};
const onEmbeddingClick = () => {
setLinkParams({ link, roomId });
setLinkParams({ link, roomId, isPublic: isPublicRoomType });
setEmbeddingPanelIsVisible(true);
onCloseContextMenu();
};
const onDeleteLink = () => {
setLinkParams({ link });
setLinkParams({ link, roomId, isPublic: isPublicRoomType });
setDeleteLinkDialogVisible(true);
onCloseContextMenu();
};

View File

@ -80,6 +80,7 @@ import FormGalleryReactSvgUrl from "PUBLIC_DIR/images/form.gallery.react.svg?url
import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg?url";
import ActionsUploadReactSvgUrl from "PUBLIC_DIR/images/actions.upload.react.svg?url";
import PluginMoreReactSvgUrl from "PUBLIC_DIR/images/plugin.more.react.svg?url";
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
import { getCategoryUrl } from "@docspace/client/src/helpers/utils";
@ -442,6 +443,41 @@ class ContextOptionsStore {
toastr.success(t("Translations:LinkCopySuccess"));
};
onOpenEmbeddingSettings = async (item) => {
const { shared, navigationPath, getSelectedFolder } =
this.selectedFolderStore;
const { setLinkParams, setEmbeddingPanelIsVisible } = this.dialogsStore;
if (item.canShare) {
setLinkParams({ fileId: item.id });
setEmbeddingPanelIsVisible(true);
} else {
const sharedItem = shared
? getSelectedFolder()
: navigationPath.find((r) => r.shared);
if (!sharedItem) return;
const roomId = sharedItem?.id;
try {
const itemLink = await getFileLink(item.id);
const isPublicRoomType = sharedItem.roomType === RoomsType.PublicRoom;
setLinkParams({
link: itemLink,
roomId,
fileId: item.id,
isPublic: isPublicRoomType,
});
setEmbeddingPanelIsVisible(true);
} catch (error) {
toastr.error(error);
}
}
};
onCreateAndCopySharedLink = async (item, t) => {
const primaryLink = await this.filesStore.getPrimaryLink(item.id);
@ -1227,14 +1263,14 @@ class ContextOptionsStore {
item.roomType === RoomsType.PublicRoom ||
item.roomType === RoomsType.CustomRoom;
const { shared, navigationPath } = this.selectedFolderStore;
if (item.isRoom && withOpen) {
withOpen =
this.selectedFolderStore.navigationPath.findIndex(
(f) => f.id === item.id,
) === -1;
withOpen = navigationPath.findIndex((f) => f.id === item.id) === -1;
}
const isArchive = item.rootFolderType === FolderType.Archive;
const isShared = shared || navigationPath.findIndex((r) => r.shared) > -1;
const optionsModel = [
{
@ -1440,6 +1476,14 @@ class ContextOptionsStore {
// icon: MailReactSvgUrl,
// disabled: emailSendIsDisabled,
// },
{
id: "option_embedding-setting",
key: "embedding-settings",
label: t("Files:Embed"),
icon: CodeReactSvgUrl,
onClick: () => this.onOpenEmbeddingSettings(item),
disabled: (!item.canShare && !isShared) || isArchive,
},
{
id: "option_show-info",
key: "show-info",

View File

@ -2006,6 +2006,7 @@ class FilesStore {
"separator-SubmitToGallery",
"link-for-room-members",
"sharing-settings",
"embedding-settings",
// "external-link",
"owner-change",
// "link-for-portal-users",
@ -2265,6 +2266,10 @@ class FilesStore {
]);
}
if (this.publicRoomStore.isPublicRoom) {
fileOptions = this.removeOptions(fileOptions, ["embedding-settings"]);
}
// if (isPrivacyFolder) {
// fileOptions = this.removeOptions(fileOptions, [
// "preview",

View File

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

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 757 B