diff --git a/packages/client/public/locales/en/Files.json b/packages/client/public/locales/en/Files.json index b7e2f0cabd..2008b1861b 100644 --- a/packages/client/public/locales/en/Files.json +++ b/packages/client/public/locales/en/Files.json @@ -181,7 +181,7 @@ "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", - "RoomFilesLifetime": "The file lifetime is set to {{days}} days in this room", + "RoomFilesLifetime": "The file lifetime is set to {{days}} {{period}} in this room", "FileWillBeDeleted": "The file will be deleted {{date}}", "LifetimeDialogDescription": "Lifetime countdown begins at the file creation date. Some files in this room exceed the proposed lifetime and will be deleted once you enable the setting.", "LifetimeDialogDescriptionHeader": "Older files with exceeded lifetime will be deleted" diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 7338735f3d..c464a8a020 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -336,8 +336,6 @@ const FilesSelectorWrapper = ({ ); }; - const titleIconTooltip = t("Files:RoomFilesLifetime", { days: 12 }); // TODO: days - return ( { +const FileLifetime = ({ t, roomParams, setRoomParams }) => { + const lifetime = roomParams.lifetime ?? { + value: "12", + deletePermanently: false, + period: 0, + }; + const dateOptions = [ { key: 1, label: t("Common:Days")[0].toUpperCase() + t("Common:Days").slice(1), - "data-type": 1, + value: 0, }, { key: 2, label: t("Common:Months"), - "data-type": 2, + value: 1, }, { key: 3, label: t("Common:Years"), - "data-type": 3, + value: 2, }, ]; @@ -67,36 +73,57 @@ const FileLifetime = ({ t }) => { { key: 1, label: t("Common:MoveToTrash"), - "data-type": 1, + value: false, }, { key: 2, label: t("Common:DeletePermanently"), - "data-type": 2, + value: true, }, ]; - const [inputValue, setInputValue] = useState(""); - const [selectedDate, setSelectedDate] = useState(dateOptions[0]); - const [selectedDelete, setSelectedDelete] = useState(deleteOptions[0]); + const selectedInputValue = lifetime.value + ""; + const selectedDateOption = dateOptions.find( + (o) => o.value === lifetime.period, + ); + const selectedDeleteOptions = lifetime.deletePermanently + ? deleteOptions[1] + : deleteOptions[0]; + + const [inputValue, setInputValue] = useState(selectedInputValue); + const [selectedDate, setSelectedDate] = useState(selectedDateOption); + const [selectedDelete, setSelectedDelete] = useState(selectedDeleteOptions); const onChange = (e) => { // /^(?:[1-9][0-9]*|0)$/ if (e.target.value && !/^(?:[1-9][0-9]*)$/.test(e.target.value)) return; setInputValue(e.target.value); + + setRoomParams({ + ...roomParams, + lifetime: { ...lifetime, value: +e.target.value }, + }); }; const isLoading = false; const onSelectDate = (option) => { setSelectedDate(option); - console.log("onDateSelect", option); + + setRoomParams({ + ...roomParams, + lifetime: { ...lifetime, period: option.value }, + }); }; const onSelectDelete = (option) => { setSelectedDelete(option); - console.log("onSelectDelete", option); + + setRoomParams({ + ...roomParams, + lifetime: { ...lifetime, deletePermanently: option.value }, + }); }; return ( diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/VirtualDataRoomBlock.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/VirtualDataRoomBlock.js index 94033d48a9..0d24315182 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/VirtualDataRoomBlock.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/VirtualDataRoomBlock.js @@ -67,7 +67,9 @@ const Block = ({ const VirtualDataRoomBlock = ({ t, roomParams, setRoomParams }) => { const role = t("Translations:RoleViewer"); - const [fileLifetimeChecked, setFileLifetimeChecked] = useState(false); + const [fileLifetimeChecked, setFileLifetimeChecked] = useState( + !!roomParams?.lifetime, + ); const [copyAndDownloadChecked, setCopyAndDownloadChecked] = useState(false); const [watermarksChecked, setWatermarksChecked] = useState(false); @@ -103,7 +105,11 @@ const VirtualDataRoomBlock = ({ t, roomParams, setRoomParams }) => { isDisabled={false} isChecked={fileLifetimeChecked} > - + { (isPublicRoomType && !isPublicRoom && PublicRoomIconUrl) || (isVirtualDataRoomType && LifetimeRoomIconUrl); - const titleIconTooltip = t("Files:RoomFilesLifetime", { days: 12 }); // TODO: days + const titleIconTooltip = selectedFolder.lifetime + ? t("Files:RoomFilesLifetime", { + days: selectedFolder.lifetime.value, + period: getLifetimePeriodTranslation(selectedFolder.lifetime.period, t), + }) + : null; const navigationButtonLabel = showNavigationButton ? t("Files:ShareRoom") diff --git a/packages/client/src/store/CreateEditRoomStore.js b/packages/client/src/store/CreateEditRoomStore.js index 664fa66a8b..1f32699e06 100644 --- a/packages/client/src/store/CreateEditRoomStore.js +++ b/packages/client/src/store/CreateEditRoomStore.js @@ -126,6 +126,7 @@ class CreateEditRoomStore { roomType: roomParams.type, title: roomParams.title || t("Common:NewRoom"), indexing: roomParams.indexing, + lifetime: roomParams.lifetime, createAsNewFolder: roomParams.createAsNewFolder ?? true, ...(quotaLimit && { quota: +quotaLimit, diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index cc02acb56a..e5d57bdbff 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -3164,6 +3164,7 @@ class FilesStore { inRoom, requestToken, indexing, + lifetime, lastOpened, quotaLimit, usedSpace, @@ -3333,6 +3334,7 @@ class FilesStore { ...pluginOptions, inRoom, indexing, + lifetime, type, hasDraft, isForm, diff --git a/packages/client/src/store/SelectedFolderStore.ts b/packages/client/src/store/SelectedFolderStore.ts index 13cdab5ddd..91b4bfe5a5 100644 --- a/packages/client/src/store/SelectedFolderStore.ts +++ b/packages/client/src/store/SelectedFolderStore.ts @@ -40,7 +40,11 @@ import type { TPathParts, } from "@docspace/shared/types"; import { TFolder, TFolderSecurity } from "@docspace/shared/api/files/types"; -import { TLogo, TRoomSecurity } from "@docspace/shared/api/rooms/types"; +import { + TLogo, + TRoomLifetime, + TRoomSecurity, +} from "@docspace/shared/api/rooms/types"; import { setDocumentTitle } from "../helpers/utils"; @@ -141,6 +145,8 @@ class SelectedFolderStore { parentRoomType: Nullable = null; + lifetime: TRoomLifetime | null = null; + constructor(settingsStore: SettingsStore) { makeAutoObservable(this); this.settingsStore = settingsStore; @@ -185,6 +191,7 @@ class SelectedFolderStore { type: this.type, isRootFolder: this.isRootFolder, parentRoomType: this.parentRoomType, + lifetime: this.lifetime, }; }; diff --git a/packages/shared/api/rooms/types.ts b/packages/shared/api/rooms/types.ts index 5c442a6d33..07eb47f5d0 100644 --- a/packages/shared/api/rooms/types.ts +++ b/packages/shared/api/rooms/types.ts @@ -54,6 +54,12 @@ export type TRoomSecurity = { CopySharedLink: boolean; }; +export type TRoomLifetime = { + deletePermanently: boolean; + period: number; + value: number; +}; + export type TRoom = { parentId: number; filesCount: number; @@ -79,6 +85,7 @@ export type TRoom = { updatedBy: TCreatedBy; isArchive?: boolean; security: TRoomSecurity; + lifetime: TRoomLifetime; }; export type TGetRooms = { diff --git a/packages/shared/components/selector/Selector.tsx b/packages/shared/components/selector/Selector.tsx index 581d34fdb5..705eb98113 100644 --- a/packages/shared/components/selector/Selector.tsx +++ b/packages/shared/components/selector/Selector.tsx @@ -134,7 +134,6 @@ const Selector = ({ withInfo, infoText, - titleIconTooltip, }: SelectorProps) => { const [footerVisible, setFooterVisible] = React.useState(false); const [isSearch, setIsSearch] = React.useState(false); @@ -600,7 +599,6 @@ const Selector = ({ withFooterInput={withFooterInput} withFooterCheckbox={withFooterCheckbox} descriptionText={descriptionText} - titleIconTooltip={titleIconTooltip} inputItemVisible={inputItemVisible} setInputItemVisible={setInputItemVisible} // bread crumbs diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index 3e2855dddc..2fa4526c85 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -342,7 +342,6 @@ export type SelectorProps = TSelectorHeader & alwaysShowFooter?: boolean; descriptionText?: string; - titleIconTooltip?: string; }; export type BodyProps = TSelectorBreadCrumbs & @@ -381,7 +380,6 @@ export type BodyProps = TSelectorBreadCrumbs & withFooterInput?: boolean; withFooterCheckbox?: boolean; descriptionText?: string; - titleIconTooltip?: string; }; export type FooterProps = TSelectorFooterSubmitButton & @@ -543,6 +541,7 @@ export type TSelectorItem = TSelectorItemType & { isSelected?: boolean; isDisabled?: boolean; disabledText?: string; + lifetimeTooltip?: string; }; export type Data = { @@ -551,7 +550,6 @@ export type Data = { isMultiSelect: boolean; isItemLoaded: (index: number) => boolean; rowLoader: React.ReactNode; - titleIconTooltip?: string; renderCustomItem?: ( label: string, role?: string, diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index d8686e49c8..00877e400f 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -102,7 +102,6 @@ const Body = ({ withInfo, infoText, - titleIconTooltip, setInputItemVisible, inputItemVisible, }: BodyProps) => { @@ -304,7 +303,6 @@ const Body = ({ rowLoader, isItemLoaded, renderCustomItem, - titleIconTooltip, setInputItemVisible, inputItemVisible, }} diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index c21a83670d..d8f79a9ef8 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -70,7 +70,6 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { isItemLoaded, rowLoader, renderCustomItem, - titleIconTooltip, setInputItemVisible, inputItemVisible, }: Data = data; @@ -110,6 +109,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { isGroup, disabledText, dropDownItems, + lifetimeTooltip, } = item; if (isInputItem) { @@ -181,7 +181,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { const getContent = () => ( - {titleIconTooltip} + {lifetimeTooltip} ); @@ -237,7 +237,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { {label} - {titleIconTooltip && ( + {lifetimeTooltip && ( <> string; - titleIconTooltip?: string; withCreate: boolean; createDefineRoomLabel?: string; diff --git a/packages/shared/selectors/Files/FilesSelector.utils.ts b/packages/shared/selectors/Files/FilesSelector.utils.ts index e8c389778a..4c03d594b5 100644 --- a/packages/shared/selectors/Files/FilesSelector.utils.ts +++ b/packages/shared/selectors/Files/FilesSelector.utils.ts @@ -27,10 +27,14 @@ import { TSelectorItem } from "../../components/selector"; import { TFile, TFolder } from "../../api/files/types"; import { TRoom } from "../../api/rooms/types"; -import { getIconPathByFolderType } from "../../utils/common"; +import { + getIconPathByFolderType, + getLifetimePeriodTranslation, +} from "../../utils/common"; import { iconSize32 } from "../../utils/image-helpers"; import { DEFAULT_FILE_EXTS } from "./FilesSelector.constants"; import { getTitleWithoutExtension } from "../../utils"; +import { TTranslation } from "../../types"; const isDisableFolder = ( folder: TFolder, @@ -118,9 +122,10 @@ export const convertFilesToItems: ( return items; }; -export const convertRoomsToItems: (rooms: TRoom[]) => TSelectorItem[] = ( +export const convertRoomsToItems: ( rooms: TRoom[], -) => { + t: TTranslation, +) => TSelectorItem[] = (rooms: TRoom[], t: TTranslation) => { const items = rooms.map((room) => { const { id, @@ -133,12 +138,20 @@ export const convertRoomsToItems: (rooms: TRoom[]) => TSelectorItem[] = ( parentId, rootFolderType, shared, + lifetime, } = room; const icon = logo.medium || ""; const iconProp = icon ? { icon } : { color: logo.color as string }; + const lifetimeTooltip = lifetime + ? t("Files:RoomFilesLifetime", { + days: String(lifetime.value), + period: getLifetimePeriodTranslation(lifetime.period, t), + }) + : null; + return { id, label: title, @@ -151,6 +164,7 @@ export const convertRoomsToItems: (rooms: TRoom[]) => TSelectorItem[] = ( isFolder: true, roomType, shared, + lifetimeTooltip, ...iconProp, }; }); diff --git a/packages/shared/selectors/Files/hooks/useRoomsHelper.tsx b/packages/shared/selectors/Files/hooks/useRoomsHelper.tsx index 6f1599da1b..cb22c2afff 100644 --- a/packages/shared/selectors/Files/hooks/useRoomsHelper.tsx +++ b/packages/shared/selectors/Files/hooks/useRoomsHelper.tsx @@ -142,7 +142,7 @@ const useRoomsHelper = ({ setIsBreadCrumbsLoading(false); } - const itemList: TSelectorItem[] = convertRoomsToItems(folders); + const itemList: TSelectorItem[] = convertRoomsToItems(folders, t); setHasNextPage(count === PAGE_COUNT); diff --git a/packages/shared/selectors/Files/index.tsx b/packages/shared/selectors/Files/index.tsx index 360a873aff..8487ca92d0 100644 --- a/packages/shared/selectors/Files/index.tsx +++ b/packages/shared/selectors/Files/index.tsx @@ -108,7 +108,6 @@ const FilesSelector = ({ withBreadCrumbs: withBreadCrumbsProp, filesSettings, cancelButtonLabel, - titleIconTooltip, withCreate, createDefineRoomLabel, @@ -602,7 +601,6 @@ const FilesSelector = ({ : getFileList } descriptionText={descriptionText} - titleIconTooltip={titleIconTooltip} disableFirstFetch /> ); diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 2f6d2e3649..434576e92d 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -411,6 +411,24 @@ export function getProviderLabel(provider: string, t: (key: string) => string) { return ""; } } + +export const getLifetimePeriodTranslation = ( + period: number, + t: TTranslation, +) => { + switch (period) { + case 0: + return t("Common:Days").toLowerCase(); + case 1: + return t("Common:Months").toLowerCase(); + case 2: + return t("Common:Years").toLowerCase(); + + default: + return t("Common:Days").toLowerCase(); + } +}; + export const isLanguageRtl = (lng: string) => { if (!lng) return;