diff --git a/package.json b/package.json index 48b963b88a..46822adf48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docspace", - "version": "2.6.0", + "version": "2.6.1", "private": true, "workspaces": { "packages": [ diff --git a/packages/client/package.json b/packages/client/package.json index 747c090470..cedf6bdafc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@docspace/client", - "version": "2.6.0", + "version": "2.6.1", "private": true, "homepage": "", "scripts": { diff --git a/packages/client/public/locales/en/Translations.json b/packages/client/public/locales/en/Translations.json index 38b7d0ad8e..8ccc7ba1af 100644 --- a/packages/client/public/locales/en/Translations.json +++ b/packages/client/public/locales/en/Translations.json @@ -33,11 +33,14 @@ "RoleEditorDescription": "Operations with existing files: viewing, editing, form filling, reviewing, commenting.", "RoleFormFiller": "Form filler", "RoleFormFillerDescription": "Operations with existing files: viewing, form filling, reviewing, commenting.", + "RoleFormFillerFormRoomDescription": "Form fillers can fill out forms and view only their completed/started forms within the Complete and In Process folders.", "RolePortalAdminDescription": "{{productName}} admins can access {{productName}} settings, manage and archive rooms, invite new users and assign roles below their level. All admins have access to the Personal section.", "RolePowerUserDescription": "Power users can create and edit files in the room, but can't create rooms, manage users, or access settings.", + "RolePowerUserFormRoomDescription": "Power users can upload forms to the room and have full access to the Complete and In Process folders.", "RoleReviewer": "Reviewer", "RoleReviewerDescription": "Operations with existing files: viewing, reviewing, commenting.", "RoleRoomAdminDescription": "Room admins can create and manage the assigned rooms, invite new users, and assign roles of room admin and lower. All admins have access to the Personal section.", + "RoleRoomAdminFormRoomDescription": "Room admins can create and manage rooms, invite new users and assign roles of room admin or lower. Room admins can upload forms to the room and have full access to the Complete and In Process folders.", "RoleUserDescription": "Users can only access the rooms they are invited to by admins. They can't create own rooms, folders or files.", "RoleViewer": "Viewer", "RoleViewerDescription": "File viewing", diff --git a/packages/client/src/components/Article/Body/index.js b/packages/client/src/components/Article/Body/index.js index ad42b1da31..e20f3a0493 100644 --- a/packages/client/src/components/Article/Body/index.js +++ b/packages/client/src/components/Article/Body/index.js @@ -105,6 +105,17 @@ const ArticleBodyContent = (props) => { case myFolderId: const myFilter = FilesFilter.getDefault(); myFilter.folder = folderId; + + const filterStorageItem = + userId && localStorage.getItem(`UserFilter=${userId}`); + + if (filterStorageItem) { + const splitFilter = filterStorageItem.split(","); + + myFilter.sortBy = splitFilter[0]; + myFilter.sortOrder = splitFilter[1]; + } + params = myFilter.toUrlParams(); path = getCategoryUrl(CategoryType.Personal); @@ -123,6 +134,17 @@ const ArticleBodyContent = (props) => { case recycleBinFolderId: const recycleBinFilter = FilesFilter.getDefault(); recycleBinFilter.folder = folderId; + + const filterStorageTrash = + userId && localStorage.getItem(`UserFilterTrash=${userId}`); + + if (filterStorageTrash) { + const splitFilterTrash = filterStorageTrash.split(","); + + recycleBinFilter.sortBy = splitFilterTrash[0]; + recycleBinFilter.sortOrder = splitFilterTrash[1]; + } + params = recycleBinFilter.toUrlParams(); path = getCategoryUrl(CategoryType.Trash); diff --git a/packages/client/src/components/panels/InvitePanel/index.js b/packages/client/src/components/panels/InvitePanel/index.js index 8799b4de81..7633df58a1 100644 --- a/packages/client/src/components/panels/InvitePanel/index.js +++ b/packages/client/src/components/panels/InvitePanel/index.js @@ -34,7 +34,7 @@ import React, { import { observer, inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { DeviceType } from "@docspace/shared/enums"; +import { DeviceType, EmployeeType } from "@docspace/shared/enums"; import { LOADER_TIMEOUT } from "@docspace/shared/constants"; import { Backdrop } from "@docspace/shared/components/backdrop"; @@ -72,11 +72,6 @@ const InvitePanel = ({ visible, setRoomSecurity, getRoomSecurityInfo, - getPortalInviteLinks, - userLink, - guestLink, - adminLink, - collaboratorLink, defaultAccess, inviteUsers, setInfoPanelIsMobileHidden, @@ -88,9 +83,7 @@ const InvitePanel = ({ currentDeviceType, }) => { const [invitePanelIsLoding, setInvitePanelIsLoading] = useState( - () => - ((!userLink || !guestLink || !collaboratorLink) && !adminLink) || - roomId !== -1, + roomId !== -1, ); const [selectedRoom, setSelectedRoom] = useState(null); const [hasErrors, setHasErrors] = useState(false); @@ -117,6 +110,33 @@ const InvitePanel = ({ setExternalLinksVisible(visible); }; + const accessModel = [ + { + id: "user", + title: "User", + shareLink: "", + access: EmployeeType.User, + }, + { + id: "guest", + title: "Guest", + shareLink: "", + access: EmployeeType.Guest, + }, + { + id: "admin", + title: "Admin", + shareLink: "", + access: EmployeeType.Admin, + }, + { + id: "collaborator", + title: "Collaborator", + shareLink: "", + access: EmployeeType.Collaborator, + }, + ]; + const selectRoom = () => { const room = folders.find((folder) => folder.id === roomId); @@ -167,40 +187,7 @@ const InvitePanel = ({ useEffect(() => { if (roomId === -1) { - if ((!userLink || !guestLink || !collaboratorLink) && !adminLink) { - setInvitePanelIsLoading(true); - getPortalInviteLinks().finally(() => { - disableInvitePanelLoader(); - }); - } - - setShareLinks([ - { - id: "user", - title: "User", - shareLink: userLink, - access: 1, - }, - { - id: "guest", - title: "Guest", - shareLink: guestLink, - access: 2, - }, - { - id: "admin", - title: "Admin", - shareLink: adminLink, - access: 3, - }, - { - id: "collaborator", - title: "Collaborator", - shareLink: collaboratorLink, - access: 4, - }, - ]); - + setShareLinks(accessModel); return; } @@ -208,7 +195,7 @@ const InvitePanel = ({ Promise.all([selectRoom(), getInfo()]).finally(() => { disableInvitePanelLoader(false); }); - }, [roomId, userLink, guestLink, adminLink, collaboratorLink]); + }, [roomId]); useEffect(() => { const hasErrors = inviteItems.some((item) => !!item.errors?.length); @@ -487,14 +474,6 @@ export default inject( isRoomMembersPanelOpen, } = infoPanelStore; - const { - getPortalInviteLinks, - userLink, - guestLink, - adminLink, - collaboratorLink, - } = peopleStore.inviteLinksStore; - const { inviteItems, invitePanelOptions, @@ -520,11 +499,6 @@ export default inject( visible: invitePanelOptions.visible, defaultAccess: invitePanelOptions.defaultAccess, getFolderInfo, - getPortalInviteLinks, - userLink, - guestLink, - adminLink, - collaboratorLink, inviteUsers, setInfoPanelIsMobileHidden, updateInfoPanelMembers, diff --git a/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js b/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js index ddeb656146..3157df9554 100644 --- a/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js +++ b/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js @@ -64,20 +64,26 @@ const ExternalLinks = ({ setActiveLink, activeLink, isMobileView, + getPortalInviteLink, }) => { const [actionLinksVisible, setActionLinksVisible] = useState(false); const inputsRef = useRef(); - const toggleLinks = () => { + const toggleLinks = async (e) => { if (roomId === -1) { - const link = shareLinks.find((l) => l.access === +defaultAccess); + if (e?.target?.checked) { + const link = shareLinks.find((l) => l.access === defaultAccess); - setActiveLink(link); - copyLink(link.shareLink); + link.shareLink = await getPortalInviteLink(defaultAccess); + + setActiveLink(link); + copyLink(link.shareLink); + } } else { !externalLinksVisible ? editLink() : disableLink(); } + onChangeExternalLinksVisible(!externalLinksVisible); }; @@ -106,11 +112,13 @@ const ExternalLinks = ({ setActiveLink(activeLink); }; - const onSelectAccess = (access) => { + const onSelectAccess = async (access) => { let link = null; if (roomId === -1) { link = shareLinks.find((l) => l.access === access.access); + link.shareLink = await getPortalInviteLink(access.access); + setActiveLink(link); } else { setInvitationLinks(roomId, "Invite", +access.access, shareLinks[0].id); @@ -254,17 +262,21 @@ const ExternalLinks = ({ ); }; -export default inject(({ userStore, dialogsStore, filesStore }) => { - const { isOwner } = userStore.user; - const { invitePanelOptions } = dialogsStore; - const { setInvitationLinks } = filesStore; - const { roomId, hideSelector, defaultAccess } = invitePanelOptions; +export default inject( + ({ userStore, dialogsStore, filesStore, peopleStore }) => { + const { isOwner } = userStore.user; + const { invitePanelOptions } = dialogsStore; + const { setInvitationLinks } = filesStore; + const { roomId, hideSelector, defaultAccess } = invitePanelOptions; + const { getPortalInviteLink } = peopleStore.inviteLinksStore; - return { - setInvitationLinks, - roomId, - hideSelector, - defaultAccess, - isOwner, - }; -})(observer(ExternalLinks)); + return { + setInvitationLinks, + roomId, + hideSelector, + defaultAccess, + isOwner, + getPortalInviteLink, + }; + }, +)(observer(ExternalLinks)); diff --git a/packages/client/src/components/panels/InvitePanel/utils/index.js b/packages/client/src/components/panels/InvitePanel/utils/index.js index cc47ca63c7..951954fe6b 100644 --- a/packages/client/src/components/panels/InvitePanel/utils/index.js +++ b/packages/client/src/components/panels/InvitePanel/utils/index.js @@ -31,6 +31,50 @@ import { } from "@docspace/shared/enums"; import { checkIfAccessPaid } from "SRC_DIR/helpers"; +/** + * @param {RoomsType} roomType + * @param {(key: string) => string} t + * @returns {string} + */ +const getRoomAdminDescription = (roomType, t) => { + switch (roomType) { + case RoomsType.FormRoom: + return t("Translations:RoleRoomAdminFormRoomDescription"); + + default: + return t("Translations:RoleRoomAdminDescription"); + } +}; +/** + * @param {RoomsType} roomType + * @param {(key: string)=> string} t + * @returns {string} + */ +const getPowerUserDescription = (roomType, t) => { + switch (roomType) { + case RoomsType.FormRoom: + return t("Translations:RolePowerUserFormRoomDescription"); + + default: + return t("Translations:RolePowerUserDescription"); + } +}; + +/** + * @param {RoomsType} roomType + * @param {(key: string)=> string} t + * @returns {string} + */ +const getFormFillerDescription = (roomType, t) => { + switch (roomType) { + case RoomsType.FormRoom: + return t("Translations:RoleFormFillerFormRoomDescription"); + + default: + return t("Translations:RoleFormFillerDescription"); + } +}; + export const getAccessOptions = ( t, roomType = RoomsType.CustomRoom, @@ -56,7 +100,7 @@ export const getAccessOptions = ( roomAdmin: { key: "roomAdmin", label: t("Common:RoomAdmin"), - description: t("Translations:RoleRoomAdminDescription"), + description: getRoomAdminDescription(roomType, t), ...(!standalone && { quota: t("Common:Paid") }), color: "#EDC409", access: @@ -66,7 +110,7 @@ export const getAccessOptions = ( collaborator: { key: "collaborator", label: t("Common:PowerUser"), - description: t("Translations:RolePowerUserDescription"), + description: getPowerUserDescription(roomType, t), ...(!standalone && { quota: t("Common:Paid") }), color: "#EDC409", access: @@ -92,7 +136,7 @@ export const getAccessOptions = ( formFiller: { key: "formFiller", label: t("Translations:RoleFormFiller"), - description: t("Translations:RoleFormFillerDescription"), + description: getFormFillerDescription(roomType, t), access: ShareAccessRights.FormFilling, type: "user", }, diff --git a/packages/client/src/components/panels/UploadPanel/index.js b/packages/client/src/components/panels/UploadPanel/index.js index c1544e6c7f..dc0ee3c326 100644 --- a/packages/client/src/components/panels/UploadPanel/index.js +++ b/packages/client/src/components/panels/UploadPanel/index.js @@ -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 ClearActiveReactSvgUrl from "PUBLIC_DIR/images/clear.active.react.svg?url"; +import ClearReactSvgUrl from "PUBLIC_DIR/images/clear.react.svg?url"; import ButtonCancelReactSvgUrl from "PUBLIC_DIR/images/button.cancel.react.svg?url"; import React from "react"; @@ -136,8 +136,8 @@ class UploadPanelComponent extends React.Component {
{uploaded && converted ? ( diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js index 4c62ab6e87..76b188ceb9 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -54,6 +54,8 @@ class FilesTableHeader extends React.Component { showStorageInfo, isArchiveFolder, tableStorageName, + roomsFilter, + filter, } = this.props; const defaultColumns = []; @@ -365,6 +367,9 @@ class FilesTableHeader extends React.Component { const tableColumns = columns.map((c) => c.enable && c.key); + const sortBy = isRooms ? roomsFilter.sortBy : filter.sortBy; + const sortOrder = isRooms ? roomsFilter.sortOrder : filter.sortOrder; + this.setTableColumns(tableColumns); if (fromUpdate) { this.setState({ @@ -372,6 +377,8 @@ class FilesTableHeader extends React.Component { resetColumnsSize, columnStorageName, columnInfoPanelStorageName, + sortBy, + sortOrder, }); } else { this.state = { @@ -379,6 +386,8 @@ class FilesTableHeader extends React.Component { resetColumnsSize, columnStorageName, columnInfoPanelStorageName, + sortBy, + sortOrder, }; } }; @@ -425,8 +434,13 @@ class FilesTableHeader extends React.Component { isRecentTab, isArchiveFolder, showStorageInfo, + roomsFilter, + filter, } = this.props; + const sortBy = isRooms ? roomsFilter.sortBy : filter.sortBy; + const sortOrder = isRooms ? roomsFilter.sortOrder : filter.sortOrder; + if ( isArchiveFolder !== prevProps.isArchiveFolder || isRooms !== prevProps.isRooms || @@ -434,12 +448,15 @@ class FilesTableHeader extends React.Component { columnStorageName !== prevProps.columnStorageName || columnInfoPanelStorageName !== prevProps.columnInfoPanelStorageName || isRecentTab !== prevProps.isRecentTab || - showStorageInfo !== prevProps.showStorageInfo + showStorageInfo !== prevProps.showStorageInfo || + sortBy !== this.state.sortBy || + sortOrder !== this.state.sortOrder ) { return this.getTableColumns(true); } const { columns } = this.state; + if (this.props.withContent !== prevProps.withContent) { const columnIndex = columns.findIndex((c) => c.key === "Share"); if (columnIndex === -1) return; @@ -528,9 +545,6 @@ class FilesTableHeader extends React.Component { t, containerRef, isHeaderChecked, - filter, - roomsFilter, - isRooms, firstElemChecked, sortingVisible, infoPanelVisible, @@ -547,11 +561,10 @@ class FilesTableHeader extends React.Component { resetColumnsSize, columnStorageName, columnInfoPanelStorageName, + sortBy, + sortOrder, } = this.state; - const sortBy = isRooms ? roomsFilter.sortBy : filter.sortBy; - const sortOrder = isRooms ? roomsFilter.sortOrder : filter.sortOrder; - return ( { - if (!hideableColumns[columnTitle]) return; - - if (availableSort?.includes(columnTitle)) { - const idx = availableSort.findIndex((x) => x === columnTitle); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && options.push(hideableColumns[columnTitle]); - } - }); - } else { - options.push(type, department, email); - if (showStorageInfo) options.push(storage); - } + options.push(firstName, lastName, type, department, email); + if (showStorageInfo) options.push(storage); return options; } @@ -2069,29 +2035,7 @@ const SectionFilterContent = ({ default: true, }; - groupsOptions.push(title); - - if (accountsViewAs === "table") { - const availableSort = localStorage - ?.getItem(`${TABLE_GROUPS_COLUMNS}=${userId}`) - ?.split(","); - - const infoPanelColumnsSize = localStorage - ?.getItem(`${COLUMNS_GROUPS_SIZE_INFO_PANEL}=${userId}`) - ?.split(" "); - - if (availableSort?.includes("Head of Group")) { - const idx = availableSort.findIndex((x) => x === "Head of Group"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && groupsOptions.push(manager); - } - } else { - groupsOptions.push(manager); - } + groupsOptions.push(title, manager); return groupsOptions; } @@ -2181,220 +2125,25 @@ const SectionFilterContent = ({ commonOptions.push(name); - if (viewAs === "table") { - if (isRooms) { - const availableSort = localStorage - ?.getItem(`${TABLE_ROOMS_COLUMNS}=${userId}`) - ?.split(","); - - const infoPanelColumnsSize = localStorage - ?.getItem(`${COLUMNS_ROOMS_SIZE_INFO_PANEL}=${userId}`) - ?.split(" "); - - const hideOption = infoPanelVisible && infoPanelColumnsSize; - - if (availableSort?.includes("Type")) { - const idx = availableSort.findIndex((x) => x === "Type"); - const hide = hideOption && infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(roomType); - } - - if (availableSort?.includes("Tags")) { - const idx = availableSort.findIndex((x) => x === "Tags"); - const hide = hideOption && infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(tags); - } - - if (availableSort?.includes("Owner")) { - const idx = availableSort.findIndex((x) => x === "Owner"); - const hide = hideOption && infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(owner); - } - - if (availableSort?.includes("Activity")) { - const idx = availableSort.findIndex((x) => x === "Activity"); - const hide = hideOption && infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(modifiedDate); - } - - if (showStorageInfo && availableSort?.includes("Storage")) { - const idx = availableSort.findIndex( - (x) => x === SortByFieldName.UsedSpace, - ); - const hide = hideOption && infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(sortByStorage); - } - } else if (isTrash) { - const availableSort = localStorage - ?.getItem(`${TABLE_TRASH_COLUMNS}=${userId}`) - ?.split(","); - - const infoPanelColumnsSize = localStorage - ?.getItem(`${COLUMNS_TRASH_SIZE_INFO_PANEL}=${userId}`) - ?.split(" "); - - if (availableSort?.includes("Room")) { - const idx = availableSort.findIndex((x) => x === "Room"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(room); - } - if (availableSort?.includes("AuthorTrash")) { - const idx = availableSort.findIndex((x) => x === "AuthorTrash"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(authorOption); - } - if (availableSort?.includes("CreatedTrash")) { - const idx = availableSort.findIndex((x) => x === "CreatedTrash"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(creationDate); - } - if (availableSort?.includes("Erasure")) { - const idx = availableSort.findIndex((x) => x === "Erasure"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(erasure); - } - if (availableSort?.includes("SizeTrash")) { - const idx = availableSort.findIndex((x) => x === "SizeTrash"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(size); - } - if (availableSort?.includes("TypeTrash")) { - const idx = availableSort.findIndex((x) => x === "TypeTrash"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(type); - } - } else if (isRecentTab) { - const availableSort = localStorage - ?.getItem(`${TABLE_RECENT_COLUMNS}=${userId}`) - ?.split(","); - - const infoPanelColumnsSize = localStorage - ?.getItem(`${COLUMNS_RECENT_SIZE_INFO_PANEL}=${userId}`) - ?.split(" "); - - if (availableSort?.includes("LastOpened")) { - const idx = availableSort.findIndex((x) => x === "LastOpened"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(lastOpenedDate); - } - - if (availableSort?.includes("Size")) { - const idx = availableSort.findIndex((x) => x === "Size"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(size); - } - } else { - const availableSort = localStorage - ?.getItem(`${TABLE_COLUMNS}=${userId}`) - ?.split(","); - - const infoPanelColumnsSize = localStorage - ?.getItem(`${COLUMNS_SIZE_INFO_PANEL}=${userId}`) - ?.split(" "); - - if (availableSort?.includes("Author")) { - const idx = availableSort.findIndex((x) => x === "Author"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(authorOption); - } - if (availableSort?.includes("Created")) { - const idx = availableSort.findIndex((x) => x === "Created"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(creationDate); - } - if (availableSort?.includes("Modified")) { - const idx = availableSort.findIndex((x) => x === "Modified"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(modifiedDate); - } - if (availableSort?.includes("Size")) { - const idx = availableSort.findIndex((x) => x === "Size"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - !hide && commonOptions.push(size); - } - if (availableSort?.includes("Type")) { - const idx = availableSort.findIndex((x) => x === "Type"); - const hide = - infoPanelVisible && - infoPanelColumnsSize && - infoPanelColumnsSize[idx] === "0px"; - - // !hide && commonOptions.push(type); - } - } + if (isRooms) { + commonOptions.push(roomType); + commonOptions.push(tags); + commonOptions.push(owner); + commonOptions.push(modifiedDate); + showStorageInfo && commonOptions.push(sortByStorage); + } else if (isTrash) { + // commonOptions.push(authorOption); + // commonOptions.push(creationDate); + commonOptions.push(erasure); + commonOptions.push(size); + // commonOptions.push(type); } else { - if (isRooms) { - commonOptions.push(roomType); - commonOptions.push(tags); - commonOptions.push(owner); - commonOptions.push(modifiedDate); - showStorageInfo && commonOptions.push(sortByStorage); - } else if (isTrash) { - // commonOptions.push(authorOption); - // commonOptions.push(creationDate); - commonOptions.push(erasure); - commonOptions.push(size); - // commonOptions.push(type); - } else { - // commonOptions.push(authorOption); - // commonOptions.push(creationDate); - commonOptions.push(modifiedDate); - commonOptions.push(size); - // commonOptions.push(type); - } + // commonOptions.push(authorOption); + // commonOptions.push(creationDate); + commonOptions.push(modifiedDate); + commonOptions.push(size); + // commonOptions.push(type); + isRecentTab && commonOptions.push(lastOpenedDate); } return commonOptions; diff --git a/packages/client/src/pages/Home/Section/Header/index.js b/packages/client/src/pages/Home/Section/Header/index.js index 19a7dd8131..c66876e6fe 100644 --- a/packages/client/src/pages/Home/Section/Header/index.js +++ b/packages/client/src/pages/Home/Section/Header/index.js @@ -240,6 +240,8 @@ const SectionHeaderContent = (props) => { }; const onContextOptionsClick = () => { + if (isInsideGroup) return; + setBufferSelection(selectedFolder); }; diff --git a/packages/client/src/pages/Home/Section/Tabs/MyDocumentsTabs/index.js b/packages/client/src/pages/Home/Section/Tabs/MyDocumentsTabs/index.js index 0dfe92a42f..51f216292b 100644 --- a/packages/client/src/pages/Home/Section/Tabs/MyDocumentsTabs/index.js +++ b/packages/client/src/pages/Home/Section/Tabs/MyDocumentsTabs/index.js @@ -38,6 +38,7 @@ const MyDocumentsTabs = ({ setFilter, showBodyLoader, isRoot, + user, }) => { const { t } = useTranslation(["Common", "Files"]); @@ -56,13 +57,25 @@ const MyDocumentsTabs = ({ const filter = FilesFilter.getDefault(); const url = window.DocSpace.location.pathname; - if (e.id === "recent") { + const recent = e.id === "recent"; + + const filterStorageItem = user?.id + ? recent + ? localStorage.getItem(`UserFilterRecent=${user.id}`) + : localStorage.getItem(`UserFilter=${user.id}`) + : null; + + if (filterStorageItem) { + const splitFilter = filterStorageItem.split(","); + + filter.sortBy = splitFilter[0]; + filter.sortOrder = splitFilter[1]; + } else if (recent) filter.sortBy = "LastOpened"; + + if (recent) { filter.folder = e.id; filter.searchArea = 3; - filter.sortBy = "LastOpened"; - } else { - filter.searchArea = null; - } + } else filter.searchArea = null; setFilter(filter); window.DocSpace.navigate(`${url}?${filter.toUrlParams()}`); @@ -83,17 +96,18 @@ const MyDocumentsTabs = ({ }; export default inject( - ({ treeFoldersStore, filesStore, clientLoadingStore }) => { + ({ treeFoldersStore, filesStore, clientLoadingStore, userStore }) => { const { isPersonalRoom, isRecentTab, isRoot } = treeFoldersStore; const { setFilter } = filesStore; const { showBodyLoader } = clientLoadingStore; - + const { user } = userStore; return { isPersonalRoom, isRecentTab, setFilter, showBodyLoader, isRoot, + user, }; }, )(observer(MyDocumentsTabs)); diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index a9b411b295..e22ae4dbfc 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -1942,7 +1942,7 @@ class ContextOptionsStore { selection.findIndex((k) => k.security.Download) !== -1; const favoriteItems = selection.filter((k) => - k.contextOptions.includes("mark-as-favorite"), + k.contextOptions?.includes("mark-as-favorite"), ); const moveItems = selection.filter((k) => diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 601f0fd738..4ef3e4d9d3 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -1459,6 +1459,23 @@ class FilesActionStore { filter.folder = id; + if (isRoom) { + const key = + categoryType === CategoryType.Archive + ? `UserFilterArchiveRoom=${this.userStore.user?.id}` + : `UserFilterSharedRoom=${this.userStore.user?.id}`; + + const filterStorageSharedRoom = + this.userStore.user?.id && localStorage.getItem(key); + + if (filterStorageSharedRoom) { + const splitFilter = filterStorageSharedRoom.split(","); + + filter.sortBy = splitFilter[0]; + filter.sortOrder = splitFilter[1]; + } + } + const url = getCategoryUrl(categoryType, id); window.DocSpace.navigate(`${url}?${filter.toUrlParams()}`, { state }); @@ -2334,7 +2351,8 @@ class FilesActionStore { onMarkAsRead = (item) => this.markAsRead([], [`${item.id}`], item); openFileAction = (item, t, e) => { - const { openDocEditor, isPrivacyFolder, setSelection } = this.filesStore; + const { openDocEditor, isPrivacyFolder, setSelection, categoryType } = + this.filesStore; const { currentDeviceType } = this.settingsStore; const { fileItemsList } = this.pluginStore; const { enablePlugins } = this.settingsStore; @@ -2384,6 +2402,30 @@ class FilesActionStore { ); const filter = FilesFilter.getDefault(); + + const filterObj = FilesFilter.getFilter(window.location); + + if (isRoom) { + const key = + categoryType === CategoryType.Archive + ? `UserFilterArchiveRoom=${this.userStore.user?.id}` + : `UserFilterSharedRoom=${this.userStore.user?.id}`; + + const filterStorageSharedRoom = + this.userStore.user?.id && localStorage.getItem(key); + + if (filterStorageSharedRoom) { + const splitFilter = filterStorageSharedRoom.split(","); + + filter.sortBy = splitFilter[0]; + filter.sortOrder = splitFilter[1]; + } + } else { + // For the document section at all levels there is one sorting + filter.sortBy = filterObj.sortBy; + filter.sortOrder = filterObj.sortOrder; + } + filter.folder = id; const url = `${path}?${filter.toUrlParams()}`; @@ -2605,6 +2647,11 @@ class FilesActionStore { const filter = FilesFilter.getDefault(); + const filterObj = FilesFilter.getFilter(window.location); + + filter.sortBy = filterObj.sortBy; + filter.sortOrder = filterObj.sortOrder; + filter.folder = id; const categoryType = getCategoryType(window.DocSpace.location); diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 24db897f0f..969c227316 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -72,7 +72,7 @@ import debounce from "lodash.debounce"; import clone from "lodash/clone"; import Queue from "queue-promise"; import { parseHistory } from "SRC_DIR/pages/Home/InfoPanel/Body/helpers/HistoryHelper"; - +import { toJSON } from "@docspace/shared/api/rooms/filter"; const { FilesFilter, RoomsFilter } = api; const storageViewAs = localStorage.getItem("viewAs"); @@ -1300,10 +1300,24 @@ class FilesStore { }; //TODO: FILTER - setFilesFilter = (filter) => { - if (!this.publicRoomStore.isPublicRoom) { - const key = `UserFilter=${this.userStore.user?.id}`; - const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; + setFilesFilter = (filter, folderId = null) => { + const { recycleBinFolderId } = this.treeFoldersStore; + + const key = + this.categoryType === CategoryType.Archive + ? `UserFilterArchiveRoom=${this.userStore.user?.id}` + : this.categoryType === CategoryType.SharedRoom + ? `UserFilterSharedRoom=${this.userStore.user?.id}` + : folderId === "recent" + ? `UserFilterRecent=${this.userStore.user?.id}` + : +folderId === recycleBinFolderId + ? `UserFilterTrash=${this.userStore.user?.id}` + : !this.publicRoomStore.isPublicRoom + ? `UserFilter=${this.userStore.user?.id}` + : null; + + if (key) { + const value = `${filter.sortBy},${filter.sortOrder}`; localStorage.setItem(key, value); } @@ -1330,6 +1344,21 @@ class FilesStore { setRoomsFilter = (filter) => { if (!this.settingsStore.withPaging) filter.pageCount = 100; + const isArchive = this.categoryType === CategoryType.Archive; + + const key = isArchive + ? `UserRoomsArchivedFilter=${this.userStore.user?.id}` + : `UserRoomsSharedFilter=${this.userStore.user?.id}`; + + const sharedStorageFilter = JSON.parse(localStorage.getItem(key)); + if (sharedStorageFilter) { + sharedStorageFilter.sortBy = filter.sortBy; + sharedStorageFilter.sortOrder = filter.sortOrder; + + const value = toJSON(sharedStorageFilter); + localStorage.setItem(key, value); + } + // this.setFilterUrl(filter, true); this.roomsFilter = filter; @@ -1463,8 +1492,7 @@ class FilesStore { const splitFilter = filterStorageItem.split(","); filterData.sortBy = splitFilter[0]; - filterData.pageCount = +splitFilter[1]; - filterData.sortOrder = splitFilter[2]; + filterData.sortOrder = splitFilter[1]; } if (!this.settingsStore.withPaging) { @@ -1540,7 +1568,7 @@ class FilesStore { //save filter for after closing preview change url this.setTempFilter(filterData); } else { - this.setFilesFilter(filterData); //TODO: FILTER + this.setFilesFilter(filterData, folderId); //TODO: FILTER } const isPrivacyFolder = diff --git a/packages/client/src/store/InviteLinksStore.js b/packages/client/src/store/InviteLinksStore.js index 550ffbc6fa..ad26f54fe0 100644 --- a/packages/client/src/store/InviteLinksStore.js +++ b/packages/client/src/store/InviteLinksStore.js @@ -27,9 +27,12 @@ import { makeAutoObservable, runInAction } from "mobx"; import { getInvitationLinks, + getInvitationLink, getShortenedLink, } from "@docspace/shared/api/portal"; +import { EmployeeType } from "@docspace/shared/enums"; + class InviteLinksStore { peopleStore = null; userLink = null; @@ -59,9 +62,7 @@ class InviteLinksStore { }; getPortalInviteLinks = async () => { - const isViewerAdmin = !this.peopleStore.authStore.isVisitor; - - if (!isViewerAdmin) return Promise.resolve(); + if (this.peopleStore.authStore.isVisitor) return Promise.resolve(); const links = await getInvitationLinks(); @@ -73,6 +74,31 @@ class InviteLinksStore { }); }; + getPortalInviteLink = async (type) => { + if (this.peopleStore.authStore.isVisitor) return Promise.resolve(); + + const link = await getInvitationLink(type); + + runInAction(() => { + switch (type) { + case EmployeeType.User: + this.setUserLink(link); + break; + case EmployeeType.Guest: + this.setGuestLink(link); + break; + case EmployeeType.Admin: + this.setAdminLink(link); + break; + case EmployeeType.Collaborator: + this.setCollaboratorLink(link); + break; + } + }); + + return link; + }; + getShortenedLink = async (link, forUser = false) => { if (forUser) { const userLink = await getShortenedLink(link); diff --git a/packages/doceditor/package.json b/packages/doceditor/package.json index a9827b8705..9e8f08dcd1 100644 --- a/packages/doceditor/package.json +++ b/packages/doceditor/package.json @@ -1,6 +1,6 @@ { "name": "@docspace/doceditor", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "build": "node ./scripts/buildTranslations.js && next build", diff --git a/packages/doceditor/src/components/completed-form/CompletedForm.styled.ts b/packages/doceditor/src/components/completed-form/CompletedForm.styled.ts index e63e06b173..e810bc9a19 100644 --- a/packages/doceditor/src/components/completed-form/CompletedForm.styled.ts +++ b/packages/doceditor/src/components/completed-form/CompletedForm.styled.ts @@ -27,33 +27,61 @@ import styled from "styled-components"; -import { mobile } from "@docspace/shared/utils"; +import { mobile, mobileMore } from "@docspace/shared/utils"; import type { CompletedFormLayoutProps } from "./CompletedForm.types"; -export const CompletedFormLayout = styled.section` - display: flex; - align-items: center; - flex-direction: column; - +export const ContainerCompletedForm = styled.section` box-sizing: border-box; * { box-sizing: border-box; } - width: 100%; - min-height: 100dvh; - padding: 100px 16px 16px; - background-image: ${(props) => props.bgPattern}; background-repeat: no-repeat; background-attachment: fixed; background-size: cover; background-position: center; + width: 100%; + min-height: 100dvh; + height: 100%; + + .scroller { + > .scroll-body { + display: flex; + flex-direction: column; + padding-inline-end: 16px !important; + } + } + + .completed-form__default-layout { + padding: clamp(42px, 8vh, 100px) 16px 16px; + + picture { + } + } + + @media ${mobile} { + .completed-form__default-layout { + padding: 0px 16px 16px; + } + + background-image: none; + } +`; + +export const CompletedFormLayout = styled.div` + display: flex; + align-items: center; + flex-direction: column; + + padding: clamp(42px, 8vh, 100px) 0px 16px 16px; + picture { - margin-bottom: clamp(40px, 10vh, 125px); + margin-bottom: clamp(40px, 8vh, 125px); + user-select: none; } .link { @@ -68,9 +96,14 @@ export const CompletedFormLayout = styled.section` margin-top: 24px; } - @media ${mobile} { - background-image: none; + @media ${mobileMore} and (max-height: 650px) { + padding-top: 42px; + .completed-form__logo { + margin-bottom: 40px; + } + } + @media ${mobile} { padding-top: 0px; .completed-form__icon { @@ -95,6 +128,11 @@ export const CompletedFormLayout = styled.section` align-self: center; } } + + .completed-form__empty { + gap: 20px; + margin-top: 24px; + } } `; @@ -228,6 +266,19 @@ export const FormNumberWrapper = styled.div` grid-area: form-number; + .form-number--big { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + + @media ${mobileMore} { + .form-number--big { + font-size: 23px; + line-height: 28px; + } + } + > div { justify-content: center; flex-grow: 1; diff --git a/packages/doceditor/src/components/completed-form/CompletedForm.tsx b/packages/doceditor/src/components/completed-form/CompletedForm.tsx index fa36983c63..0bfb20af4a 100644 --- a/packages/doceditor/src/components/completed-form/CompletedForm.tsx +++ b/packages/doceditor/src/components/completed-form/CompletedForm.tsx @@ -46,10 +46,11 @@ import { isNullOrUndefined } from "@docspace/shared/utils/typeGuards"; import { Button, ButtonSize } from "@docspace/shared/components/button"; import { WhiteLabelLogoType } from "@docspace/shared/enums"; -import { mobile, mobileMore } from "@docspace/shared/utils"; +import { classNames, mobile, mobileMore } from "@docspace/shared/utils"; import { Heading, HeadingLevel } from "@docspace/shared/components/heading"; import { IconButton } from "@docspace/shared/components/icon-button"; import { copyShareLink } from "@docspace/shared/utils/copy"; +import { Scrollbar } from "@docspace/shared/components/scrollbar"; import { Avatar, @@ -69,10 +70,13 @@ import { FormNumberWrapper, ManagerWrapper, MainContent, + ContainerCompletedForm, } from "./CompletedForm.styled"; import type { CompletedFormProps } from "./CompletedForm.types"; +const BIG_FORM_NUMBER = 9_999_999; + export const CompletedForm = ({ session, share, @@ -92,25 +96,29 @@ export const CompletedForm = ({ if (!session) return ( - - - - - logo - - icon - - {t("CompletedForm:Title")} - {t("CompletedForm:Description")} - - + + + + + + logo + + icon + + + {t("CompletedForm:Title")} + + {t("CompletedForm:Description")} + + + ); const { @@ -172,85 +180,100 @@ export const CompletedForm = ({ }); return ( - - - - - logo - - - - {t("CompletedForm:FormCompletedSuccessfully")} - - - {isAnonim - ? t("CompletedForm:DescriptionForAnonymous") - : t("CompletedForm:DescriptionForRegisteredUser")} - - - - - - - {completedForm.title} - - - - - {t("CompletedForm:FormNumber")} - - {formNumber} - - - - {t("CompletedForm:FormOwner")} - - - - {decode(manager.displayName)} + + + + + + + logo + + + + {t("CompletedForm:FormCompletedSuccessfully")} - - - {manager.email} - - - - - -