Merge branch 'develop' into bugfix/new-selector

This commit is contained in:
Timofey Boyko 2023-08-18 14:29:18 +03:00
commit 7b74c280ea
30 changed files with 205 additions and 86 deletions

View File

@ -25,6 +25,9 @@
"DisableNotifications": "Disable notifications", "DisableNotifications": "Disable notifications",
"Document": "Document", "Document": "Document",
"DocumentEdited": "Cannot perform the action because the document is being edited.", "DocumentEdited": "Cannot perform the action because the document is being edited.",
"PasswordLink": " Add a password to protect your link.",
"ChooseExpirationDate": "Limit availability period for this link by setting an expiration date.",
"PreventDownloadFilesAndFolders": "Disable downloads of files and folders from this room to secure your data.",
"EditRoom": "Edit room", "EditRoom": "Edit room",
"EmptyFile": "Empty file", "EmptyFile": "Empty file",
"EmptyFilterDescriptionText": "No files or folders match this filter. Try a different one or clear filter to view all files. ", "EmptyFilterDescriptionText": "No files or folders match this filter. Try a different one or clear filter to view all files. ",
@ -138,6 +141,7 @@
"ShareRoom": "Share room", "ShareRoom": "Share room",
"DownloadAll": "Download all", "DownloadAll": "Download all",
"PublicRoom": "Public room", "PublicRoom": "Public room",
"RoomAvailableViaExternalLink": "Room available via external link",
"PasswordSuccessfullyCopied": "Password successfully copied", "PasswordSuccessfullyCopied": "Password successfully copied",
"LinkAddedSuccessfully": "Link added successfully", "LinkAddedSuccessfully": "Link added successfully",
"MoveToPublicRoomTitle": "Move to Public room", "MoveToPublicRoomTitle": "Move to Public room",
@ -149,5 +153,8 @@
"LinkValidUntil": "This link will be valid until", "LinkValidUntil": "This link will be valid until",
"NoExternalLinks": "No external links", "NoExternalLinks": "No external links",
"AllLinksAreDisabled": "All links are disabled", "AllLinksAreDisabled": "All links are disabled",
"MaximumNumberOfExternalLinksCreated": "Maximum number of external links created" "MaximumNumberOfExternalLinksCreated": "Maximum number of external links created",
"AddNewExternalLink": "Add new external link",
"CopyLinkPassword": "Copy link password",
"ShowLinkActions": "Show link actions"
} }

View File

@ -73,7 +73,6 @@ const withLoader = (WrappedComponent) => (Loader) => {
isLoadingFilesFind, isLoadingFilesFind,
isInit: isPublicRoom ? true : isInit, isInit: isPublicRoom ? true : isInit,
showBodyLoader, showBodyLoader,
isPublicRoom,
accountsViewAs, accountsViewAs,
}; };
} }

View File

@ -27,6 +27,7 @@ export type Item = {
isFolder: boolean; isFolder: boolean;
isDisabled?: boolean; isDisabled?: boolean;
security: Security; security: Security;
roomType: number;
}; };
export type BreadCrumb = { export type BreadCrumb = {
@ -89,6 +90,7 @@ export type FilesSelectorProps = {
withoutImmediatelyClose: boolean; withoutImmediatelyClose: boolean;
isThirdParty: boolean; isThirdParty: boolean;
isEditorDialog: boolean; isEditorDialog: boolean;
setMoveToPublicRoomVisible: (visible: boolean, operationData: object) => void;
onClose?: () => void; onClose?: () => void;

View File

@ -352,12 +352,14 @@ export const useFilesHelper = ({
pathParts.map(async (folderId: number | string) => { pathParts.map(async (folderId: number | string) => {
const folderInfo: any = await getFolderInfo(folderId); const folderInfo: any = await getFolderInfo(folderId);
const { title, id, parentId, rootFolderType } = folderInfo; const { title, id, parentId, rootFolderType, roomType } =
folderInfo;
return { return {
label: title, label: title,
id: id, id: id,
isRoom: parentId === 0 && rootFolderType === FolderType.Rooms, isRoom: parentId === 0 && rootFolderType === FolderType.Rooms,
roomType,
}; };
}) })
); );

View File

@ -23,6 +23,10 @@ const getRoomLogo = (roomType: number) => {
case RoomsType.EditingRoom: case RoomsType.EditingRoom:
path = "editing.svg"; path = "editing.svg";
break; break;
case RoomsType.PublicRoom:
path = "public.svg";
break;
} }
return iconSize32.get(path); return iconSize32.get(path);
@ -55,6 +59,7 @@ const convertRoomsToItems = (rooms: any) => {
parentId, parentId,
rootFolderType, rootFolderType,
isFolder: true, isFolder: true,
roomType,
}; };
}); });

View File

@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next";
// @ts-ignore // @ts-ignore
import Loaders from "@docspace/common/components/Loaders"; import Loaders from "@docspace/common/components/Loaders";
import { FolderType } from "@docspace/common/constants"; import { FolderType, RoomsType } from "@docspace/common/constants";
import Aside from "@docspace/components/aside"; import Aside from "@docspace/components/aside";
import Backdrop from "@docspace/components/backdrop"; import Backdrop from "@docspace/components/backdrop";
@ -84,6 +84,7 @@ const FilesSelector = ({
setSelectedItems, setSelectedItems,
includeFolder, includeFolder,
setMoveToPublicRoomVisible,
}: FilesSelectorProps) => { }: FilesSelectorProps) => {
const { t } = useTranslation(["Files", "Common", "Translations"]); const { t } = useTranslation(["Files", "Common", "Translations"]);
@ -177,6 +178,7 @@ const FilesSelector = ({
id: item.id, id: item.id,
isRoom: isRoom:
item.parentId === 0 && item.rootFolderType === FolderType.Rooms, item.parentId === 0 && item.rootFolderType === FolderType.Rooms,
roomType: item.roomType,
}, },
]); ]);
setSelectedItemId(item.id); setSelectedItemId(item.id);
@ -295,6 +297,10 @@ const FilesSelector = ({
fileName: string, fileName: string,
isChecked: boolean isChecked: boolean
) => { ) => {
const isPublic =
breadCrumbs.findIndex((f: any) => f.roomType === RoomsType.PublicRoom) >
-1;
if ((isMove || isCopy || isRestoreAll) && !isEditorDialog) { if ((isMove || isCopy || isRestoreAll) && !isEditorDialog) {
const folderTitle = breadCrumbs[breadCrumbs.length - 1].label; const folderTitle = breadCrumbs[breadCrumbs.length - 1].label;
@ -332,6 +338,11 @@ const FilesSelector = ({
}, },
}; };
if (isPublic) {
setMoveToPublicRoomVisible(true, operationData);
return;
}
setIsRequestRunning(true); setIsRequestRunning(true);
setSelectedItems(); setSelectedItems();
checkFileConflicts(selectedItemId, folderIds, fileIds) checkFileConflicts(selectedItemId, folderIds, fileIds)
@ -548,6 +559,7 @@ export default inject(
conflictResolveDialogVisible, conflictResolveDialogVisible,
isFolderActions, isFolderActions,
setIsFolderActions, setIsFolderActions,
setMoveToPublicRoomVisible,
} = dialogsStore; } = dialogsStore;
const { theme } = auth.settingsStore; const { theme } = auth.settingsStore;
@ -608,6 +620,7 @@ export default inject(
setIsFolderActions, setIsFolderActions,
setSelectedItems, setSelectedItems,
includeFolder, includeFolder,
setMoveToPublicRoomVisible,
}; };
} }
)(observer(FilesSelector)); )(observer(FilesSelector));

View File

@ -92,13 +92,13 @@ const ThirdPartyStorage = ({
return ( return (
<StyledThirdPartyStorage> <StyledThirdPartyStorage>
<ToggleParam {/* <ToggleParam
id="shared_third-party-storage-toggle" id="shared_third-party-storage-toggle"
title={t("Common:ThirdPartyStorage")} title={t("Common:ThirdPartyStorage")}
description={t("ThirdPartyStorageDescription")} description={t("ThirdPartyStorageDescription")}
isChecked={storageLocation.isThirdparty} isChecked={storageLocation.isThirdparty}
onCheckedChange={onChangeIsThirdparty} onCheckedChange={onChangeIsThirdparty}
/> /> */}
{storageLocation.isThirdparty && ( {storageLocation.isThirdparty && (
<ThirdPartyComboBox <ThirdPartyComboBox
@ -137,11 +137,8 @@ const ThirdPartyStorage = ({
export default inject(({ auth, settingsStore, dialogsStore }) => { export default inject(({ auth, settingsStore, dialogsStore }) => {
const { currentColorScheme } = auth.settingsStore; const { currentColorScheme } = auth.settingsStore;
const { const { openConnectWindow, saveThirdParty, deleteThirdParty } =
openConnectWindow, settingsStore.thirdPartyStore;
saveThirdParty,
deleteThirdParty,
} = settingsStore.thirdPartyStore;
const { const {
setConnectItem, setConnectItem,

View File

@ -25,6 +25,7 @@ const MoveToPublicRoomComponent = (props) => {
setMovingInProgress, setMovingInProgress,
itemOperationToFolder, itemOperationToFolder,
clearActiveOperations, clearActiveOperations,
setSelectedItems,
} = props; } = props;
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@ -69,6 +70,7 @@ const MoveToPublicRoomComponent = (props) => {
setIsLoading(true); setIsLoading(true);
}, 500); }, 500);
setSelectedItems();
checkFileConflicts(destFolderId, folderIds, fileIds) checkFileConflicts(destFolderId, folderIds, fileIds)
.then(async (conflicts) => { .then(async (conflicts) => {
if (conflicts.length) { if (conflicts.length) {
@ -153,7 +155,8 @@ export default inject(
moveToPublicRoomData, moveToPublicRoomData,
} = dialogsStore; } = dialogsStore;
const { setConflictDialogData, checkFileConflicts } = filesActionsStore; const { setConflictDialogData, checkFileConflicts, setSelectedItems } =
filesActionsStore;
const { itemOperationToFolder, clearActiveOperations } = uploadDataStore; const { itemOperationToFolder, clearActiveOperations } = uploadDataStore;
return { return {
@ -169,6 +172,7 @@ export default inject(
setMovingInProgress, setMovingInProgress,
itemOperationToFolder, itemOperationToFolder,
clearActiveOperations, clearActiveOperations,
setSelectedItems,
}; };
} }
)(observer(MoveToPublicRoomDialog)); )(observer(MoveToPublicRoomDialog));

View File

@ -9,6 +9,7 @@ const LimitTimeBlock = (props) => {
setExpirationDate, setExpirationDate,
setIsExpired, setIsExpired,
isExpired, isExpired,
language,
} = props; } = props;
const onChange = (date) => { const onChange = (date) => {
@ -35,6 +36,7 @@ const LimitTimeBlock = (props) => {
minDate={minDate} minDate={minDate}
openDate={new Date()} openDate={new Date()}
hasError={isExpired} hasError={isExpired}
locale={language}
/> />
</ToggleBlock> </ToggleBlock>
); );

View File

@ -86,7 +86,7 @@ const PasswordAccessBlock = (props) => {
isDisabled={isLoading} isDisabled={isLoading}
onClick={onCleanClick} onClick={onCleanClick}
> >
{t("Clean")} {t("Files:Clean")}
</Link> </Link>
<Link <Link
fontSize="13px" fontSize="13px"
@ -96,7 +96,7 @@ const PasswordAccessBlock = (props) => {
isDisabled={isLoading} isDisabled={isLoading}
onClick={onCopyClick} onClick={onCopyClick}
> >
{t("CopyPassword")} {t("Files:CopyPassword")}
</Link> </Link>
</div> </div>
</div> </div>

View File

@ -42,6 +42,7 @@ const EditLinkPanel = (props) => {
isDenyDownload, isDenyDownload,
link, link,
date, date,
language,
} = props; } = props;
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@ -219,6 +220,7 @@ const EditLinkPanel = (props) => {
expirationDate={expirationDate} expirationDate={expirationDate}
setExpirationDate={setExpirationDate} setExpirationDate={setExpirationDate}
setIsExpired={setIsExpired} setIsExpired={setIsExpired}
language={language}
/> />
</div> </div>
</StyledScrollbar> </StyledScrollbar>
@ -296,6 +298,7 @@ export default inject(({ auth, dialogsStore, publicRoomStore }) => {
unsavedChangesDialogVisible, unsavedChangesDialogVisible,
setUnsavedChangesDialog, setUnsavedChangesDialog,
link: link ?? template, link: link ?? template,
language: auth.language,
}; };
})( })(
withTranslation(["SharingPanel", "Common", "Files"])(observer(EditLinkPanel)) withTranslation(["SharingPanel", "Common", "Files"])(observer(EditLinkPanel))

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState, useCallback } from "react"; import React, { useState } from "react";
import copy from "copy-to-clipboard"; import copy from "copy-to-clipboard";
import Text from "@docspace/components/text"; import Text from "@docspace/components/text";
import Link from "@docspace/components/link"; import Link from "@docspace/components/link";
@ -9,28 +9,34 @@ import IconButton from "@docspace/components/icon-button";
import Button from "@docspace/components/button"; import Button from "@docspace/components/button";
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url"; import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
import { StyledBody } from "./StyledEmbeddingPanel"; import { StyledBody } from "./StyledEmbeddingPanel";
import { objectToGetParams } from "@docspace/common/utils";
const EmbeddingBody = ({ t, embeddingLink }) => { const EmbeddingBody = ({ t, link, roomId }) => {
const [size, setSize] = useState("auto"); const [size, setSize] = useState("auto");
const [widthValue, setWidthValue] = useState("100%"); const [widthValue, setWidthValue] = useState("100%");
const [heightValue, setHeightValue] = useState("100%"); const [heightValue, setHeightValue] = useState("100%");
const getIframe = useCallback( const config = {
() => width: `${widthValue}`,
`<iframe src="${embeddingLink}" width="${widthValue}" height="${heightValue}" frameborder="0" scrolling="no" allowtransparency> </iframe>`, height: `${heightValue}`,
[embeddingLink, widthValue, heightValue] frameId: "ds-frame",
); init: true,
const [link, setLink] = useState(getIframe()); showHeader: true,
showTitle: true,
showMenu: false,
showFilter: true,
rootPath: "/rooms/shared/",
id: roomId,
};
useEffect(() => { const scriptUrl = `${window.location.origin}/static/scripts/api.js`;
const link = getIframe(); const params = objectToGetParams(config);
setLink(link); const codeBlock = `<div id="${config.frameId}">Fallback text</div>\n<script src="${scriptUrl}${params}"></script>`;
}, [embeddingLink, widthValue, heightValue]);
const onChangeWidth = (e) => setWidthValue(e.target.value); const onChangeWidth = (e) => setWidthValue(e.target.value);
const onChangeHeight = (e) => setHeightValue(e.target.value); const onChangeHeight = (e) => setHeightValue(e.target.value);
const onCopyLink = () => { const onCopyLink = () => {
copy(link); copy(codeBlock);
toastr.success(t("EmbeddingPanel:CodeCopySuccess")); toastr.success(t("EmbeddingPanel:CodeCopySuccess"));
}; };
@ -127,14 +133,16 @@ const EmbeddingBody = ({ t, embeddingLink }) => {
/> */} /> */}
</div> </div>
<div className="embedding-panel_code-container"> <div className="embedding-panel_code-container">
<Text className="embedding-panel_text">{t("EmbedCode")}:</Text> <Text className="embedding-panel_text">
{t("EmbeddingPanel:EmbedCode")}:
</Text>
<IconButton <IconButton
className="embedding-panel_copy-icon" className="embedding-panel_copy-icon"
size="16" size="16"
iconName={CopyReactSvgUrl} iconName={CopyReactSvgUrl}
onClick={onCopyLink} onClick={onCopyLink}
/> />
<Textarea isReadOnly value={link} heightTextArea={150} /> <Textarea isReadOnly value={codeBlock} heightTextArea={150} />
</div> </div>
</div> </div>
</StyledBody> </StyledBody>

View File

@ -8,9 +8,7 @@ import { StyledEmbeddingPanel, StyledScrollbar } from "./StyledEmbeddingPanel";
import EmbeddingBody from "./EmbeddingBody"; import EmbeddingBody from "./EmbeddingBody";
const EmbeddingPanelComponent = (props) => { const EmbeddingPanelComponent = (props) => {
const { t, link, visible, setEmbeddingPanelIsVisible } = props; const { t, link, roomId, visible, setEmbeddingPanelIsVisible } = props;
const embeddingLink = "embeddingLinkembeddingLinkembeddingLinkembeddingLink";
const scrollRef = useRef(null); const scrollRef = useRef(null);
@ -22,7 +20,7 @@ const EmbeddingPanelComponent = (props) => {
(e.key === "Esc" || e.key === "Escape") && onClose(); (e.key === "Esc" || e.key === "Escape") && onClose();
useEffect(() => { useEffect(() => {
scrollRef.current && scrollRef.current.view.focus(); scrollRef.current && scrollRef.current?.view?.focus();
document.addEventListener("keyup", onKeyPress); document.addEventListener("keyup", onKeyPress);
@ -44,7 +42,7 @@ const EmbeddingPanelComponent = (props) => {
</Heading> </Heading>
</div> </div>
<StyledScrollbar ref={scrollRef} stype="mediumBlack"> <StyledScrollbar ref={scrollRef} stype="mediumBlack">
<EmbeddingBody t={t} embeddingLink={link} /> <EmbeddingBody t={t} link={link} roomId={roomId} />
</StyledScrollbar> </StyledScrollbar>
</Aside> </Aside>
</StyledEmbeddingPanel> </StyledEmbeddingPanel>
@ -59,6 +57,7 @@ export default inject(({ dialogsStore }) => {
visible: embeddingPanelIsVisible, visible: embeddingPanelIsVisible,
setEmbeddingPanelIsVisible, setEmbeddingPanelIsVisible,
link: linkParams?.link?.sharedTo?.shareLink, link: linkParams?.link?.sharedTo?.shareLink,
roomId: linkParams?.roomId,
}; };
})( })(
withTranslation(["Files", "EmbeddingPanel"])( withTranslation(["Files", "EmbeddingPanel"])(

View File

@ -13,6 +13,7 @@ import EyeReactSvgUrl from "PUBLIC_DIR/images/eye.react.svg?url";
import SettingsReactSvgUrl from "PUBLIC_DIR/images/catalog.settings.react.svg?url"; import SettingsReactSvgUrl from "PUBLIC_DIR/images/catalog.settings.react.svg?url";
import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url"; import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url";
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url"; import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url";
import OutlineReactSvgUrl from "PUBLIC_DIR/images/outline-true.react.svg?url"; import OutlineReactSvgUrl from "PUBLIC_DIR/images/outline-true.react.svg?url";
import LockedReactSvgUrl from "PUBLIC_DIR/images/locked.react.svg?url"; import LockedReactSvgUrl from "PUBLIC_DIR/images/locked.react.svg?url";
import LoadedReactSvgUrl from "PUBLIC_DIR/images/loaded.react.svg?url"; import LoadedReactSvgUrl from "PUBLIC_DIR/images/loaded.react.svg?url";
@ -86,13 +87,13 @@ const LinkRow = (props) => {
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
}; };
const onLockClick = () => { const onCopyPassword = () => {
copy(password); copy(password);
toastr.success(t("Files:PasswordSuccessfullyCopied")); toastr.success(t("Files:PasswordSuccessfullyCopied"));
}; };
const onEmbeddingClick = () => { const onEmbeddingClick = () => {
setLinkParams({ link }); setLinkParams({ link, roomId });
setEmbeddingPanelIsVisible(true); setEmbeddingPanelIsVisible(true);
}; };
@ -130,6 +131,14 @@ const LinkRow = (props) => {
icon: CodeReactSvgUrl, icon: CodeReactSvgUrl,
onClick: onEmbeddingClick, onClick: onEmbeddingClick,
}, },
!disabled && {
key: "copy-link-settings-key",
label: t("SharingPanel:CopyExternalLink"),
icon: CopyToReactSvgUrl,
onClick: onCopyExternalLink,
},
disabled disabled
? { ? {
key: "enable-link-key", key: "enable-link-key",
@ -160,7 +169,6 @@ const LinkRow = (props) => {
return ( return (
<StyledLinkRow {...rest} isExpired={isExpired}> <StyledLinkRow {...rest} isExpired={isExpired}>
<Avatar <Avatar
className="avatar"
size="min" size="min"
source={EyeReactSvgUrl} source={EyeReactSvgUrl}
roleIcon={expiryDate ? <ClockReactSvg /> : null} roleIcon={expiryDate ? <ClockReactSvg /> : null}
@ -198,7 +206,8 @@ const LinkRow = (props) => {
className="locked-icon" className="locked-icon"
size={16} size={16}
iconName={LockedReactSvgUrl} iconName={LockedReactSvgUrl}
onClick={onLockClick} onClick={onCopyPassword}
title={t("Files:CopyLinkPassword")}
/> />
)} )}
<IconButton <IconButton
@ -206,12 +215,17 @@ const LinkRow = (props) => {
size={16} size={16}
iconName={CopyReactSvgUrl} iconName={CopyReactSvgUrl}
onClick={onCopyExternalLink} onClick={onCopyExternalLink}
title={t("SharingPanel:CopyExternalLink")}
/> />
</> </>
)} )}
{!isArchiveFolder && ( {!isArchiveFolder && (
<ContextMenuButton getData={getData} isDisabled={false} /> <ContextMenuButton
getData={getData}
isDisabled={false}
title={t("Files:ShowLinkActions")}
/>
)} )}
</div> </div>
</StyledLinkRow> </StyledLinkRow>

View File

@ -4,6 +4,7 @@ import PeopleIcon from "PUBLIC_DIR/images/people.react.svg?url";
import CrossReactSvg from "PUBLIC_DIR/images/cross.react.svg?url"; import CrossReactSvg from "PUBLIC_DIR/images/cross.react.svg?url";
import IconButton from "@docspace/components/icon-button"; import IconButton from "@docspace/components/icon-button";
import { StyledPublicRoomBar } from "./StyledPublicRoom"; import { StyledPublicRoomBar } from "./StyledPublicRoom";
import Text from "@docspace/components/text";
const PublicRoomBar = (props) => { const PublicRoomBar = (props) => {
const { headerText, bodyText, iconName, onClose, ...rest } = props; const { headerText, bodyText, iconName, onClose, ...rest } = props;
@ -15,9 +16,13 @@ const PublicRoomBar = (props) => {
<div className="header-icon"> <div className="header-icon">
<ReactSVG src={iconName ? iconName : PeopleIcon} /> <ReactSVG src={iconName ? iconName : PeopleIcon} />
</div> </div>
<div>{headerText}</div> <Text className="text-container_header" fontWeight={600}>
{headerText}
</Text>
</div> </div>
<div className="body-container">{bodyText}</div> <Text className="text-container_body" fontWeight={400}>
{bodyText}
</Text>
</div> </div>
{/* <IconButton {/* <IconButton

View File

@ -29,7 +29,7 @@ const PublicRoomBlock = (props) => {
<> <>
{externalLinks.length > 0 && !isArchiveFolder && ( {externalLinks.length > 0 && !isArchiveFolder && (
<PublicRoomBar <PublicRoomBar
headerText={t("Files:PublicRoom")} headerText={t("Files:RoomAvailableViaExternalLink")}
bodyText={t("CreateEditRoomDialog:PublicRoomBarDescription")} bodyText={t("CreateEditRoomDialog:PublicRoomBarDescription")}
/> />
)} )}
@ -56,6 +56,7 @@ const PublicRoomBlock = (props) => {
onClick={onAddNewLink} onClick={onAddNewLink}
size={16} size={16}
isDisabled={externalLinks.length >= LINKS_LIMIT_COUNT} isDisabled={externalLinks.length >= LINKS_LIMIT_COUNT}
title={t("Files:AddNewExternalLink")}
/> />
{externalLinks.length >= LINKS_LIMIT_COUNT && ( {externalLinks.length >= LINKS_LIMIT_COUNT && (

View File

@ -4,7 +4,7 @@ import commonIconsStyles from "@docspace/components/utils/common-icons-style";
const StyledPublicRoomBar = styled.div` const StyledPublicRoomBar = styled.div`
display: flex; display: flex;
background-color: #f8f9f9; background-color: ${(props) => props.theme.infoBlock.background};
color: #333; color: #333;
font-size: 12px; font-size: 12px;
padding: 12px 16px; padding: 12px 16px;
@ -25,9 +25,12 @@ const StyledPublicRoomBar = styled.div`
font-weight: 600; font-weight: 600;
} }
.body-container { .text-container_header {
color: #555f65; color: ${(props) => props.theme.infoBlock.headerColor};
font-weight: 400; }
.text-container_body {
color: ${(props) => props.theme.infoBlock.descriptionColor};
} }
.close-icon { .close-icon {
@ -87,12 +90,13 @@ const StyledLinkRow = styled.div`
} }
.avatar_role-wrapper { .avatar_role-wrapper {
${({ isExpired }) => ${({ isExpired, theme }) =>
isExpired &&
css` css`
svg { svg {
path { path {
fill: #f98e86; fill: ${isExpired
? theme.infoPanel.links.iconErrorColor
: theme.infoPanel.links.iconColor};
} }
} }
`} `}

View File

@ -938,7 +938,7 @@ const SectionHeaderContent = (props) => {
const isRoot = const isRoot =
isLoading && stateIsRoot isLoading && stateIsRoot
? stateIsRoot ? stateIsRoot
: isRootFolder || isAccountsPage || isSettingsPage || isPublicRoom; : isRootFolder || isAccountsPage || isSettingsPage;
const currentTitle = isSettingsPage const currentTitle = isSettingsPage
? t("Common:Settings") ? t("Common:Settings")

View File

@ -1,10 +1,9 @@
import React from "react"; import React from "react";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { useNavigate, useLocation } from "react-router-dom"; import { useLocation, Outlet } from "react-router-dom";
import Section from "@docspace/common/components/Section"; import Section from "@docspace/common/components/Section";
import SectionHeaderContent from "../Home/Section/Header"; import SectionHeaderContent from "../Home/Section/Header";
import SectionFilterContent from "../Home/Section/Filter"; import SectionFilterContent from "../Home/Section/Filter";
import SectionBodyContent from "../Home/Section/Body";
import FilesPanels from "../../components/FilesPanels"; import FilesPanels from "../../components/FilesPanels";
import { RoomSharingDialog } from "../../components/dialogs"; import { RoomSharingDialog } from "../../components/dialogs";
@ -62,7 +61,7 @@ const PublicRoomPage = (props) => {
)} )}
<Section.SectionBody> <Section.SectionBody>
<SectionBodyContent /> <Outlet />
</Section.SectionBody> </Section.SectionBody>
</Section> </Section>
@ -83,8 +82,7 @@ export default inject(
clientLoadingStore, clientLoadingStore,
}) => { }) => {
const { withPaging } = auth.settingsStore; const { withPaging } = auth.settingsStore;
const { validatePublicRoomKey, isLoaded, isLoading, roomStatus, roomId } = const { isLoaded, isLoading, roomStatus, roomId } = publicRoomStore;
publicRoomStore;
const { fetchFiles, isEmptyPage } = filesStore; const { fetchFiles, isEmptyPage } = filesStore;
const { getFilesSettings } = settingsStore; const { getFilesSettings } = settingsStore;
@ -113,7 +111,6 @@ export default inject(
getFilesSettings, getFilesSettings,
withPaging, withPaging,
validatePublicRoomKey,
showSecondaryProgressBar, showSecondaryProgressBar,
secondaryProgressBarValue, secondaryProgressBarValue,

View File

@ -21,6 +21,7 @@ const PublicRoom = (props) => {
validatePublicRoomKey, validatePublicRoomKey,
getFilesSettings, getFilesSettings,
setPublicRoomKey, setPublicRoomKey,
setIsArticleLoading,
} = props; } = props;
const navigate = useNavigate(); const navigate = useNavigate();
@ -38,6 +39,7 @@ const PublicRoom = (props) => {
const fetchRoomFiles = async () => { const fetchRoomFiles = async () => {
setPublicRoomKey(key); setPublicRoomKey(key);
await getFilesSettings(); await getFilesSettings();
setIsArticleLoading(false);
const filterObj = FilesFilter.getFilter(window.location); const filterObj = FilesFilter.getFilter(window.location);
@ -94,22 +96,26 @@ const PublicRoom = (props) => {
); );
}; };
export default inject(({ auth, publicRoomStore, settingsStore }) => { export default inject(
const { validatePublicRoomKey, isLoaded, isLoading, roomStatus, roomId } = ({ auth, publicRoomStore, settingsStore, clientLoadingStore }) => {
publicRoomStore; const { validatePublicRoomKey, isLoaded, isLoading, roomStatus, roomId } =
publicRoomStore;
const { getFilesSettings } = settingsStore; const { getFilesSettings } = settingsStore;
const { setPublicRoomKey } = auth.settingsStore; const { setPublicRoomKey } = auth.settingsStore;
const { setIsArticleLoading } = clientLoadingStore;
return { return {
roomId, roomId,
isLoaded, isLoaded,
isLoading, isLoading,
roomStatus, roomStatus,
getFilesSettings, getFilesSettings,
validatePublicRoomKey, validatePublicRoomKey,
setPublicRoomKey, setPublicRoomKey,
}; setIsArticleLoading,
})(observer(PublicRoom)); };
}
)(observer(PublicRoom));

View File

@ -254,6 +254,17 @@ const ClientRoutes = [
</ErrorBoundary> </ErrorBoundary>
</PublicRoute> </PublicRoute>
), ),
errorElement: <Error404 />,
children: [
{
index: true,
element: (
<PublicRoute>
<FilesView />
</PublicRoute>
),
},
],
}, },
{ {
path: "/wizard", path: "/wizard",

View File

@ -4,8 +4,6 @@ const SHOW_LOADER_TIMER = 500;
const MIN_LOADER_TIMER = 500; const MIN_LOADER_TIMER = 500;
class ClientLoadingStore { class ClientLoadingStore {
publicRoomStore;
isLoaded = false; isLoaded = false;
firstLoad = true; firstLoad = true;
@ -33,10 +31,8 @@ class ClientLoadingStore {
body: null, body: null,
}; };
constructor(publicRoomStore) { constructor() {
makeAutoObservable(this); makeAutoObservable(this);
this.publicRoomStore = publicRoomStore;
} }
setIsLoaded = (isLoaded) => { setIsLoaded = (isLoaded) => {
@ -217,7 +213,7 @@ class ClientLoadingStore {
get isLoading() { get isLoading() {
return ( return (
(this.isArticleLoading && !this.publicRoomStore.isPublicRoom) || this.isArticleLoading ||
this.pendingSectionLoaders.header || this.pendingSectionLoaders.header ||
this.pendingSectionLoaders.filter || this.pendingSectionLoaders.filter ||
this.pendingSectionLoaders.body this.pendingSectionLoaders.body
@ -225,7 +221,6 @@ class ClientLoadingStore {
} }
get showArticleLoader() { get showArticleLoader() {
if (this.publicRoomStore.isPublicRoom) return false;
return this.isArticleLoading; return this.isArticleLoading;
} }

View File

@ -38,7 +38,7 @@ import saveAs from "file-saver";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import config from "PACKAGE_FILE"; import config from "PACKAGE_FILE";
import toastr from "@docspace/components/toast/toastr"; import toastr from "@docspace/components/toast/toastr";
import { ShareAccessRights } from "@docspace/common/constants"; import { ShareAccessRights, RoomsType } from "@docspace/common/constants";
import combineUrl from "@docspace/common/utils/combineUrl"; import combineUrl from "@docspace/common/utils/combineUrl";
import { import {
isMobile as isMobileUtils, isMobile as isMobileUtils,
@ -620,7 +620,7 @@ class ContextOptionsStore {
return promise; return promise;
}; };
onClickInviteUsers = (e) => { onClickInviteUsers = (e, item) => {
const data = (e.currentTarget && e.currentTarget.dataset) || e; const data = (e.currentTarget && e.currentTarget.dataset) || e;
const { action } = data; const { action } = data;
@ -635,7 +635,10 @@ class ContextOptionsStore {
visible: true, visible: true,
roomId: action ? action : e, roomId: action ? action : e,
hideSelector: false, hideSelector: false,
defaultAccess: ShareAccessRights.ReadOnly, defaultAccess:
item.roomType === RoomsType.PublicRoom
? ShareAccessRights.RoomManager
: ShareAccessRights.ReadOnly,
}); });
} }
}; };
@ -1035,7 +1038,7 @@ class ContextOptionsStore {
key: "invite-users-to-room", key: "invite-users-to-room",
label: t("Common:InviteUsers"), label: t("Common:InviteUsers"),
icon: PersonReactSvgUrl, icon: PersonReactSvgUrl,
onClick: (e) => this.onClickInviteUsers(e), onClick: (e) => this.onClickInviteUsers(e, item),
disabled: false, disabled: false,
action: item.id, action: item.id,
}, },

View File

@ -58,7 +58,7 @@ const treeFoldersStore = new TreeFoldersStore(selectedFolderStore, authStore);
const publicRoomStore = new PublicRoomStore(); const publicRoomStore = new PublicRoomStore();
const clientLoadingStore = new ClientLoadingStore(publicRoomStore); const clientLoadingStore = new ClientLoadingStore();
const settingsStore = new SettingsStore( const settingsStore = new SettingsStore(
thirdPartyStore, thirdPartyStore,

View File

@ -143,6 +143,13 @@ const StyledContainer = styled.div`
.title-icon { .title-icon {
min-width: 16px; min-width: 16px;
min-height: 16px; min-height: 16px;
svg {
path,
rect {
fill: ${({ theme }) => theme.navigation.publicIcon};
}
}
} }
} }

View File

@ -131,8 +131,8 @@ export const RoomsType = Object.freeze({
EditingRoom: 2, EditingRoom: 2,
// ReviewRoom: 3, //TODO: Restore when certs will be done // ReviewRoom: 3, //TODO: Restore when certs will be done
// ReadOnlyRoom: 4, //TODO: Restore when certs will be done // ReadOnlyRoom: 4, //TODO: Restore when certs will be done
CustomRoom: 5,
PublicRoom: 6, PublicRoom: 6,
CustomRoom: 5,
}); });
export const RoomsTypeValues = Object.freeze( export const RoomsTypeValues = Object.freeze(

View File

@ -118,6 +118,13 @@ const DatePicker = (props) => {
); );
const handleClick = (e) => { const handleClick = (e) => {
if (
e.target.classList.contains("nav-thumb-vertical") ||
e.target.classList.contains("nav-thumb-horizontal")
) {
return;
}
!selectorRef?.current?.contains(e.target) && !selectorRef?.current?.contains(e.target) &&
!calendarRef?.current?.contains(e.target) && !calendarRef?.current?.contains(e.target) &&
!selectedItemRef?.current?.contains(e.target) && !selectedItemRef?.current?.contains(e.target) &&
@ -125,9 +132,9 @@ const DatePicker = (props) => {
}; };
useEffect(() => { useEffect(() => {
document.addEventListener("click", handleClick, { capture: true }); document.addEventListener("mousedown", handleClick, { capture: true });
return () => return () =>
document.removeEventListener("click", handleClick, { capture: true }); document.removeEventListener("mousedown", handleClick, { capture: true });
}, []); }, []);
useEffect(() => { useEffect(() => {

View File

@ -206,6 +206,10 @@ const StyledTableGroupMenu = styled.div`
} }
} }
} }
.scroll-body {
display: flex;
}
`; `;
StyledTableGroupMenu.defaultProps = { theme: Base }; StyledTableGroupMenu.defaultProps = { theme: Base };

View File

@ -1939,6 +1939,7 @@ const Base = {
expanderColor: black, expanderColor: black,
background: white, background: white,
rootFolderTitleColor: "#A3A9AE", rootFolderTitleColor: "#A3A9AE",
publicIcon: black,
icon: { icon: {
fill: "#316DAA", fill: "#316DAA",
@ -2013,6 +2014,11 @@ const Base = {
closeButtonSize: "17px", closeButtonSize: "17px",
closeButtonBg: "transparent", closeButtonBg: "transparent",
links: {
iconColor: "#3B72A7",
iconErrorColor: "rgba(242, 28, 14, 0.5)", //"#F21C0E",
},
members: { members: {
iconColor: "#A3A9AE", iconColor: "#A3A9AE",
iconHoverColor: "#657077", iconHoverColor: "#657077",
@ -3121,6 +3127,12 @@ const Base = {
errorColor: "#F21C0E", errorColor: "#F21C0E",
}, },
}, },
infoBlock: {
background: "#F8F9F9",
headerColor: "#333",
descriptionColor: "#555F65",
},
}; };
export default Base; export default Base;

View File

@ -1935,6 +1935,7 @@ const Dark = {
expanderColor: "#eeeeee", expanderColor: "#eeeeee",
background: black, background: black,
rootFolderTitleColor: "#858585", rootFolderTitleColor: "#858585",
publicIcon: "#858585",
icon: { icon: {
fill: "#E06A1B", fill: "#E06A1B",
@ -2009,6 +2010,11 @@ const Dark = {
closeButtonSize: "12px", closeButtonSize: "12px",
closeButtonBg: "#a2a2a2", closeButtonBg: "#a2a2a2",
links: {
iconColor: "#858585",
iconErrorColor: "rgba(242, 28, 14, 0.5)", //"#F21C0E",
},
members: { members: {
iconColor: "#A3A9AE", iconColor: "#A3A9AE",
iconHoverColor: "#ffffff", iconHoverColor: "#ffffff",
@ -3124,6 +3130,12 @@ const Dark = {
errorColor: "#F21C0E", errorColor: "#F21C0E",
}, },
}, },
infoBlock: {
background: "#282828",
headerColor: "#FFF",
descriptionColor: "#ADADAD",
},
}; };
export default Dark; export default Dark;