diff --git a/packages/client/package.json b/packages/client/package.json index e68d87aa19..a158bf611b 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -73,6 +73,7 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/webpack": "^5.5.0", + "@types/element-resize-detector": "^1.1.6", "@types/eslint": "^8.44.7", "@types/he": "^1.2.3", "@typescript-eslint/eslint-plugin": "^6.12.0", diff --git a/packages/client/public/locales/en/InviteDialog.json b/packages/client/public/locales/en/InviteDialog.json index 5874d94ca0..cfe716db99 100644 --- a/packages/client/public/locales/en/InviteDialog.json +++ b/packages/client/public/locales/en/InviteDialog.json @@ -2,7 +2,7 @@ "AddManually": "Add manually", "AddManuallyDescriptionAccounts": "Invite new users to {{productName}} personally via email", "AddManuallyDescriptionRoom": "Add existing {{productName}} users to the room using the names or invite new users personally via email", - "EmailErrorMessage": "Email address is not valid. You can edit the email by clicking on it.", + "EmailErrorMessage": "Email address not valid. You can edit the email by double-clicking on it.", "GroupMaxAvailableRoleWarning": "Groups can be added to a room with the {{roleName}} role as maximum. However, you can change the role of individual users in the group after it has been successfully added.", "InvitationLanguage": "Invitation language", "InviteAccountSearchPlaceholder": "Invite people by email", diff --git a/packages/client/src/components/EmptyContainer/index.js b/packages/client/src/components/EmptyContainer/index.js index 3abb285a6b..bbddb8e054 100644 --- a/packages/client/src/components/EmptyContainer/index.js +++ b/packages/client/src/components/EmptyContainer/index.js @@ -23,10 +23,12 @@ // All the Product's GUI elements, including illustrations and icon sets, as well as technical writing // 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 { useContext } from "react"; import { observer, inject } from "mobx-react"; //import { useLocation } from "react-router-dom"; +import { Context } from "@docspace/shared/utils"; import { Events, FileExtensions } from "@docspace/shared/enums"; import RootFolderContainer from "./RootFolderContainer"; @@ -49,7 +51,6 @@ const EmptyContainer = ({ theme, type, - sectionWidth, isRoomNotFoundOrMoved, isGracePeriod, setQuotaWarningDialogVisible, @@ -60,6 +61,8 @@ const EmptyContainer = ({ }) => { //const location = useLocation(); + const { sectionWidth } = useContext(Context); + linkStyles.color = theme.filesEmptyContainer.linkColor; const onCreate = (e) => { diff --git a/packages/client/src/components/FilesSelector/FilesSelector.types.ts b/packages/client/src/components/FilesSelector/FilesSelector.types.ts index ffb6752146..62d246bf57 100644 --- a/packages/client/src/components/FilesSelector/FilesSelector.types.ts +++ b/packages/client/src/components/FilesSelector/FilesSelector.types.ts @@ -29,12 +29,15 @@ import { TFilesSettings, TFolder, } from "@docspace/shared/api/files/types"; -import { TBreadCrumb } from "@docspace/shared/components/selector/Selector.types"; +import { + TBreadCrumb, + TSelectorHeader, +} from "@docspace/shared/components/selector/Selector.types"; import { DeviceType } from "@docspace/shared/enums"; import { TTheme } from "@docspace/shared/themes"; import SocketIOHelper from "@docspace/shared/utils/socket"; -export type FilesSelectorProps = { +export type FilesSelectorProps = TSelectorHeader & { isPanelVisible: boolean; // withoutImmediatelyClose: boolean; isThirdParty: boolean; diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 1e95e8ab26..a8d133eb90 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -140,6 +140,7 @@ const FilesSelectorWrapper = ({ openRoot, filesSettings, + headerProps, }: FilesSelectorProps) => { const { t }: { t: TTranslation } = useTranslation([ "Files", @@ -392,6 +393,7 @@ const FilesSelectorWrapper = ({ getFilesArchiveError={getFilesArchiveError} withCreate={(isMove || isCopy || isRestore || isRestoreAll) ?? false} filesSettings={filesSettings} + headerProps={headerProps} /> ); }; diff --git a/packages/client/src/components/Main/index.js b/packages/client/src/components/Main/index.js index 3d6e8fc76b..eae6a1982f 100644 --- a/packages/client/src/components/Main/index.js +++ b/packages/client/src/components/Main/index.js @@ -76,10 +76,12 @@ const Main = (props) => { if (mainBarVisible && isMobileUtils()) { const mainBar = document.getElementById("main-bar"); - if (!mainBar.offsetHeight) - return (updateSizeRef.current = setTimeout(() => onResize(), 0)); + if (mainBar) { + if (!mainBar?.offsetHeight) + return (updateSizeRef.current = setTimeout(() => onResize(), 0)); - correctHeight -= mainBar.offsetHeight; + correctHeight -= mainBar?.offsetHeight; + } } const isTouchDevice = diff --git a/packages/client/src/components/RoomsSelectorInput/index.js b/packages/client/src/components/RoomsSelectorInput/index.js index bac3c36877..d5772fb893 100644 --- a/packages/client/src/components/RoomsSelectorInput/index.js +++ b/packages/client/src/components/RoomsSelectorInput/index.js @@ -105,7 +105,7 @@ const RoomsSelectorInput = (props) => { submitButtonLabel={submitButtonLabel} onSubmit={handleOnSubmit} withHeader={withHeader} - headerProps={headerProps} + headerProps={{ ...headerProps, onCloseClick: onClose }} setIsDataReady={setIsDataReady} roomType={roomType} /> @@ -137,6 +137,7 @@ const RoomsSelectorInput = (props) => { withoutBodyScroll zIndex={310} onClose={onClose} + withoutHeader > {SelectorBody} diff --git a/packages/client/src/components/dialogs/ChangePortalOwnerDialog/index.js b/packages/client/src/components/dialogs/ChangePortalOwnerDialog/index.js index eb5b62bfcd..a4f8d2d6ea 100644 --- a/packages/client/src/components/dialogs/ChangePortalOwnerDialog/index.js +++ b/packages/client/src/components/dialogs/ChangePortalOwnerDialog/index.js @@ -154,6 +154,7 @@ const ChangePortalOwnerDialog = ({ disableSubmitButton={false} withHeader headerProps={{ + onCloseClick: onCloseAction, onBackClick, withoutBackButton: false, headerLabel: "", diff --git a/packages/client/src/components/dialogs/ChangePricingPlanDialog/index.js b/packages/client/src/components/dialogs/ChangePricingPlanDialog/index.js index bd78a132b7..2914257078 100644 --- a/packages/client/src/components/dialogs/ChangePricingPlanDialog/index.js +++ b/packages/client/src/components/dialogs/ChangePricingPlanDialog/index.js @@ -97,11 +97,7 @@ const ChangePricingPlanDialog = ({ isLarge isLoading={!ready} > - - - {t("ChangePricingPlan")} - - + {t("ChangePricingPlan")} {t("CannotChangePlan")} diff --git a/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/StyledComponent.js b/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/StyledComponent.js deleted file mode 100644 index 1cb1b9eb35..0000000000 --- a/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/StyledComponent.js +++ /dev/null @@ -1,36 +0,0 @@ -// (c) Copyright Ascensio System SIA 2009-2024 -// -// This program is a free software product. -// You can redistribute it and/or modify it under the terms -// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software -// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended -// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of -// any third-party rights. -// -// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see -// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html -// -// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. -// -// The interactive user interfaces in modified source and object code versions of the Program must -// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. -// -// Pursuant to Section 7(b) of the License you must retain the original Product logo when -// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under -// trademark law for use of our trademarks. -// -// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing -// 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 styled from "styled-components"; - -import { ModalDialog } from "@docspace/shared/components/modal-dialog"; - -const StyledModalDialog = styled(ModalDialog)` - p { - margin-bottom: 16px; - } -`; -export default StyledModalDialog; diff --git a/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/index.js b/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/index.js index 66ad2a3dc2..922d9a696d 100644 --- a/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/index.js +++ b/packages/client/src/components/dialogs/ChangeStorageQuotaDialog/index.js @@ -34,7 +34,6 @@ import { toastr } from "@docspace/shared/components/toast"; import { setTenantQuotaSettings } from "@docspace/shared/api/settings"; import QuotaForm from "../../../components/QuotaForm"; -import StyledModalDialog from "./StyledComponent"; const ChangeStorageQuotaDialog = (props) => { const { @@ -115,7 +114,7 @@ const ChangeStorageQuotaDialog = (props) => { }; return ( - + {isDisableQuota ? t("Common:DisableStorageQuota") @@ -159,7 +158,7 @@ const ChangeStorageQuotaDialog = (props) => { scale /> - + ); }; diff --git a/packages/client/src/components/dialogs/ConflictResolveDialog/index.tsx b/packages/client/src/components/dialogs/ConflictResolveDialog/index.tsx index 2014f089d1..100b58461e 100644 --- a/packages/client/src/components/dialogs/ConflictResolveDialog/index.tsx +++ b/packages/client/src/components/dialogs/ConflictResolveDialog/index.tsx @@ -37,6 +37,7 @@ import { ConflictResolveDialogProps, TActiveItem, } from "./ConflictResolveDialog.types"; +import { Text } from "@docspace/shared/components/text"; const ConflictResolveDialog = (props: ConflictResolveDialogProps) => { const { @@ -217,7 +218,7 @@ const ConflictResolveDialog = (props: ConflictResolveDialogProps) => { ns="Common" i18nKey="FileActionRequired" values={{ fileName: items[0].title }} - components={{ 1: }} + components={{ 1: }} /> ); diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/CreateRoomDialog.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/CreateRoomDialog.js index 2fadca655d..50988c27c2 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/CreateRoomDialog.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/CreateRoomDialog.js @@ -33,7 +33,6 @@ import TagHandler from "./handlers/TagHandler"; import SetRoomParams from "./sub-components/SetRoomParams"; import RoomTypeList from "./sub-components/RoomTypeList"; -import DialogHeader from "./sub-components/DialogHeader"; const StyledModalDialog = styled(ModalDialog)` .header-with-button { @@ -161,6 +160,10 @@ const CreateRoomDialog = ({ onClose(); }; + const dialogHeader = roomParams.type + ? t("ChooseRoomType") + : t("Files:CreateRoom"); + return ( - - - + {dialogHeader} {!roomParams.type ? ( diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/EditRoomDialog.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/EditRoomDialog.js index bbc27807a2..9a7c7fefa6 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/EditRoomDialog.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/EditRoomDialog.js @@ -28,7 +28,6 @@ import React, { useState, useEffect, useRef, useCallback } from "react"; import TagHandler from "./handlers/TagHandler"; import SetRoomParams from "./sub-components/SetRoomParams"; -import DialogHeader from "./sub-components/DialogHeader"; import { ModalDialog } from "@docspace/shared/components/modal-dialog"; import { Button } from "@docspace/shared/components/button"; @@ -132,9 +131,7 @@ const EditRoomDialog = ({ isScrollLocked={isScrollLocked} withFooterBorder > - - - + {t("RoomEditing")} { - return ( - <> - {isEdit ? ( - {t("RoomEditing")} - ) : isChooseRoomType ? ( - {t("ChooseRoomType")} - ) : ( -
- {!disabledIcon && ( - - )} -
{t("Files:CreateRoom")}
-
- )} - - ); -}; - -export default withTranslation(["CreateEditRoomDialog", "Files"])( - withLoader(DialogHeader)(), -); diff --git a/packages/client/src/components/dialogs/DataReassignmentDialog/index.js b/packages/client/src/components/dialogs/DataReassignmentDialog/index.js index 610bf529d1..53d02ddf7d 100644 --- a/packages/client/src/components/dialogs/DataReassignmentDialog/index.js +++ b/packages/client/src/components/dialogs/DataReassignmentDialog/index.js @@ -227,6 +227,7 @@ const DataReassignmentDialog = ({ withCancelButton cancelButtonLabel="" headerProps={{ + onCloseClick: onClose, onBackClick: onClosePeopleSelector, withoutBackButton: false, headerLabel: "", diff --git a/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx b/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx index 52304481fe..daef7c5006 100644 --- a/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx +++ b/packages/client/src/components/dialogs/EditGroupMembersDialog/sub-components/GroupMember/index.tsx @@ -43,7 +43,7 @@ import { toastr } from "@docspace/shared/components/toast"; import { HelpButton } from "@docspace/shared/components/help-button"; import { getUserRoleOptions } from "@docspace/shared/utils/room-members/getUserRoleOptions"; import { ShareAccessRights } from "@docspace/shared/enums"; -import { getUserRole } from "@docspace/shared/utils/common"; +import { getUserRole, getUserTypeLabel } from "@docspace/shared/utils/common"; import { TGroupMemberInvitedInRoom } from "@docspace/shared/api/groups/types"; import * as Styled from "./index.styled"; @@ -59,7 +59,7 @@ const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => { const [isLoading, setIsLoading] = useState(false); const { t } = useTranslation("Common"); - const userRole = user.isOwner + const userRole = member.owner ? getUserRoleOptions(t).portalAdmin : getUserRoleOptionsByUserAccess( t, @@ -74,6 +74,10 @@ const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => { const userRoleOptions = filterUserRoleOptions(fullRoomRoleOptions, user); + const hasIndividualRightsInRoom = + member.owner || + (member.userAccess && member.userAccess !== member.groupAccess); + let type; if (user.isOwner) type = "owner"; else if (user.isAdmin) type = "admin"; @@ -83,6 +87,11 @@ const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => { const role = getUserRole(user, userRole?.type); + const typeLabel = getUserTypeLabel( + role as "owner" | "admin" | "user" | "collaborator" | "manager", + t, + ); + let selectedUserRoleCBOption; if (user.isOwner) selectedUserRoleCBOption = { @@ -140,26 +149,25 @@ const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => { {decode(user.displayName)}
- {user.email} + {typeLabel} |{" "} + {user.email}
- {member.userAccess && - member.userAccess !== member.groupAccess && - !user.isOwner && ( - - {t("PeopleTranslations:IndividualRights")} - - } - /> - )} + {hasIndividualRightsInRoom && ( + + {t("PeopleTranslations:IndividualRights")} + + } + /> + )}
{userRole && userRoleOptions && ( diff --git a/packages/client/src/components/panels/AddUsersPanel/index.tsx b/packages/client/src/components/panels/AddUsersPanel/index.tsx index aeab566c06..5dc57f558b 100644 --- a/packages/client/src/components/panels/AddUsersPanel/index.tsx +++ b/packages/client/src/components/panels/AddUsersPanel/index.tsx @@ -529,6 +529,7 @@ const AddUsersPanel = ({ visible={visible} onClose={onClosePanels} withoutBodyScroll + withoutHeader > - - - {t("ChangeOwner", { fileName })} - -
{ className="header_aside-panel" visible={visible} onClose={onClose} + withoutHeader withoutBodyScroll > { disableSubmitButton={false} withHeader headerProps={{ + onCloseClick: onClose, onBackClick, withoutBackButton: !showBackButton, headerLabel: t("Files:ChangeTheRoomOwner"), diff --git a/packages/client/src/components/panels/EmbeddingPanel/StyledEmbeddingPanel.js b/packages/client/src/components/panels/EmbeddingPanel/StyledEmbeddingPanel.js index ebd8c282c1..3ff51f670e 100644 --- a/packages/client/src/components/panels/EmbeddingPanel/StyledEmbeddingPanel.js +++ b/packages/client/src/components/panels/EmbeddingPanel/StyledEmbeddingPanel.js @@ -28,10 +28,6 @@ import styled, { css } from "styled-components"; import { ModalDialog } from "@docspace/shared/components/modal-dialog"; const StyledModalDialog = styled(ModalDialog)` - .modal-header { - margin: 0; - } - .modal-body { padding: 0; } diff --git a/packages/client/src/components/panels/HotkeysPanel/StyledHotkeys.js b/packages/client/src/components/panels/HotkeysPanel/StyledHotkeys.js index b4f40c7186..e6200a3cae 100644 --- a/packages/client/src/components/panels/HotkeysPanel/StyledHotkeys.js +++ b/packages/client/src/components/panels/HotkeysPanel/StyledHotkeys.js @@ -43,16 +43,6 @@ const StyledHotkeysPanel = styled.div` } } - .hotkeys_header { - padding: 0 16px; - border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom}; - - .hotkeys_heading { - font-weight: 700; - font-size: 18px; - } - } - .hotkeys_sub-header { font-weight: 700; font-size: 16px; diff --git a/packages/client/src/components/panels/HotkeysPanel/index.js b/packages/client/src/components/panels/HotkeysPanel/index.js index 17c090f81c..3a4c959d4e 100644 --- a/packages/client/src/components/panels/HotkeysPanel/index.js +++ b/packages/client/src/components/panels/HotkeysPanel/index.js @@ -90,10 +90,8 @@ const HotkeyPanel = ({ visible={visible} onClose={onClose} withoutBodyScroll={true} + header={t("Common:Hotkeys")} > -
- {t("Common:Hotkeys")} -
{t("HotkeysNavigation")} diff --git a/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js b/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js index 25669afd61..fbf9f8de3f 100644 --- a/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js +++ b/packages/client/src/components/panels/InvitePanel/StyledInvitePanel.js @@ -38,7 +38,6 @@ import { ToggleButton } from "@docspace/shared/components/toggle-button"; import { mobile, commonIconsStyles } from "@docspace/shared/utils"; import CheckIcon from "PUBLIC_DIR/images/check.edit.react.svg"; import CrossIcon from "PUBLIC_DIR/images/cross.edit.react.svg"; -import CrossIconMobile from "PUBLIC_DIR/images/cross.react.svg"; import DeleteIcon from "PUBLIC_DIR/images/mobile.actions.remove.react.svg"; import { isMobile, desktop, commonInputStyles } from "@docspace/shared/utils"; import Base from "@docspace/shared/themes/base"; @@ -124,24 +123,15 @@ const ScrollList = styled.div` } `; -const StyledBlock = styled.div` - padding: ${(props) => (props.noPadding ? "0px" : "0 16px")}; +const StyledExternalLink = styled.div` border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom}; `; - -StyledBlock.defaultProps = { theme: Base }; - const StyledInviteUserBody = styled.div` display: flex; flex-direction: column; overflow: auto; `; -const StyledHeading = styled(Heading)` - font-weight: 700; - font-size: 18px; -`; - const StyledSubHeader = styled(Heading)` font-weight: 700; font-size: 16px; @@ -440,14 +430,6 @@ StyledCrossIcon.defaultProps = { theme: Base }; const StyledDeleteIcon = styled(DeleteIcon)` cursor: pointer; - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: auto; - ` - : css` - margin-left: auto; - `} ${iconStyles} `; @@ -501,25 +483,6 @@ const StyledToggleButton = styled(ToggleButton)` margin-top: -4px; `; -const StyledControlContainer = styled.div` - width: 17px; - height: 17px; - position: absolute; - - cursor: pointer; - - align-items: center; - justify-content: center; - z-index: 450; - - @media ${mobile} { - display: flex; - - top: -27px; - right: 10px; - left: unset; - } -`; const StyledInviteLanguage = styled.div` padding-left: 16px; padding-right: 16px; @@ -574,19 +537,17 @@ const StyledInviteLanguage = styled.div` gap: 2px; } `; -const StyledCrossIconMobile = styled(CrossIconMobile)` - width: 17px; - height: 17px; - z-index: 455; - path { - fill: ${(props) => props.theme.catalog.control.fill}; - } -`; StyledCrossIcon.defaultProps = { theme: Base }; + +const ErrorWrapper = styled.div` + display: flex; + flex-wrap: nowrap; + gap: 12px; + margin-inline-start: auto; +`; + export { - StyledBlock, - StyledHeading, StyledInvitePanel, StyledRow, StyledSubHeader, @@ -608,7 +569,7 @@ export { StyledToggleButton, StyledDescription, StyledInviteLanguage, - StyledControlContainer, - StyledCrossIconMobile, StyledInviteUserBody, + StyledExternalLink, + ErrorWrapper, }; diff --git a/packages/client/src/components/panels/InvitePanel/index.js b/packages/client/src/components/panels/InvitePanel/index.js index 29047271a8..fca73f9079 100644 --- a/packages/client/src/components/panels/InvitePanel/index.js +++ b/packages/client/src/components/panels/InvitePanel/index.js @@ -38,20 +38,13 @@ import { DeviceType, EmployeeType } from "@docspace/shared/enums"; import { LOADER_TIMEOUT } from "@docspace/shared/constants"; import { Backdrop } from "@docspace/shared/components/backdrop"; -import { Aside } from "@docspace/shared/components/aside"; +import { Aside, AsideHeader } from "@docspace/shared/components/aside"; import { Button } from "@docspace/shared/components/button"; import { toastr } from "@docspace/shared/components/toast"; import { Portal } from "@docspace/shared/components/portal"; import { isDesktop, isMobile, size } from "@docspace/shared/utils"; -import { - StyledBlock, - StyledHeading, - StyledInvitePanel, - StyledButtons, - StyledControlContainer, - StyledCrossIconMobile, -} from "./StyledInvitePanel"; +import { StyledInvitePanel, StyledButtons } from "./StyledInvitePanel"; import ItemsList from "./sub-components/ItemsList"; import InviteInput from "./sub-components/InviteInput"; @@ -60,7 +53,7 @@ import { Scrollbar } from "@docspace/shared/components/scrollbar"; import InfoBar from "./sub-components/InfoBar"; import InvitePanelLoader from "./sub-components/InvitePanelLoader"; -import { Link } from "@docspace/shared/components/link"; + import { Text } from "@docspace/shared/components/text"; import { combineUrl } from "@docspace/shared/utils/combineUrl"; import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme"; @@ -429,9 +422,6 @@ const InvitePanel = ({ const invitePanelNode = ( <> - - {t("Common:InviteUsers")} - {invitePanelIsLoding ? ( ) : ( @@ -479,9 +469,11 @@ const InvitePanel = ({ > {isMobileView ? (
- - - + + {invitePanelNode}
) : ( @@ -498,6 +490,7 @@ const InvitePanel = ({ onClose={onClose} withoutBodyScroll zIndex={310} + header={t("Common:InviteUsers")} > {invitePanelNode} 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 e52f3623a0..e267dab9bb 100644 --- a/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js +++ b/packages/client/src/components/panels/InvitePanel/sub-components/ExternalLinks.js @@ -45,12 +45,12 @@ import { Text } from "@docspace/shared/components/text"; import AccessSelector from "../../../AccessSelector"; import PaidQuotaLimitError from "../../../PaidQuotaLimitError"; import { - StyledBlock, StyledSubHeader, StyledInviteInput, StyledInviteInputContainer, StyledToggleButton, StyledDescription, + StyledExternalLink, } from "../StyledInvitePanel"; import { getFreeUsersRoleArray, getFreeUsersTypeArray } from "../utils"; @@ -212,7 +212,7 @@ const ExternalLinks = ({ roomId === -1 ? getFreeUsersTypeArray() : getFreeUsersRoleArray(); return ( - + {t("InviteViaLink")} {false && ( //TODO: Change to linksVisible after added link information from backend @@ -285,7 +285,7 @@ const ExternalLinks = ({ /> )} - + ); }; diff --git a/packages/client/src/components/panels/InvitePanel/sub-components/Item.js b/packages/client/src/components/panels/InvitePanel/sub-components/Item.js index eb2fc0fdb2..aaeded37f4 100644 --- a/packages/client/src/components/panels/InvitePanel/sub-components/Item.js +++ b/packages/client/src/components/panels/InvitePanel/sub-components/Item.js @@ -49,6 +49,7 @@ import { StyledHelpButton, StyledDeleteIcon, StyledInviteUserBody, + ErrorWrapper, } from "../StyledInvitePanel"; import { filterGroupRoleOptions, filterUserRoleOptions } from "SRC_DIR/helpers"; import AccessSelector from "../../../AccessSelector"; @@ -229,7 +230,7 @@ const Item = ({ {hasError ? ( - <> + - + ) : ( <> {warning && ( diff --git a/packages/client/src/components/panels/StyledPanels.js b/packages/client/src/components/panels/StyledPanels.js index ad65ed113a..7599b7a77c 100644 --- a/packages/client/src/components/panels/StyledPanels.js +++ b/packages/client/src/components/panels/StyledPanels.js @@ -256,39 +256,6 @@ const StyledContent = styled.div` StyledContent.defaultProps = { theme: Base }; -const StyledHeaderContent = styled.div` - display: flex; - align-items: center; - padding: 0 16px; - - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: -16px; - ` - : css` - margin-right: -16px; - `} - - border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom}; - - .files-operations-header, - .sharing_panel-header { - font-weight: 700; - margin: 14px 0; - } - - @media ${desktop} { - .files-operations-header, - .sharing_panel-header { - margin: 12px 0; - font-size: 18px; - } - } -`; - -StyledHeaderContent.defaultProps = { theme: Base }; - const StyledBody = styled.div` &.files-operations-body { ${(props) => @@ -711,13 +678,6 @@ const StyledLink = styled(Link)` StyledModalRowContainer.defaultProps = { theme: Base }; -const StyledUploadHeader = styled.div` - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; -`; - const StyledUploadBody = styled.div` width: calc(100% + 16px); height: 100%; @@ -732,13 +692,11 @@ export { StyledEmbeddingPanel, StyledVersionHistoryPanel, StyledContent, - StyledHeaderContent, StyledBody, StyledFooter, StyledLinkRow, StyledModalRowContainer, StyledLink, StyledNewFilesBody, - StyledUploadHeader, StyledUploadBody, }; diff --git a/packages/client/src/components/panels/UploadPanel/index.js b/packages/client/src/components/panels/UploadPanel/index.js index dc0ee3c326..f220d9add2 100644 --- a/packages/client/src/components/panels/UploadPanel/index.js +++ b/packages/client/src/components/panels/UploadPanel/index.js @@ -39,9 +39,10 @@ import { } from "@docspace/shared/components/modal-dialog"; import { DialogAsideSkeleton } from "@docspace/shared/skeletons/dialog"; -import { StyledUploadHeader, StyledUploadBody } from "../StyledPanels"; +import { StyledUploadBody } from "../StyledPanels"; import FileList from "./FileList"; import withLoader from "../../../HOCs/withLoader"; +import { AsideHeader } from "@docspace/shared/components/aside"; const StyledModal = styled(ModalDialog)` .heading { @@ -124,34 +125,24 @@ class UploadPanelComponent extends React.Component { ? t("UploadAndConvert") : t("Files:Convert"); + const url = + uploaded && converted ? ClearReactSvgUrl : ButtonCancelReactSvgUrl; + + const clickEvent = + uploaded && converted + ? this.clearUploadPanel + : uploaded + ? cancelConversion + : this.onCancelUpload; + return ( - - -
{title}
-
- {uploaded && converted ? ( - - ) : ( - - )} -
-
-
+ {title} diff --git a/packages/client/src/components/panels/VersionHistoryPanel/index.js b/packages/client/src/components/panels/VersionHistoryPanel/index.js index 3a6f544781..00a17f3648 100644 --- a/packages/client/src/components/panels/VersionHistoryPanel/index.js +++ b/packages/client/src/components/panels/VersionHistoryPanel/index.js @@ -27,7 +27,6 @@ import React from "react"; import PropTypes from "prop-types"; import { Backdrop } from "@docspace/shared/components/backdrop"; -import { Heading } from "@docspace/shared/components/heading"; import { Aside } from "@docspace/shared/components/aside"; import { FloatingButton } from "@docspace/shared/components/floating-button"; @@ -37,13 +36,11 @@ import { withTranslation } from "react-i18next"; import { StyledVersionHistoryPanel, StyledContent, - StyledHeaderContent, StyledBody, } from "../StyledPanels"; import { SectionBodyContent } from "../../../pages/VersionHistory/Section/"; import { inject, observer } from "mobx-react"; import config from "PACKAGE_FILE"; -import { ArticleHeaderLoader } from "@docspace/shared/skeletons/article"; class PureVersionHistoryPanel extends React.Component { onClose = () => { @@ -85,26 +82,10 @@ class PureVersionHistoryPanel extends React.Component { visible={visible} onClose={this.onClose} withoutBodyScroll + isLoading={!versions && !isLoading} + header={versions ? versions[0].title : ""} > - - {versions && !isLoading ? ( - - {versions[0].title} - - ) : ( - - )} - - diff --git a/packages/client/src/pages/About/AboutContent.js b/packages/client/src/pages/About/AboutContent.js index eb462d49c1..839c521904 100644 --- a/packages/client/src/pages/About/AboutContent.js +++ b/packages/client/src/pages/About/AboutContent.js @@ -100,10 +100,18 @@ const StyledAboutBody = styled.div` `; const AboutContent = (props) => { - const { buildVersionInfo, theme, companyInfoSettingsData, previewData } = - props; - const { t } = useTranslation("About"); - const license = "AGPL-3.0"; + const { + buildVersionInfo, + theme, + companyInfoSettingsData, + previewData, + standalone, + licenseUrl, + isEnterprise, + } = props; + const { t } = useTranslation(["About", "Common"]); + const isCommercial = !standalone || isEnterprise; + const license = isCommercial ? t("Common:Commercial") : "AGPL-3.0"; const linkRepo = "https://github.com/ONLYOFFICE/DocSpace"; const linkDocs = "https://github.com/ONLYOFFICE/DocumentServer"; @@ -198,9 +206,25 @@ const AboutContent = (props) => { {t("SoftwareLicense")}:{" "} - -  {license} - + {isCommercial ? ( + +  {license} + + ) : ( + +  {license} + + )}
@@ -268,11 +292,16 @@ const AboutContent = (props) => { ); }; -export default inject(({ settingsStore }) => { - const { theme, companyInfoSettingsData } = settingsStore; +export default inject(({ settingsStore, currentTariffStatusStore }) => { + const { theme, companyInfoSettingsData, standalone, licenseUrl } = + settingsStore; + const { isEnterprise } = currentTariffStatusStore; return { theme, companyInfoSettingsData, + standalone, + licenseUrl, + isEnterprise, }; })(observer(AboutContent)); diff --git a/packages/client/src/pages/Confirm/sub-components/auth.js b/packages/client/src/pages/Confirm/sub-components/auth.js index 8c50e80aff..4a97cae98b 100644 --- a/packages/client/src/pages/Confirm/sub-components/auth.js +++ b/packages/client/src/pages/Confirm/sub-components/auth.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 React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Loader } from "@docspace/shared/components/loader"; import Section from "@docspace/shared/components/section"; @@ -42,6 +42,8 @@ const Auth = (props) => { let [searchParams, setSearchParams] = useSearchParams(); const { t } = useTranslation(["Common"]); + const [authorized, setAuthorized] = useState(false); + const referenceUrl = searchParams.get("referenceUrl"); const isFileHandler = referenceUrl && referenceUrl.indexOf("filehandler.ashx") !== -1; @@ -63,6 +65,7 @@ const Auth = (props) => { try { new URL(referenceUrl); if (isFileHandler && isExternalDownloading) { + setAuthorized(true); return; } else { return window.location.replace(referenceUrl); @@ -86,6 +89,7 @@ const Auth = (props) => { return isFileHandler && isExternalDownloading ? ( diff --git a/packages/client/src/pages/Confirm/withLoader.js b/packages/client/src/pages/Confirm/withLoader.js index 063d03e6f3..9a3793bbfd 100644 --- a/packages/client/src/pages/Confirm/withLoader.js +++ b/packages/client/src/pages/Confirm/withLoader.js @@ -55,6 +55,29 @@ export default function withLoader(WrappedComponent) { const navigate = useNavigate(); + const requestError = (error) => { + let errorMessage = ""; + + if (typeof error === "object") { + errorMessage = + error?.response?.data?.error?.message || + error?.statusText || + error?.message || + ""; + } else { + errorMessage = error; + } + + console.error(errorMessage); + + navigate( + combineUrl( + window.ClientConfig?.proxy?.url, + `/login/error?message=${errorMessage}`, + ), + ); + }; + const fetch = async () => { if (type === "EmpInvite" && email) { try { @@ -74,30 +97,15 @@ export default function withLoader(WrappedComponent) { ); return; - } catch (e) {} + } catch (error) { + requestError(error); + } } try { await getPortalPasswordSettings(confirmHeader); } catch (error) { - let errorMessage = ""; - if (typeof error === "object") { - errorMessage = - error?.response?.data?.error?.message || - error?.statusText || - error?.message || - ""; - } else { - errorMessage = error; - } - - console.error(errorMessage); - navigate( - combineUrl( - window.ClientConfig?.proxy?.url, - `/login/error?message=${errorMessage}`, - ), - ); + requestError(error); } }; @@ -116,23 +124,7 @@ export default function withLoader(WrappedComponent) { useEffect(() => { if (type === "LinkInvite" || type === "EmpInvite") { axios.all([getAuthProviders(), getCapabilities()]).catch((error) => { - let errorMessage = ""; - if (typeof error === "object") { - errorMessage = - error?.response?.data?.error?.message || - error?.statusText || - error?.message || - ""; - } else { - errorMessage = error; - } - console.error(errorMessage); - navigate( - combineUrl( - window.ClientConfig?.proxy?.url, - `/login/error?message=${errorMessage}`, - ), - ); + requestError(error); }); } }, []); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 2571a89865..4de14b05c2 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -98,6 +98,7 @@ const SortFilter = ({ t, oformsFilter, sortOforms }) => { fillIcon={false} options={[]} selectedOption={{}} + manualWidth={"auto"} advancedOptions={ <> {sortData?.map((item) => ( diff --git a/packages/client/src/pages/Home/InfoPanel/Header/index.js b/packages/client/src/pages/Home/InfoPanel/Header/index.js index 846a0ee01e..60c6419153 100644 --- a/packages/client/src/pages/Home/InfoPanel/Header/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Header/index.js @@ -24,14 +24,10 @@ // 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 CrossReactSvgUrl from "PUBLIC_DIR/images/icons/17/cross.react.svg?url"; import React, { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { IconButton } from "@docspace/shared/components/icon-button"; -import { Text } from "@docspace/shared/components/text"; - import { Tabs } from "@docspace/shared/components/tabs"; import { isDesktop as isDesktopUtils, @@ -43,6 +39,7 @@ import { StyledInfoPanelHeader } from "./styles/common"; import { PluginFileType } from "SRC_DIR/helpers/plugins/enums"; import { FolderType } from "@docspace/shared/enums"; +import { AsideHeader } from "@docspace/shared/components/aside"; const InfoPanelHeaderContent = (props) => { const { @@ -194,25 +191,12 @@ const InfoPanelHeaderContent = (props) => { return ( -
- - {t("Common:Info")} - - - {!isTablet && ( -
- -
- )} -
+ {withTabs && (
diff --git a/packages/client/src/pages/Home/InfoPanel/Header/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Header/styles/common.js index cdfa111ab7..440a14bd16 100644 --- a/packages/client/src/pages/Home/InfoPanel/Header/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Header/styles/common.js @@ -28,11 +28,11 @@ import styled, { css } from "styled-components"; import { Base } from "@docspace/shared/themes"; import { tablet } from "@docspace/shared/utils"; -const getHeaderHeight = ({ withTabs, isTablet }) => { - let res = isTablet ? 53 : 69; - if (withTabs) res += 32; - return `${res}px`; -}; +// const getHeaderHeight = ({ withTabs, isTablet }) => { +// let res = isTablet ? 54 : 70; +// if (withTabs) res += 32; +// return `${res}px`; +// }; const getMainHeight = ({ isTablet }) => { let res = isTablet ? 52 : 68; @@ -43,52 +43,17 @@ const StyledInfoPanelHeader = styled.div` width: 100%; max-width: 100%; - height: ${(props) => getHeaderHeight(props)}; - min-height: ${(props) => getHeaderHeight(props)}; - @media ${tablet} { - height: ${(props) => getHeaderHeight({ ...props, isTablet: true })}; - min-height: ${(props) => getHeaderHeight({ ...props, isTablet: true })}; - } - display: flex; flex-direction: column; border-bottom: ${(props) => props.withTabs ? "none" : `1px solid ${props.theme.infoPanel.borderColor}`}; - .main { + + .header-text { height: ${(props) => getMainHeight(props)}; - min-height: ${(props) => getMainHeight(props)}; @media ${tablet} { height: ${(props) => getMainHeight({ ...props, isTablet: true })}; - min-height: ${(props) => getMainHeight({ ...props, isTablet: true })}; - } - - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - .header-text { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: 20px; - ` - : css` - margin-left: 20px; - `} } } - - .info-panel-toggle-bg { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 20px; - ` - : css` - margin-right: 20px; - `} - } - .tabs { display: flex; width: 100%; diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index b5f91a25fc..c67ef43229 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -25,12 +25,13 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import styled from "styled-components"; -import { useMemo } from "react"; +import { useMemo, useContext } from "react"; import { inject, observer } from "mobx-react"; import useViewEffect from "SRC_DIR/Hooks/useViewEffect"; import { Base } from "@docspace/shared/themes"; +import { Context } from "@docspace/shared/utils"; import { RowContainer } from "@docspace/shared/components/row-container"; import SimpleFilesRow from "./SimpleFilesRow"; @@ -62,7 +63,6 @@ StyledRowContainer.defaultProps = { theme: Base }; const FilesRowContainer = ({ filesList, - sectionWidth, viewAs, setViewAs, infoPanelVisible, @@ -75,6 +75,8 @@ const FilesRowContainer = ({ highlightFile, currentDeviceType, }) => { + const { sectionWidth } = useContext(Context); + useViewEffect({ view: viewAs, setView: setViewAs, diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index 9a16198ff7..e93e9feb23 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -28,13 +28,20 @@ import { inject, observer } from "mobx-react"; import styled, { css } from "styled-components"; import { useNavigate, useLocation } from "react-router-dom"; import elementResizeDetectorMaker from "element-resize-detector"; -import React, { useEffect, useRef, useCallback, useMemo } from "react"; +import React, { + useEffect, + useRef, + useCallback, + useMemo, + useContext, +} from "react"; import useViewEffect from "SRC_DIR/Hooks/useViewEffect"; import { Base } from "@docspace/shared/themes"; import { TableContainer } from "@docspace/shared/components/table"; import { TableBody } from "@docspace/shared/components/table"; +import { Context } from "@docspace/shared/utils"; import TableRow from "./TableRow"; import TableHeader from "./TableHeader"; @@ -121,7 +128,6 @@ const elementResizeDetector = elementResizeDetectorMaker({ const Table = ({ filesList, - sectionWidth, viewAs, setViewAs, setFirsElemChecked, @@ -142,6 +148,8 @@ const Table = ({ const [tagCount, setTagCount] = React.useState(null); const [hideColumns, setHideColumns] = React.useState(false); + const { sectionWidth } = useContext(Context); + const ref = useRef(null); const tagRef = useRef(null); diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.js b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.js index 266a0883f7..dd5bed3a46 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.js @@ -24,14 +24,17 @@ // 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 React, { useEffect } from "react"; +import React, { useEffect, useContext } from "react"; import styled from "styled-components"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; + import DragAndDrop from "@docspace/shared/components/drag-and-drop/DragAndDrop"; +// import { Context } from "@docspace/shared/utils"; import Tile from "./sub-components/Tile"; import FilesTileContent from "./FilesTileContent"; +import { FileTileContext } from "./FileTile.provider"; import withFileActions from "../../../../../HOCs/withFileActions"; import withQuickButtons from "../../../../../HOCs/withQuickButtons"; @@ -45,7 +48,6 @@ const StyledDragAndDrop = styled(DragAndDrop)` const FileTile = (props) => { const { item, - sectionWidth, dragging, onContentFileSelect, fileContextClick, @@ -70,12 +72,12 @@ const FileTile = (props) => { t, getContextModel, onHideContextMenu, - thumbSize, + // thumbSize, setSelection, id, onSelectTag, onSelectOption, - columnCount, + // columnCount, isRooms, withCtrlSelect, withShiftSelect, @@ -86,6 +88,10 @@ const FileTile = (props) => { badgeUrl, } = props; + // const { sectionWidth } = useContext(Context); + + const { columnCount, thumbSize } = useContext(FileTileContext); + const temporaryExtension = item.id === -1 ? `.${item.fileExst}` : item.fileExst; @@ -145,7 +151,7 @@ const FileTile = (props) => { : thumbnailUrl } element={element} - sectionWidth={sectionWidth} + // sectionWidth={sectionWidth} contentElement={quickButtonsComponent} onSelect={onContentFileSelect} tileContextClick={fileContextClick} @@ -177,7 +183,7 @@ const FileTile = (props) => { > {badgesComponent} diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.provider.tsx b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.provider.tsx new file mode 100644 index 0000000000..385d23f3c5 --- /dev/null +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.provider.tsx @@ -0,0 +1,28 @@ +import { createContext, PropsWithChildren, useMemo } from "react"; + +type FileTileContextType = { + thumbSize: string; + columnCount: null | number; +}; + +export const FileTileContext = createContext({ + columnCount: null, + thumbSize: "", +}); + +export const FileTileProvider = ({ + children, + columnCount, + thumbSize, +}: PropsWithChildren) => { + const value = useMemo( + () => ({ columnCount, thumbSize }), + [thumbSize, columnCount], + ); + + return ( + + {children} + + ); +}; diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.utils.ts b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.utils.ts new file mode 100644 index 0000000000..41d1d789da --- /dev/null +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FileTile.utils.ts @@ -0,0 +1,30 @@ +import elementResizeDetectorMaker from "element-resize-detector"; + +export const getThumbSize = (width: number): string => { + let imgWidth = 216; + + if (width >= 240 && width < 264) { + imgWidth = 240; + } else if (width >= 264 && width < 288) { + imgWidth = 264; + } else if (width >= 288 && width < 312) { + imgWidth = 288; + } else if (width >= 312 && width < 336) { + imgWidth = 312; + } else if (width >= 336 && width < 360) { + imgWidth = 336; + } else if (width >= 360 && width < 400) { + imgWidth = 360; + } else if (width >= 400 && width < 440) { + imgWidth = 400; + } else if (width >= 440) { + imgWidth = 440; + } + + return `${imgWidth}x156`; +}; + +export const elementResizeDetector = elementResizeDetectorMaker({ + strategy: "scroll", + callOnAdd: false, +}); diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js index 06687e5737..1fd9ef374c 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js @@ -30,45 +30,21 @@ import React, { useCallback, useState, useMemo, + useContext, } from "react"; import { inject, observer } from "mobx-react"; -import elementResizeDetectorMaker from "element-resize-detector"; -import TileContainer from "./sub-components/TileContainer"; + +import { Context } from "@docspace/shared/utils"; + import FileTile from "./FileTile"; +import { FileTileProvider } from "./FileTile.provider"; +import { elementResizeDetector, getThumbSize } from "./FileTile.utils"; -const getThumbSize = (width) => { - let imgWidth = 216; - - if (width >= 240 && width < 264) { - imgWidth = 240; - } else if (width >= 264 && width < 288) { - imgWidth = 264; - } else if (width >= 288 && width < 312) { - imgWidth = 288; - } else if (width >= 312 && width < 336) { - imgWidth = 312; - } else if (width >= 336 && width < 360) { - imgWidth = 336; - } else if (width >= 360 && width < 400) { - imgWidth = 360; - } else if (width >= 400 && width < 440) { - imgWidth = 400; - } else if (width >= 440) { - imgWidth = 440; - } - - return `${imgWidth}x156`; -}; - -const elementResizeDetector = elementResizeDetectorMaker({ - strategy: "scroll", - callOnAdd: false, -}); +import TileContainer from "./sub-components/TileContainer"; const FilesTileContainer = ({ filesList, t, - sectionWidth, withPaging, thumbnails1280x720, }) => { @@ -78,6 +54,8 @@ const FilesTileContainer = ({ const [thumbSize, setThumbSize] = useState(""); const [columnCount, setColumnCount] = useState(null); + const { sectionWidth } = useContext(Context); + useEffect(() => { return () => { isMountedRef.current = false; @@ -139,10 +117,7 @@ const FilesTileContainer = ({ } item={item} itemIndex={index} - sectionWidth={sectionWidth} selectableRef={onSetTileRef} - thumbSize={thumbSize} - columnCount={columnCount} withRef={true} /> ) : ( @@ -153,24 +128,23 @@ const FilesTileContainer = ({ } item={item} itemIndex={index} - sectionWidth={sectionWidth} - thumbSize={thumbSize} - columnCount={columnCount} /> ); }); - }, [filesList, sectionWidth, onSetTileRef, thumbSize, columnCount]); + }, [filesList, onSetTileRef, sectionWidth]); return ( - - {filesListNode} - + + + {filesListNode} + + ); }; diff --git a/packages/client/src/pages/Home/Section/Body/index.js b/packages/client/src/pages/Home/Section/Body/index.js index 0b1bb063ae..0501b6d0fe 100644 --- a/packages/client/src/pages/Home/Section/Body/index.js +++ b/packages/client/src/pages/Home/Section/Body/index.js @@ -26,9 +26,8 @@ import React, { useEffect } from "react"; import { withTranslation } from "react-i18next"; -import { useLocation } from "react-router-dom"; - import { observer, inject } from "mobx-react"; + import FilesRowContainer from "./RowsView/FilesRowContainer"; import FilesTileContainer from "./TilesView/FilesTileContainer"; import EmptyContainer from "../../../../components/EmptyContainer"; @@ -37,7 +36,6 @@ import TableView from "./TableView/TableContainer"; import withHotkeys from "../../../../HOCs/withHotkeys"; import { clearEdgeScrollingTimer, - Consumer, isMobile, isTablet, onEdgeScrolling, @@ -307,36 +305,18 @@ const SectionBodyContent = (props) => { if (isEmptyFilesList && movingInProgress) return <>; - const showEmptyPage = isEmptyFilesList; + if (isEmptyFilesList) return ; return ( - - {(context) => - showEmptyPage ? ( - <> - - - ) : viewAs === "tile" ? ( - <> - - - ) : viewAs === "table" ? ( - <> - - - ) : ( - <> - - - ) - } - + <> + {viewAs === "tile" ? ( + + ) : viewAs === "table" ? ( + + ) : ( + + )} + ); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/index.js index b166911a42..281b23cb93 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/index.js @@ -54,6 +54,7 @@ const DataImport = ({ getMigrationStatus, isMigrationInit, setIsMigrationInit, + tReady, }) => { const navigate = useNavigate(); @@ -109,10 +110,13 @@ const DataImport = ({ }; useEffect(() => { - setDocumentTitle(t("DataImport")); handleMigrationCheck(); }, []); + useEffect(() => { + if (tReady) setDocumentTitle(t("DataImport")); + }, [tReady]); + const redirectToWorkspace = (title) => { switch (title) { case "GoogleWorkspace": diff --git a/packages/client/src/pages/PortalSettings/categories/data-management/backup/auto-backup/index.js b/packages/client/src/pages/PortalSettings/categories/data-management/backup/auto-backup/index.js index fc74725cc3..2b9feebcc0 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-management/backup/auto-backup/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-management/backup/auto-backup/index.js @@ -66,7 +66,7 @@ const { EveryDayType, EveryWeekType, EveryMonthType } = AutoBackupPeriod; class AutomaticBackup extends React.PureComponent { constructor(props) { super(props); - const { t, language } = props; + const { t, tReady, language } = props; moment.locale(language); this.state = { @@ -96,7 +96,7 @@ class AutomaticBackup extends React.PureComponent { this.maxNumberCopiesArray = []; this.weekdaysLabelArray = []; - setDocumentTitle(t("AutoBackup")); + if (tReady) setDocumentTitle(t("AutoBackup")); this.getTime(); this.getMonthNumbers(); @@ -170,6 +170,12 @@ class AutomaticBackup extends React.PureComponent { this.setBasicSettings(); } + componentDidUpdate(prevProps) { + const { t, tReady } = this.props; + if (prevProps.tReady !== tReady && tReady) + setDocumentTitle(t("AutoBackup")); + } + componentWillUnmount() { const { clearProgressInterval } = this.props; clearTimeout(this.timerId); diff --git a/packages/client/src/pages/PortalSettings/categories/data-management/backup/manual-backup/index.js b/packages/client/src/pages/PortalSettings/categories/data-management/backup/manual-backup/index.js index 83ff9a5d9b..4e0bd6416c 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-management/backup/manual-backup/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-management/backup/manual-backup/index.js @@ -70,9 +70,9 @@ class ManualBackup extends React.Component { this.timerId = null; - const { t } = props; + const { t, tReady } = props; - setDocumentTitle(t("DataBackup")); + if (tReady) setDocumentTitle(t("DataBackup")); this.state = { selectedFolder: "", @@ -150,6 +150,13 @@ class ManualBackup extends React.Component { this.setBasicSettings(); } + componentDidUpdate(prevProps) { + const { t, tReady } = this.props; + + if (prevProps.tReady !== tReady && tReady) + setDocumentTitle(t("DataBackup")); + } + componentWillUnmount() { const { clearProgressInterval } = this.props; clearTimeout(this.timerId); diff --git a/packages/client/src/pages/PortalSettings/categories/data-management/backup/restore-backup/sub-components/backup-list/index.js b/packages/client/src/pages/PortalSettings/categories/data-management/backup/restore-backup/sub-components/backup-list/index.js index a1f56f8f8c..daa8bca80f 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-management/backup/restore-backup/sub-components/backup-list/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-management/backup/restore-backup/sub-components/backup-list/index.js @@ -230,11 +230,7 @@ const BackupListModalDialog = (props) => { onClose={onModalClose} withFooterBorder > - - - {t("BackupList")} - - + {t("BackupList")} { - const { t, currentColorScheme, sdkLink, theme } = props; + const { t, currentColorScheme, sdkLink, theme, tReady } = props; const isSmall = useRef( (() => { @@ -130,8 +130,6 @@ const PortalIntegration = (props) => { const [isFlex, setIsFlex] = useState(isSmall.current); - setDocumentTitle(t("JavascriptSdk")); - const navigate = useNavigate(); const navigateToPortal = () => navigate("docspace"); @@ -191,6 +189,10 @@ const PortalIntegration = (props) => { }, ]; + useEffect(() => { + if (tReady) setDocumentTitle(t("JavascriptSdk")); + }, [tReady]); + const onResize = (entries) => { const belowThreshold = entries[0].contentRect.width <= 600; if (belowThreshold !== isSmall.current) { diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/PluginSDK/index.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/PluginSDK/index.js index 5b895bca99..06da078735 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/PluginSDK/index.js +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/PluginSDK/index.js @@ -47,11 +47,15 @@ const PluginSDK = ({ isEmptyList, theme, }) => { - const { t } = useTranslation(["WebPlugins", "VersionHistory", "Common"]); + const { t, ready } = useTranslation([ + "WebPlugins", + "VersionHistory", + "Common", + ]); React.useEffect(() => { - setDocumentTitle(t("WebPlugins:PluginSDK")); - }, []); + if (ready) setDocumentTitle(t("WebPlugins:PluginSDK")); + }, [ready]); const isMobile = currentDeviceType === "mobile"; diff --git a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js index 4254f9f825..47cb463165 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js @@ -73,6 +73,8 @@ const AttributeMapping = (props) => { isUIDisabled, isDefaultUsersQuotaSet, + + currentColorScheme, } = props; const { t } = useTranslation("Ldap"); @@ -232,7 +234,7 @@ const AttributeMapping = (props) => { components={[ , ]} @@ -284,7 +286,7 @@ const AttributeMapping = (props) => { ); }; -export default inject(({ ldapStore, currentQuotaStore }) => { +export default inject(({ ldapStore, currentQuotaStore, settingsStore }) => { const { setMail, setFirstName, @@ -310,6 +312,8 @@ export default inject(({ ldapStore, currentQuotaStore }) => { const { isDefaultUsersQuotaSet } = currentQuotaStore; + const { currentColorScheme } = settingsStore; + return { setFirstName, setSecondName, @@ -330,5 +334,6 @@ export default inject(({ ldapStore, currentQuotaStore }) => { isUIDisabled, isDefaultUsersQuotaSet, + currentColorScheme, }; })(observer(AttributeMapping)); diff --git a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/LdapFieldComponent.js b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/LdapFieldComponent.js index ccb0ff1dc1..a9c8c74201 100644 --- a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/LdapFieldComponent.js +++ b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/LdapFieldComponent.js @@ -39,7 +39,7 @@ const LdapFieldComponent = (props) => { name, onChange, isPassword, - ...prop + ...rest } = props; const onChangeFn = (e) => { @@ -54,12 +54,12 @@ const LdapFieldComponent = (props) => { onChange && onChange(e); }; - const onFocus = (e) => { - const name = e.target.name; - if (errors[name]) { - removeErrorField(name); - } - }; + // const onFocus = (e) => { + // const name = e.target.name; + // if (errors[name]) { + // removeErrorField(name); + // } + // }; const onBlur = (e) => { if (e.target.value.trim() === "") { @@ -68,16 +68,16 @@ const LdapFieldComponent = (props) => { }; if (isTextArea) - return