From 3ed017f99cb7211988b837b4a9e7974c4373f7d6 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 29 Feb 2024 11:44:48 +0300 Subject: [PATCH 001/126] Web: Added language change for user invitation page. --- packages/client/src/HOCs/withCultureNames.tsx | 11 +++-- .../NavMenu/sub-components/header-unauth.js | 48 +++++++++++++++++- .../Confirm/sub-components/StyledConfirm.js | 6 +++ .../Confirm/sub-components/createUser.js | 49 +++++++++++++++++-- 4 files changed, 105 insertions(+), 9 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index f6a96975ea..92347a0de0 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -34,7 +34,8 @@ export default function withCultureNames< props: Omit & ComponentWithCultureNamesProps, ) => { - const { tReady, cultures, i18n, getPortalCultures } = props; + const { tReady, cultures, i18n, getPortalCultures, isAuthenticated } = + props; useEffect(() => { if (cultures.length > 0) return; @@ -48,9 +49,9 @@ export default function withCultureNames< return culturesArg.map((culture) => { return { key: culture, - label: t(`Culture_${culture}`), + ...(isAuthenticated && { label: t(`Culture_${culture}`) }), icon: flagsIcons?.get(`${culture}.react.svg`), - isBeta: isBetaLanguage(culture), + ...(isAuthenticated && { isBeta: isBetaLanguage(culture) }), }; }); }; @@ -67,11 +68,13 @@ export default function withCultureNames< ); }; - const Injected = inject(({ settingsStore }) => { + const Injected = inject(({ authStore, settingsStore }) => { const { cultures, getPortalCultures } = settingsStore; + const { isAuthenticated } = authStore; return { cultures, getPortalCultures, + isAuthenticated, }; })( observer(withTranslation("Common")(ComponentWithCultureNames)), diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 43dcf9b4ec..e31e6e39a9 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -5,7 +5,12 @@ import { Box } from "@docspace/shared/components/box"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; import { Base } from "@docspace/shared/themes"; -import { mobile } from "@docspace/shared/utils"; +import { getCookie, mobile } from "@docspace/shared/utils"; +import { ComboBox } from "@docspace/shared/components/combobox"; +import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; +import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; +import { convertLanguage } from "@docspace/shared/utils/common"; +import { setCookie } from "@docspace/shared/utils/cookie"; const Header = styled.header` align-items: left; @@ -44,6 +49,14 @@ const Header = styled.header` padding: 12px 0; cursor: pointer; } + + .language-combo-box { + //margin: auto; + // margin-right: 8px; + position: absolute; + right: 8px; + top: 6px; + } `; Header.defaultProps = { theme: Base }; @@ -55,11 +68,24 @@ const HeaderUnAuth = ({ isLoaded, logoUrl, theme, + cultureNames, }) => { const { t } = useTranslation("NavMenu"); const logo = !theme.isBase ? logoUrl?.path?.dark : logoUrl?.path?.light; + const cultureName = getCookie(LANGUAGE); + const language = convertLanguage(cultureName); + const selectedLanguage = cultureNames.find((item) => item.key === language); + + console.log("cultureNames", cultureNames, language); + const onLanguageSelect = (e) => { + setCookie(LANGUAGE, e.key, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + location.reload(); + }; return (
)} + +
); }; @@ -103,4 +147,4 @@ export default inject(({ authStore, settingsStore }) => { logoUrl, theme, }; -})(observer(HeaderUnAuth)); +})(withCultureNames(observer(HeaderUnAuth))); diff --git a/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js b/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js index 2e54f4636a..14464556e5 100644 --- a/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js +++ b/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js @@ -35,6 +35,12 @@ export const StyledPage = styled.div` .subtitle { margin-bottom: 32px; } + + .language-combo-box { + position: absolute; + right: 28px; + top: 28px; + } `; export const StyledContent = styled.div` diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 28b99e4ec7..50f040b474 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -25,9 +25,14 @@ import { createPasswordHash, getOAuthToken, getLoginLink, + convertLanguage, } from "@docspace/shared/utils/common"; import { login } from "@docspace/shared/utils/loginUtils"; -import { PROVIDERS_DATA } from "@docspace/shared/constants"; +import { + COOKIE_EXPIRATION_YEAR, + LANGUAGE, + PROVIDERS_DATA, +} from "@docspace/shared/constants"; import { combineUrl } from "@docspace/shared/utils/combineUrl"; import { IconButton } from "@docspace/shared/components/icon-button"; import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme"; @@ -43,6 +48,10 @@ import { RegisterContainer, StyledCreateUserContent, } from "./StyledCreateUser"; +import { ComboBox } from "@docspace/shared/components/combobox"; +import { getCookie, setCookie } from "@docspace/shared/utils/cookie"; +import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; +import { isMobile } from "@docspace/shared/utils"; const DEFAULT_ROOM_TEXT = "{{firstName}} {{lastName}} invites you to join the room {{roomName}} for secure document collaboration."; @@ -108,7 +117,9 @@ const CreateUserForm = (props) => { currentColorScheme, userNameRegex, defaultPage, + cultureNames, } = props; + const inputRef = React.useRef(null); const emailFromLink = linkData?.email ? linkData.email : ""; @@ -457,9 +468,39 @@ const CreateUserForm = (props) => { ssoSVG: SsoReactSvgUrl, } : {}; + const cultureName = getCookie(LANGUAGE); + const language = convertLanguage(cultureName); + const selectedLanguage = cultureNames.find((item) => item.key === language); + + const onLanguageSelect = (e) => { + setCookie(LANGUAGE, e.key, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + location.reload(); + }; return ( + {!isMobile() && ( + + )} @@ -726,7 +767,9 @@ export default inject(({ settingsStore, authStore }) => { userNameRegex, }; })( - withTranslation(["Confirm", "Common", "Wizard"])( - withLoader(observer(CreateUserForm)), + withCultureNames( + withTranslation(["Confirm", "Common", "Wizard"])( + withLoader(observer(CreateUserForm)), + ), ), ); From 39ffe5897dbafd2e1d553f607d0bd95bf06b73e5 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Sun, 3 Mar 2024 11:21:01 +0300 Subject: [PATCH 002/126] Web: Added language switching on the login page when switching from the invitation page. --- .../Confirm/sub-components/createUser.js | 27 ++++++++++++------- .../login/src/client/components/Login.tsx | 6 ++--- packages/shared/utils/cookie.ts | 3 +++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index df230b3118..2d3f0b571c 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -91,6 +91,18 @@ const CreateUserForm = (props) => { cultureNames, } = props; + const [searchParams, setSearchParams] = useSearchParams(); + + const culture = searchParams.get("culture"); + const installedLanguage = culture ?? getCookie(LANGUAGE); + + //const language = convertLanguage(cultureName); + const selectedLanguage = cultureNames.find( + (item) => item.key === installedLanguage, + ); + + const [cultureName, setCultureName] = useState(installedLanguage); + const inputRef = React.useRef(null); const emailFromLink = linkData?.email ? linkData.email : ""; @@ -117,8 +129,6 @@ const CreateUserForm = (props) => { const [isEmailErrorShow, setIsEmailErrorShow] = useState(false); const [isPasswordErrorShow, setIsPasswordErrorShow] = useState(false); - const [searchParams, setSearchParams] = useSearchParams(); - const [registrationForm, setRegistrationForm] = useState(emailFromLink); const focusInput = () => { @@ -184,7 +194,7 @@ const CreateUserForm = (props) => { window.location.href = combineUrl( window.DocSpaceConfig?.proxy?.url, "/login", - `?loginData=${loginData}`, + `?culture=${cultureName}&loginData=${loginData}`, ); } catch (err) { const status = err?.response?.status; @@ -200,7 +210,7 @@ const CreateUserForm = (props) => { const onSubmit = () => { const { linkData, hashSettings } = props; const type = parseInt(linkData.emplType); - const culture = searchParams.get("culture"); + setIsLoading(true); setErrorText(""); @@ -247,7 +257,7 @@ const CreateUserForm = (props) => { firstname: fname.trim(), lastname: sname.trim(), email: email, - cultureName: culture, + cultureName: cultureName, }; if (!!type) { @@ -439,16 +449,15 @@ const CreateUserForm = (props) => { ssoSVG: SsoReactSvgUrl, } : {}; - const cultureName = getCookie(LANGUAGE); - const language = convertLanguage(cultureName); - const selectedLanguage = cultureNames.find((item) => item.key === language); const onLanguageSelect = (e) => { + let url = location.href; + setCookie(LANGUAGE, e.key, { "max-age": COOKIE_EXPIRATION_YEAR, }); - location.reload(); + location.href = url.replace(`culture=${culture}`, `culture=${e.key}`); }; return ( diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index db86feb764..7304329760 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -58,11 +58,11 @@ const Login: React.FC = ({ useEffect(() => { if (search) { - const isInviteInfo = search.indexOf("loginData="); + const startInviteIndex = search.indexOf("loginData="); - if (isInviteInfo === -1) return; + if (startInviteIndex === -1) return; - const encodeString = search.slice(search.indexOf("=") + 1); + const encodeString = search.slice(startInviteIndex + 10); const decodeString = atob(encodeString); const queryParams = JSON.parse(decodeString); diff --git a/packages/shared/utils/cookie.ts b/packages/shared/utils/cookie.ts index 4351314709..73c8fccb40 100644 --- a/packages/shared/utils/cookie.ts +++ b/packages/shared/utils/cookie.ts @@ -11,6 +11,9 @@ export function getCookie(name: string) { if (url.pathname === "/confirm/LinkInvite" && culture) { return culture; } + if (url.pathname === "/login/" && culture) { + return culture; + } } const matches = document.cookie.match( From e720eb33e0fa780ace12c4f84b3c2d5ef797501f Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Sun, 3 Mar 2024 13:38:42 +0300 Subject: [PATCH 003/126] Web: General logic is placed in a separate file. --- packages/client/src/HOCs/withCultureNames.tsx | 30 ++++++++++++- .../NavMenu/sub-components/header-unauth.js | 21 ++-------- .../Confirm/sub-components/createUser.js | 42 ++++--------------- 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index 92347a0de0..9b3d374c8a 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -1,10 +1,11 @@ import { observer, inject } from "mobx-react"; import React, { useEffect, useMemo } from "react"; import { withTranslation, I18nextProviderProps } from "react-i18next"; - import { isBetaLanguage } from "@docspace/shared/utils"; +import { getCookie, setCookie } from "@docspace/shared/utils/cookie"; import { flagsIcons } from "@docspace/shared/utils/image-flags"; import { Loader, LoaderTypes } from "@docspace/shared/components/loader"; +import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; type I18n = I18nextProviderProps["i18n"]; @@ -60,9 +61,34 @@ export default function withCultureNames< () => mapCulturesToArray(cultures, i18n), [cultures, i18n], ); + const url = new URL(window.location.href); + const culture = url.searchParams.get("culture"); + const currentCultureName = culture ?? getCookie(LANGUAGE); + const selectedCultureObj = cultureNames.find( + (item) => item.key === currentCultureName, + ); + + const onLanguageSelect = (e) => { + setCookie(LANGUAGE, e.key, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + if (culture) { + location.href = url.replace(`culture=${culture}`, `culture=${e.key}`); + return; + } + + location.reload(); + }; return cultures.length > 0 && tReady ? ( - + ) : ( ); diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index e31e6e39a9..b83437002e 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -5,12 +5,9 @@ import { Box } from "@docspace/shared/components/box"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; import { Base } from "@docspace/shared/themes"; -import { getCookie, mobile } from "@docspace/shared/utils"; +import { mobile } from "@docspace/shared/utils"; import { ComboBox } from "@docspace/shared/components/combobox"; import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; -import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; -import { convertLanguage } from "@docspace/shared/utils/common"; -import { setCookie } from "@docspace/shared/utils/cookie"; const Header = styled.header` align-items: left; @@ -69,23 +66,13 @@ const HeaderUnAuth = ({ logoUrl, theme, cultureNames, + selectedCultureObj, + onLanguageSelect, }) => { const { t } = useTranslation("NavMenu"); const logo = !theme.isBase ? logoUrl?.path?.dark : logoUrl?.path?.light; - const cultureName = getCookie(LANGUAGE); - const language = convertLanguage(cultureName); - const selectedLanguage = cultureNames.find((item) => item.key === language); - - console.log("cultureNames", cultureNames, language); - const onLanguageSelect = (e) => { - setCookie(LANGUAGE, e.key, { - "max-age": COOKIE_EXPIRATION_YEAR, - }); - - location.reload(); - }; return (
{ userNameRegex, defaultPage, cultureNames, + selectedCultureObj, + currentCultureName, + onLanguageSelect, } = props; - const [searchParams, setSearchParams] = useSearchParams(); - - const culture = searchParams.get("culture"); - const installedLanguage = culture ?? getCookie(LANGUAGE); - - //const language = convertLanguage(cultureName); - const selectedLanguage = cultureNames.find( - (item) => item.key === installedLanguage, - ); - - const [cultureName, setCultureName] = useState(installedLanguage); - const inputRef = React.useRef(null); const emailFromLink = linkData?.email ? linkData.email : ""; @@ -257,7 +239,7 @@ const CreateUserForm = (props) => { firstname: fname.trim(), lastname: sname.trim(), email: email, - cultureName: cultureName, + cultureName: currentCultureName, }; if (!!type) { @@ -450,16 +432,6 @@ const CreateUserForm = (props) => { } : {}; - const onLanguageSelect = (e) => { - let url = location.href; - - setCookie(LANGUAGE, e.key, { - "max-age": COOKIE_EXPIRATION_YEAR, - }); - - location.href = url.replace(`culture=${culture}`, `culture=${e.key}`); - }; - return ( {!isMobile() && ( @@ -467,7 +439,7 @@ const CreateUserForm = (props) => { className="language-combo-box" directionY={"both"} options={cultureNames} - selectedOption={selectedLanguage} + selectedOption={selectedCultureObj} onSelect={onLanguageSelect} isDisabled={false} scaled={false} From 582f95162dbbb7361bcd0a4280127fe167af139a Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 4 Mar 2024 13:33:18 +0300 Subject: [PATCH 004/126] Web: Added language support for login page. --- packages/client/src/HOCs/withCultureNames.tsx | 18 +---- packages/login/index.d.ts | 1 + .../login/src/client/components/Login.tsx | 74 +++++++++++++++++-- .../src/client/components/StyledLogin.ts | 6 ++ .../login/src/server/lib/helpers/index.ts | 9 ++- packages/shared/utils/common.ts | 29 ++++++++ 6 files changed, 115 insertions(+), 22 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index 9b3d374c8a..e76ba6060f 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -1,11 +1,11 @@ import { observer, inject } from "mobx-react"; import React, { useEffect, useMemo } from "react"; import { withTranslation, I18nextProviderProps } from "react-i18next"; -import { isBetaLanguage } from "@docspace/shared/utils"; + import { getCookie, setCookie } from "@docspace/shared/utils/cookie"; -import { flagsIcons } from "@docspace/shared/utils/image-flags"; import { Loader, LoaderTypes } from "@docspace/shared/components/loader"; import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; +import { mapCulturesToArray } from "@docspace/shared/utils/common"; type I18n = I18nextProviderProps["i18n"]; @@ -45,20 +45,8 @@ export default function withCultureNames< // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const mapCulturesToArray = (culturesArg: string[], i18nArg: I18n) => { - const t = i18nArg.getFixedT(null, "Common"); - return culturesArg.map((culture) => { - return { - key: culture, - ...(isAuthenticated && { label: t(`Culture_${culture}`) }), - icon: flagsIcons?.get(`${culture}.react.svg`), - ...(isAuthenticated && { isBeta: isBetaLanguage(culture) }), - }; - }); - }; - const cultureNames = useMemo( - () => mapCulturesToArray(cultures, i18n), + () => mapCulturesToArray(cultures, isAuthenticated, i18n), [cultures, i18n], ); const url = new URL(window.location.href); diff --git a/packages/login/index.d.ts b/packages/login/index.d.ts index 6f179135f6..27a1c11ad8 100644 --- a/packages/login/index.d.ts +++ b/packages/login/index.d.ts @@ -122,6 +122,7 @@ declare global { ssoSettings?: ISSOSettings; logoUrls: ILogoUrl[]; error?: IError; + cultures: string[]; } interface DevRequest { diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index 7304329760..5306a855d4 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -1,15 +1,24 @@ -import React, { useState, useCallback, useEffect } from "react"; +import React, { useState, useCallback, useEffect, useMemo } from "react"; +import {} from "react-router-dom"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; -import { useLocation } from "react-router-dom"; +import { useLocation, useSearchParams } from "react-router-dom"; import { LoginFormWrapper, LoginContent } from "./StyledLogin"; import { Text } from "@docspace/shared/components/text"; import { SocialButtonsGroup } from "@docspace/shared/components/social-buttons-group"; -import { getOAuthToken, getLoginLink } from "@docspace/shared/utils/common"; +import { + getOAuthToken, + getLoginLink, + mapCulturesToArray, +} from "@docspace/shared/utils/common"; import { Link } from "@docspace/shared/components/link"; -import { checkIsSSR } from "@docspace/shared/utils"; -import { PROVIDERS_DATA } from "@docspace/shared/constants"; +import { checkIsSSR, getCookie } from "@docspace/shared/utils"; +import { + COOKIE_EXPIRATION_YEAR, + LANGUAGE, + PROVIDERS_DATA, +} from "@docspace/shared/constants"; import { Toast } from "@docspace/shared/components/toast"; import LoginForm from "./sub-components/LoginForm"; import RecoverAccessModalDialog from "@docspace/shared/components/recover-access-modal-dialog/RecoverAccessModalDialog"; @@ -26,6 +35,9 @@ import { TenantStatus } from "@docspace/shared/enums"; import GreetingContainer from "./sub-components/GreetingContainer"; import { Scrollbar } from "@docspace/shared/components/scrollbar"; +import { setCookie } from "@docspace/shared/utils/cookie"; +import { ComboBox } from "@docspace/shared/components/combobox"; + const themes = { Dark: Dark, Base: Base, @@ -49,6 +61,7 @@ const Login: React.FC = ({ setTheme, logoUrls, isBaseTheme, + cultures, }) => { const location = useLocation(); @@ -56,6 +69,15 @@ const Login: React.FC = ({ const isRestoringPortal = portalSettings?.tenantStatus === TenantStatus.PortalRestore; + let [searchParams] = useSearchParams(); + + const cultureNames = useMemo( + () => mapCulturesToArray(cultures, false), + [cultures] + ); + + const culture = searchParams.get("culture"); + useEffect(() => { if (search) { const startInviteIndex = search.indexOf("loginData="); @@ -71,8 +93,13 @@ const Login: React.FC = ({ window.history.replaceState({}, document.title, window.location.pathname); } + const cultureName = culture ?? getCookie(LANGUAGE); + setCurrantCultureName(cultureName); + isRestoringPortal && window.location.replace("/preparation-portal"); }, []); + + const [currentCultureName, setCurrantCultureName] = useState("en"); const [isLoading, setIsLoading] = useState(false); const [recoverDialogVisible, setRecoverDialogVisible] = useState(false); const [invitationLinkData, setInvitationLinkData] = useState({ @@ -95,6 +122,26 @@ const Login: React.FC = ({ cookieSettingsEnabled: false, }; + const selectedCultureObj = cultureNames.find( + (item) => item.key === currentCultureName + ); + + const onLanguageSelect = (e) => { + setCookie(LANGUAGE, e.key, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + if (culture) { + window.location.href = window.location.href.replace( + `culture=${culture}`, + `culture=${e.key}` + ); + return; + } + + window.location.reload(); + }; + const ssoLabel = capabilities?.ssoLabel || ""; const ssoUrl = capabilities?.ssoUrl || ""; const { t } = useTranslation(["Login", "Common"]); @@ -211,6 +258,23 @@ const Login: React.FC = ({ >
+ { return availableThemes.selected === theme.id; @@ -87,6 +91,7 @@ export const getInitialState = async ( currentColorScheme, logoUrls, ssoSettings, + cultures, }; return initialState; diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 8cc9944c43..22fd4eb51c 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -5,8 +5,11 @@ import find from "lodash/find"; import moment from "moment-timezone"; import { isMobile } from "react-device-detect"; +import { I18nextProviderProps } from "react-i18next"; import sjcl from "sjcl"; +import { flagsIcons } from "@docspace/shared/utils/image-flags"; + import LoginPageSvgUrl from "PUBLIC_DIR/images/logo/loginpage.svg?url"; import DarkLoginPageSvgUrl from "PUBLIC_DIR/images/logo/dark_loginpage.svg?url"; import LeftMenuSvgUrl from "PUBLIC_DIR/images/logo/leftmenu.svg?url"; @@ -970,3 +973,29 @@ export const insertDataLayer = (id: string) => { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ user_id: id }); }; + +type I18n = I18nextProviderProps["i18n"]; +export const mapCulturesToArray = ( + culturesArg: string[], + isAuthenticated: boolean, + i18nArg?: I18n, +) => { + if (i18nArg) { + const t = i18nArg.getFixedT(null, "Common"); + return culturesArg.map((culture) => { + return { + key: culture, + ...(isAuthenticated && { label: t(`Culture_${culture}`) }), + icon: flagsIcons?.get(`${culture}.react.svg`), + ...(isAuthenticated && { isBeta: isBetaLanguage(culture) }), + }; + }); + } + + return culturesArg.map((culture) => { + return { + key: culture, + icon: flagsIcons?.get(`${culture}.react.svg`), + }; + }); +}; From bd84465c1e1592c2a2930991b2aaf9dcee5a6a7e Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 4 Mar 2024 13:33:29 +0300 Subject: [PATCH 005/126] Web: Fixed error. --- packages/client/src/pages/Confirm/sub-components/createUser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index f0623c7d00..56e3fa456b 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -176,7 +176,7 @@ const CreateUserForm = (props) => { window.location.href = combineUrl( window.DocSpaceConfig?.proxy?.url, "/login", - `?culture=${cultureName}&loginData=${loginData}`, + `?culture=${currentCultureName}&loginData=${loginData}`, ); } catch (err) { const status = err?.response?.status; From f56fe540b7ffc35c710b0867dd0c2506ef49c958 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 4 Mar 2024 16:24:26 +0300 Subject: [PATCH 006/126] Web: Added a combobox with language switching on the login page. --- .../login/src/client/components/Login.tsx | 214 +++++++++--------- .../src/client/components/StyledLogin.ts | 7 +- 2 files changed, 113 insertions(+), 108 deletions(-) diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index 5306a855d4..2ac8969ed5 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -99,7 +99,7 @@ const Login: React.FC = ({ isRestoringPortal && window.location.replace("/preparation-portal"); }, []); - const [currentCultureName, setCurrantCultureName] = useState("en"); + const [currentCultureName, setCurrantCultureName] = useState("en-GB"); const [isLoading, setIsLoading] = useState(false); const [recoverDialogVisible, setRecoverDialogVisible] = useState(false); const [invitationLinkData, setInvitationLinkData] = useState({ @@ -250,114 +250,114 @@ const Login: React.FC = ({ const isRegisterContainerVisible = !checkIsSSR() && enabledJoin; return ( - +
- - - - - - - - {(oauthDataExists() || ssoExists()) && ( - <> -
- - {t("Common:orContinueWith")} - -
- - - )} - - {enableAdmMess && ( - - {t("RecoverAccess")} - - )} -
- - - {recoverDialogVisible && ( - - )} -
-
- - {isRegisterContainerVisible && ( - + - )} -
-
+ + + + + + {(oauthDataExists() || ssoExists()) && ( + <> +
+ + {t("Common:orContinueWith")} + +
+ + + )} + + {enableAdmMess && ( + + {t("RecoverAccess")} + + )} +
+ + + {recoverDialogVisible && ( + + )} +
+
+ + {isRegisterContainerVisible && ( + + )} +
+ ); }; diff --git a/packages/login/src/client/components/StyledLogin.ts b/packages/login/src/client/components/StyledLogin.ts index f4fad69564..45cd984076 100644 --- a/packages/login/src/client/components/StyledLogin.ts +++ b/packages/login/src/client/components/StyledLogin.ts @@ -73,9 +73,14 @@ export const LoginFormWrapper = styled.div` } .language-combo-box { - position: absolute; + position: fixed; right: 28px; top: 28px; + + @media ${mobile} { + top: 7px; + right: 8px; + } } .invitation-info-container { margin-bottom: 16px; From ed598a4b476e8dca3a9e3cb3ff2789bd2475d715 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 14 Mar 2024 10:28:33 +0300 Subject: [PATCH 007/126] Fixed after merge. --- .../login/src/client/components/Login.tsx | 210 +++++++++--------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index c52ae09e3b..e5442dc0ad 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -94,7 +94,7 @@ const Login: React.FC = ({ return decoder.decode(charCodeArray); }; - const encodeString = search.slice(search.indexOf("=") + 1); + const encodeString = search.slice(firstIndex + 10); const decodeString = fromBinaryStr(encodeString); const queryParams = JSON.parse(decodeString); @@ -260,113 +260,113 @@ const Login: React.FC = ({ const isRegisterContainerVisible = !checkIsSSR() && enabledJoin; return ( - +
- - - - + + + + - - - - {(oauthDataExists() || ssoExists()) && ( - <> -
- - {t("Common:orContinueWith")} - -
- - - )} - - {enableAdmMess && ( - - {t("RecoverAccess")} - - )} -
- - {recoverDialogVisible && ( - - )} -
-
- - {isRegisterContainerVisible && ( - - )} -
-
+ + + {(oauthDataExists() || ssoExists()) && ( + <> +
+ + {t("Common:orContinueWith")} + +
+ + + )} + + {enableAdmMess && ( + + {t("RecoverAccess")} + + )} +
+ + {recoverDialogVisible && ( + + )} + + + + {isRegisterContainerVisible && ( + + )} + +
); }; From 918daa782ce92ccbfcacda683a6952f4d47beff4 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Tue, 16 Apr 2024 16:12:02 +0300 Subject: [PATCH 008/126] Web: Added changing the language without reloading the page. --- packages/client/src/HOCs/withCultureNames.tsx | 24 ++++++------- .../Confirm/sub-components/createUser.js | 2 +- .../login/src/client/components/Login.tsx | 36 +++++++------------ .../components/sub-components/LoginForm.tsx | 6 ++-- packages/shared/api/user/index.js | 9 ++++- packages/shared/utils/loginUtils.ts | 2 ++ 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index e76ba6060f..f2d73d2515 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -1,19 +1,18 @@ import { observer, inject } from "mobx-react"; import React, { useEffect, useMemo } from "react"; -import { withTranslation, I18nextProviderProps } from "react-i18next"; +import { withTranslation } from "react-i18next"; import { getCookie, setCookie } from "@docspace/shared/utils/cookie"; import { Loader, LoaderTypes } from "@docspace/shared/components/loader"; import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; import { mapCulturesToArray } from "@docspace/shared/utils/common"; - -type I18n = I18nextProviderProps["i18n"]; +import i18n from "../i18n"; interface ComponentWithCultureNamesProps { tReady: boolean; cultures: string[]; + isAuthenticated: boolean; getPortalCultures: () => Promise; - i18n: I18n; } interface WrappedComponentProps extends ComponentWithCultureNamesProps { @@ -35,8 +34,7 @@ export default function withCultureNames< props: Omit & ComponentWithCultureNamesProps, ) => { - const { tReady, cultures, i18n, getPortalCultures, isAuthenticated } = - props; + const { tReady, cultures, getPortalCultures, isAuthenticated } = props; useEffect(() => { if (cultures.length > 0) return; @@ -47,7 +45,7 @@ export default function withCultureNames< const cultureNames = useMemo( () => mapCulturesToArray(cultures, isAuthenticated, i18n), - [cultures, i18n], + [cultures, isAuthenticated], ); const url = new URL(window.location.href); const culture = url.searchParams.get("culture"); @@ -56,17 +54,19 @@ export default function withCultureNames< (item) => item.key === currentCultureName, ); - const onLanguageSelect = (e) => { + const onLanguageSelect = (e: KeyboardEvent) => { + i18n.changeLanguage(e.key); + setCookie(LANGUAGE, e.key, { "max-age": COOKIE_EXPIRATION_YEAR, }); if (culture) { - location.href = url.replace(`culture=${culture}`, `culture=${e.key}`); - return; + window.location.href = url.replace( + `culture=${culture}`, + `culture=${e.key}`, + ); } - - location.reload(); }; return cultures.length > 0 && tReady ? ( diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 05690b3657..debb775e1b 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -184,7 +184,7 @@ const CreateUserForm = (props) => { window.location.href = combineUrl( window.DocSpaceConfig?.proxy?.url, "/login", - `?culture=${currentCultureName}&loginData=${loginData}`, + `?loginData=${loginData}`, ); } catch (err) { console.error(err); diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index e5442dc0ad..087d9657da 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -2,7 +2,7 @@ import React, { useState, useCallback, useEffect, useMemo } from "react"; import {} from "react-router-dom"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; -import { useLocation, useSearchParams } from "react-router-dom"; +import { useLocation } from "react-router-dom"; import { LoginFormWrapper, LoginContent } from "./StyledLogin"; import { Text } from "@docspace/shared/components/text"; @@ -13,7 +13,7 @@ import { mapCulturesToArray, } from "@docspace/shared/utils/common"; import { Link } from "@docspace/shared/components/link"; -import { checkIsSSR, getCookie } from "@docspace/shared/utils"; +import { checkIsSSR } from "@docspace/shared/utils"; import { COOKIE_EXPIRATION_YEAR, LANGUAGE, @@ -68,15 +68,11 @@ const Login: React.FC = ({ const isRestoringPortal = portalSettings?.tenantStatus === TenantStatus.PortalRestore; - let [searchParams] = useSearchParams(); - const cultureNames = useMemo( () => mapCulturesToArray(cultures, false), [cultures] ); - const culture = searchParams.get("culture"); - useEffect(() => { if (search) { const firstIndex = search.indexOf("loginData="); @@ -103,13 +99,11 @@ const Login: React.FC = ({ window.history.replaceState({}, document.title, window.location.pathname); } - const cultureName = culture ?? getCookie(LANGUAGE); - setCurrantCultureName(cultureName); - isRestoringPortal && window.location.replace("/preparation-portal"); }, []); - const [currentCultureName, setCurrantCultureName] = useState("en-GB"); + const { t, i18n } = useTranslation(["Login", "Common"]); + const [isLoading, setIsLoading] = useState(false); const [recoverDialogVisible, setRecoverDialogVisible] = useState(false); const [invitationLinkData, setInvitationLinkData] = useState({ @@ -132,29 +126,25 @@ const Login: React.FC = ({ cookieSettingsEnabled: false, }; + const currentCultureName = i18n.language; + const selectedCultureObj = cultureNames.find( (item) => item.key === currentCultureName ); - const onLanguageSelect = (e) => { - setCookie(LANGUAGE, e.key, { + const onLanguageSelect = (e: KeyboardEvent) => { + const culture = e.key; + + i18n.changeLanguage(culture); + + setCookie(LANGUAGE, culture, { "max-age": COOKIE_EXPIRATION_YEAR, }); - - if (culture) { - window.location.href = window.location.href.replace( - `culture=${culture}`, - `culture=${e.key}` - ); - return; - } - - window.location.reload(); }; const ssoLabel = capabilities?.ssoLabel || ""; const ssoUrl = capabilities?.ssoUrl || ""; - const { t } = useTranslation(["Login", "Common"]); + const mounted = useMounted(); useIsomorphicLayoutEffect(() => { diff --git a/packages/login/src/client/components/sub-components/LoginForm.tsx b/packages/login/src/client/components/sub-components/LoginForm.tsx index ece4d54c59..448fe2e6da 100644 --- a/packages/login/src/client/components/sub-components/LoginForm.tsx +++ b/packages/login/src/client/components/sub-components/LoginForm.tsx @@ -68,7 +68,7 @@ const LoginForm: React.FC = ({ const inputRef = useRef(null); - const { t, ready } = useTranslation(["Login", "Common"]); + const { t, ready, i18n } = useTranslation(["Login", "Common"]); const { message, confirmedEmail, authError } = match || { message: "", @@ -194,7 +194,9 @@ const LoginForm: React.FC = ({ isDesktop && checkPwd(); const session = !isChecked; - login(user, hash, session, captchaToken) + const currentCulture = i18n.language; + + login(user, hash, session, captchaToken, currentCulture) .then((res: string | object) => { const isConfirm = typeof res === "string" && res.includes("confirm"); const redirectPath = sessionStorage.getItem("referenceUrl"); diff --git a/packages/shared/api/user/index.js b/packages/shared/api/user/index.js index 116b02ddfa..45ded172bb 100644 --- a/packages/shared/api/user/index.js +++ b/packages/shared/api/user/index.js @@ -1,11 +1,18 @@ import { request, setWithCredentialsStatus } from "../client"; -export function login(userName, passwordHash, session, recaptchaResponse) { +export function login( + userName, + passwordHash, + session, + recaptchaResponse, + culture, +) { const data = { userName, passwordHash, session, recaptchaResponse, + culture, }; return request({ diff --git a/packages/shared/utils/loginUtils.ts b/packages/shared/utils/loginUtils.ts index 4944509eb9..c0ef779ea1 100644 --- a/packages/shared/utils/loginUtils.ts +++ b/packages/shared/utils/loginUtils.ts @@ -7,6 +7,7 @@ export async function login( hash: string, session = true, captchaToken: string = "", + currentCultureName: string = "", ): Promise { try { const response = (await api.user.login( @@ -14,6 +15,7 @@ export async function login( hash, session, captchaToken, + currentCultureName, )) as { token?: string; tfa?: string; From 22c73d5bfa8f024624650836a97e9afdd1a62018 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 17 Apr 2024 13:38:59 +0300 Subject: [PATCH 009/126] Login/Shared: Added support for changing the language when logging in via social networks. --- packages/login/src/client/components/Login.tsx | 6 +++--- .../components/sub-components/LoginForm.tsx | 15 ++++++++------- packages/shared/api/user/index.js | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index 087d9657da..79b3612d91 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -104,6 +104,7 @@ const Login: React.FC = ({ const { t, i18n } = useTranslation(["Login", "Common"]); + const currentCulture = i18n.language; const [isLoading, setIsLoading] = useState(false); const [recoverDialogVisible, setRecoverDialogVisible] = useState(false); const [invitationLinkData, setInvitationLinkData] = useState({ @@ -126,10 +127,8 @@ const Login: React.FC = ({ cookieSettingsEnabled: false, }; - const currentCultureName = i18n.language; - const selectedCultureObj = cultureNames.find( - (item) => item.key === currentCultureName + (item) => item.key === currentCulture ); const onLanguageSelect = (e: KeyboardEvent) => { @@ -302,6 +301,7 @@ const Login: React.FC = ({ enableAdmMess={enableAdmMess} cookieSettingsEnabled={cookieSettingsEnabled} emailFromInvitation={invitationLinkData.email} + currentCulture={currentCulture} /> {(oauthDataExists() || ssoExists()) && ( <> diff --git a/packages/login/src/client/components/sub-components/LoginForm.tsx b/packages/login/src/client/components/sub-components/LoginForm.tsx index 448fe2e6da..1ae509bdf9 100644 --- a/packages/login/src/client/components/sub-components/LoginForm.tsx +++ b/packages/login/src/client/components/sub-components/LoginForm.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from "react"; +import React, { useState, useRef, useEffect, useCallback } from "react"; import { FieldContainer } from "@docspace/shared/components/field-container"; import { PasswordInput } from "@docspace/shared/components/password-input"; import { Checkbox } from "@docspace/shared/components/checkbox"; @@ -31,6 +31,7 @@ interface ILoginFormProps { recaptchaPublicKey: CaptchaPublicKeyType; isBaseTheme: boolean; emailFromInvitation?: string; + currentCulture: string; } const settings = { @@ -50,6 +51,7 @@ const LoginForm: React.FC = ({ recaptchaPublicKey, isBaseTheme, emailFromInvitation, + currentCulture, }) => { const captchaRef = useRef(null); @@ -75,12 +77,11 @@ const LoginForm: React.FC = ({ confirmedEmail: "", authError: "", }; - const authCallback = (profile: string) => { localStorage.removeItem("profile"); localStorage.removeItem("code"); - thirdPartyLogin(profile) + thirdPartyLogin(profile, currentCulture) .then((response) => { if (!(response || response.token || response.confirmUrl)) throw new Error("Empty API response"); @@ -115,6 +116,10 @@ const LoginForm: React.FC = ({ authCallback(profile); }, []); + useEffect(() => { + window.authCallback = authCallback; + }, [currentCulture]); + useEffect(() => { message && setErrorText(message); confirmedEmail && setIdentifier(confirmedEmail); @@ -128,8 +133,6 @@ const LoginForm: React.FC = ({ authError && ready && toastr.error(t("Common:ProviderLoginError")); focusInput(); - - window.authCallback = authCallback; }, [message, confirmedEmail]); const onChangeLogin = (e: React.ChangeEvent) => { @@ -194,8 +197,6 @@ const LoginForm: React.FC = ({ isDesktop && checkPwd(); const session = !isChecked; - const currentCulture = i18n.language; - login(user, hash, session, captchaToken, currentCulture) .then((res: string | object) => { const isConfirm = typeof res === "string" && res.includes("confirm"); diff --git a/packages/shared/api/user/index.js b/packages/shared/api/user/index.js index 45ded172bb..ae8f43efdc 100644 --- a/packages/shared/api/user/index.js +++ b/packages/shared/api/user/index.js @@ -23,11 +23,11 @@ export function login( }); } -export function thirdPartyLogin(SerializedProfile) { +export function thirdPartyLogin(SerializedProfile, culture) { return request({ method: "post", url: "authentication", - data: { SerializedProfile }, + data: { SerializedProfile, culture }, }); } From e34681f8b0918dc41bbc3a08a149e00f9ce3d83d Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 19 Apr 2024 14:46:56 +0300 Subject: [PATCH 010/126] Web: Combobox with language selection moved to common components. --- .../Filter/LanguageFilter/index.js | 80 ++--------- packages/client/src/store/OformsStore.js | 15 +- .../language-combobox/LanguageCmbobox.tsx | 130 ++++++++++++++++++ .../LanguageCmbobox.types.ts | 41 ++++++ .../LanguageCombobox.styled.ts} | 35 ++--- .../components/language-combobox/index.ts | 26 ++++ 6 files changed, 235 insertions(+), 92 deletions(-) create mode 100644 packages/shared/components/language-combobox/LanguageCmbobox.tsx create mode 100644 packages/shared/components/language-combobox/LanguageCmbobox.types.ts rename packages/{client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js => shared/components/language-combobox/LanguageCombobox.styled.ts} (85%) create mode 100644 packages/shared/components/language-combobox/index.ts diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 6e30848787..2f6a07a779 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -24,18 +24,13 @@ // 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 * as Styled from "./index.styled"; - import { withTranslation } from "react-i18next"; -import { useState, useEffect } from "react"; +import { useEffect } from "react"; import { inject, observer } from "mobx-react"; -import { flagsIcons } from "@docspace/shared/utils/image-flags"; -import { convertToCulture } from "@docspace/shared/utils/common"; -import { isMobile } from "@docspace/shared/utils"; import { RectangleSkeleton } from "@docspace/shared/skeletons"; - +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; const LanguageFilter = ({ t, oformsFilter, @@ -48,13 +43,8 @@ const LanguageFilter = ({ languageFilterLoaded, oformFilesLoaded, }) => { - const [isOpen, setIsOpen] = useState(false); - const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onCloseDropdown = () => setIsOpen(false); - - const onFilterByLocale = async (newLocale) => { - await filterOformsByLocale(newLocale); - onCloseDropdown(); + const onFilterByLocale = async (newLocale, icon) => { + await filterOformsByLocale(newLocale, icon); const [sectionScroll] = document.getElementsByClassName("section-scroll"); sectionScroll.scrollTop = 0; @@ -71,61 +61,13 @@ const LanguageFilter = ({ return ; return ( - - - {oformLocales?.map((locale) => ( - onFilterByLocale(locale)} - fillIcon={false} - /> - ))} - - } - > - - - + ); }; diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index dbb22f7c40..da7a109a99 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -41,10 +41,14 @@ import { } from "@docspace/shared/api/oforms"; import { toastr } from "@docspace/shared/components/toast"; -import { convertToLanguage } from "@docspace/shared/utils/common"; +import { + convertToCulture, + convertToLanguage, +} from "@docspace/shared/utils/common"; import { LANGUAGE } from "@docspace/shared/constants"; import { getCookie } from "@docspace/shared/utils/cookie"; import { combineUrl } from "@docspace/shared/utils/combineUrl"; +import { flagsIcons } from "@docspace/shared/utils/image-flags"; const myDocumentsFolderId = 2; @@ -111,7 +115,11 @@ class OformsStore { this.infoPanelStore.setInfoPanelSelection(gallerySelected); }; - setOformLocales = (oformLocales) => (this.oformLocales = oformLocales); + setOformLocales = (oformLocales) => { + const convertedLocales = oformLocales.map((item) => convertToCulture(item)); + + this.oformLocales = convertedLocales; + }; setFilterOformsByLocaleIsLoading = (filterOformsByLocaleIsLoading) => { this.filterOformsByLocaleIsLoading = filterOformsByLocaleIsLoading; @@ -316,7 +324,7 @@ class OformsStore { runInAction(() => this.fetchOforms(newOformsFilter)); }; - filterOformsByLocale = async (locale) => { + filterOformsByLocale = async (locale, icon) => { if (!locale) return; if (locale !== this.oformsFilter.locale) @@ -328,6 +336,7 @@ class OformsStore { this.oformsFilter.locale = locale; this.oformsFilter.categorizeBy = ""; this.oformsFilter.categoryId = ""; + this.oformsFilter.icon = icon; const newOformsFilter = this.oformsFilter.clone(); runInAction(() => this.fetchOforms(newOformsFilter)); diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.tsx b/packages/shared/components/language-combobox/LanguageCmbobox.tsx new file mode 100644 index 0000000000..c5b212ecdd --- /dev/null +++ b/packages/shared/components/language-combobox/LanguageCmbobox.tsx @@ -0,0 +1,130 @@ +// (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 { useState, useMemo } from "react"; + +import { mapCulturesToArray } from "../../utils/common"; +import { isMobile } from "../../utils"; +import { + LanguageComboBox, + SelectedItemComponent, + ItemComponent, + WrapperComponent, +} from "./LanguageCombobox.styled"; +import { TCulture, TCultures, ComboboxProps } from "./LanguageCmbobox.types"; + +const getIconUrl = (cultureNames: TCultures, selectedCulture: TCulture) => { + const currentCulture = cultureNames.find( + (item) => item.key === selectedCulture.key, + ); + + if (!currentCulture) return ""; + + return currentCulture.icon; +}; +const LanguageCombobox = (props: ComboboxProps) => { + const { + tabIndex, + cultures, + isAuthenticated = false, + onSelectLanguage, + selectedCulture, + id, + } = props; + + const [isOpen, setIsOpen] = useState(false); + + const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => setIsOpen(false); + + const cultureNames = useMemo(() => { + return mapCulturesToArray(cultures, isAuthenticated); + }, [isAuthenticated, cultures]); + + const onSelect = (culture: TCulture) => { + if (culture.key === selectedCulture.key) return; + + onSelectLanguage(culture.key, culture.icon); + + onCloseDropdown(); + }; + + const advancedOptions = () => { + return ( + <> + {cultureNames.map((culture) => ( + onSelect(culture)} + fillIcon={false} + /> + ))} + + ); + }; + + return ( + + + + + + ); +}; +export { LanguageCombobox }; diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.types.ts b/packages/shared/components/language-combobox/LanguageCmbobox.types.ts new file mode 100644 index 0000000000..a1eacae921 --- /dev/null +++ b/packages/shared/components/language-combobox/LanguageCmbobox.types.ts @@ -0,0 +1,41 @@ +// (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 + +export type TCulture = { + key: string; + icon: string; + label?: string; +}; + +export type TCultures = TCulture[]; +export interface ComboboxProps { + selectedCulture: TCulture; + cultures: string[]; + tabIndex?: number | string; + isAuthenticated: boolean; + /** Accepts id */ + id?: string; +} diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts similarity index 85% rename from packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js rename to packages/shared/components/language-combobox/LanguageCombobox.styled.ts index e23c556cca..9b9fc3c4d2 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js +++ b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts @@ -23,25 +23,13 @@ // 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 { DropDownItem } from "@docspace/shared/components/drop-down-item"; import styled, { css } from "styled-components"; -import Base from "@docspace/shared/themes/base"; -import { ComboBox } from "@docspace/shared/components/combobox"; -import { mobile } from "@docspace/shared/utils"; -export const LanguageFilter = styled.div` - width: 41px; - box-sizing: border-box; +import { ComboBox } from "../combobox"; +import { DropDownItem } from "../drop-down-item"; +import { mobile } from "../../utils"; - .dropdown-container { - width: 100%; - box-sizing: border-box; - margin-top: 4px; - } -`; - -export const LanguangeComboBox = styled(ComboBox)` +export const LanguageComboBox = styled(ComboBox)` width: 41px; padding: 0; box-sizing: border-box; @@ -72,7 +60,7 @@ export const LanguangeComboBox = styled(ComboBox)` } `; -export const LanguageFilterSelectedItem = styled(DropDownItem)` +export const SelectedItemComponent = styled(DropDownItem)` box-sizing: border-box; display: flex; @@ -90,8 +78,7 @@ export const LanguageFilterSelectedItem = styled(DropDownItem)` } } `; - -export const LanguageFilterItem = styled(DropDownItem)` +export const ItemComponent = styled(DropDownItem)` height: 32px; width: 41px; box-sizing: border-box; @@ -121,5 +108,13 @@ export const LanguageFilterItem = styled(DropDownItem)` gap: 8px; } `; +export const WrapperComponent = styled.div` + width: 41px; + box-sizing: border-box; -LanguageFilterItem.defaultProps = { theme: Base }; + .dropdown-container { + width: 100%; + box-sizing: border-box; + margin-top: 4px; + } +`; diff --git a/packages/shared/components/language-combobox/index.ts b/packages/shared/components/language-combobox/index.ts new file mode 100644 index 0000000000..ef8c1985b5 --- /dev/null +++ b/packages/shared/components/language-combobox/index.ts @@ -0,0 +1,26 @@ +// (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 +export { LanguageCombobox } from "./LanguageCmbobox"; From 111cf5b0736741e09eb39e0521298cc99c7796d2 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 24 Apr 2024 15:14:51 +0300 Subject: [PATCH 011/126] Web: Client/Shared: LanguageCombobox component logic has been simplified. --- packages/client/src/HOCs/withCultureNames.tsx | 2 +- .../Filter/LanguageFilter/index.js | 6 +- .../shared/components/combobox/ComboBox.tsx | 16 ++- .../components/combobox/Combobox.types.ts | 2 + .../combobox/sub-components/ComboButton.tsx | 2 +- .../drop-down/sub-components/Row.tsx | 5 +- .../language-combobox/LanguageCmbobox.tsx | 126 ++++++------------ .../LanguageCmbobox.types.ts | 5 +- .../LanguageCombobox.styled.ts | 98 +++----------- packages/shared/utils/common.ts | 8 +- 10 files changed, 85 insertions(+), 185 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index c9d312c7bb..c7ecfe8f74 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -70,7 +70,7 @@ export default function withCultureNames< }, []); const cultureNames = useMemo( - () => mapCulturesToArray(cultures, isAuthenticated, i18n), + () => mapCulturesToArray(cultures, true, i18n), [cultures, isAuthenticated], ); const url = new URL(window.location.href); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 2f6a07a779..aa4ec8b717 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -43,8 +43,8 @@ const LanguageFilter = ({ languageFilterLoaded, oformFilesLoaded, }) => { - const onFilterByLocale = async (newLocale, icon) => { - await filterOformsByLocale(newLocale, icon); + const onFilterByLocale = async (newLocale) => { + await filterOformsByLocale(newLocale); const [sectionScroll] = document.getElementsByClassName("section-scroll"); sectionScroll.scrollTop = 0; @@ -65,7 +65,7 @@ const LanguageFilter = ({ cultures={oformLocales} isAuthenticated onSelectLanguage={onFilterByLocale} - selectedCulture={{ key: oformsFilter.locale, icon: oformsFilter.icon }} + selectedCulture={oformsFilter.locale} id="comboBoxLanguage" /> ); diff --git a/packages/shared/components/combobox/ComboBox.tsx b/packages/shared/components/combobox/ComboBox.tsx index 71020ccf2f..c2ce922abf 100644 --- a/packages/shared/components/combobox/ComboBox.tsx +++ b/packages/shared/components/combobox/ComboBox.tsx @@ -162,6 +162,8 @@ const ComboBoxPure = (props: ComboboxProps) => { title, className, plusBadgeValue, + optionStyle, + style, } = props; const { tabIndex, onClickSelectedItem } = props; @@ -223,10 +225,15 @@ const ComboBoxPure = (props: ComboboxProps) => { option.disabled || (!displaySelectedOption && option.label === selectedOption.label); - const isActive = - displaySelectedOption && option.label === selectedOption.label; + const isActiveOption = + typeof option.label === "string" + ? option.label === selectedOption.label + : option.key === selectedOption.key; + + const isActive = displaySelectedOption && isActiveOption; + + const isSelected = isActiveOption; - const isSelected = option.label === selectedOption.label; return ( { isModern={noBorder} isActive={isActive} isSelected={isSelected} + style={optionStyle} /> ); }) as React.ReactNode); @@ -290,7 +298,7 @@ const ComboBoxPure = (props: ComboboxProps) => { open={isOpen} forwardedRef={ref} clickOutsideAction={handleClickOutside} - style={advancedOptions ? { padding: "6px 0px" } : {}} + style={style} {...dropDownMaxHeightProp} {...dropDownManualWidthProp} showDisabledItems={showDisabledItems} diff --git a/packages/shared/components/combobox/Combobox.types.ts b/packages/shared/components/combobox/Combobox.types.ts index 5184c8cc38..47d0488097 100644 --- a/packages/shared/components/combobox/Combobox.types.ts +++ b/packages/shared/components/combobox/Combobox.types.ts @@ -148,6 +148,8 @@ export interface ComboboxProps { isLoading?: boolean; /** Type ComboBox */ type?: TCombobox; + /** Accepts css style */ + optionStyle: React.CSSProperties; setIsOpenItemAccess?: (value: boolean) => void; onClickSelectedItem?: (option: TOption) => void; withoutBackground?: boolean; diff --git a/packages/shared/components/combobox/sub-components/ComboButton.tsx b/packages/shared/components/combobox/sub-components/ComboButton.tsx index 8a113e3bc8..18165de80a 100644 --- a/packages/shared/components/combobox/sub-components/ComboButton.tsx +++ b/packages/shared/components/combobox/sub-components/ComboButton.tsx @@ -109,7 +109,7 @@ const ComboButton = (props: ComboButtonProps) => { )} {selectedOption && selectedOption.icon && ( { const separator = option?.props?.isSeparator ? { width: `calc(100% - 32px)`, height: `1px` } : {}; - const newStyle = { ...style, ...separator }; + + const optionStyle = option?.props.style ?? {}; + + const newStyle = { ...style, ...separator, ...optionStyle }; return ( { - const currentCulture = cultureNames.find( - (item) => item.key === selectedCulture.key, - ); - - if (!currentCulture) return ""; - - return currentCulture.icon; -}; const LanguageCombobox = (props: ComboboxProps) => { - const { - tabIndex, - cultures, - isAuthenticated = false, - onSelectLanguage, - selectedCulture, - id, - } = props; + const { cultures, onSelectLanguage, selectedCulture, className } = props; - const [isOpen, setIsOpen] = useState(false); - - const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onCloseDropdown = () => setIsOpen(false); + const { i18n } = useTranslation(["Common"]); const cultureNames = useMemo(() => { - return mapCulturesToArray(cultures, isAuthenticated); - }, [isAuthenticated, cultures]); + const withLabel = isMobile() ? i18n : undefined; + return mapCulturesToArray(cultures, false, withLabel); + }, [cultures]); + + const currentCulture = cultureNames.find( + (item) => item.key === selectedCulture, + ); const onSelect = (culture: TCulture) => { - if (culture.key === selectedCulture.key) return; + if (culture.key === selectedCulture) return; - onSelectLanguage(culture.key, culture.icon); - - onCloseDropdown(); - }; - - const advancedOptions = () => { - return ( - <> - {cultureNames.map((culture) => ( - onSelect(culture)} - fillIcon={false} - /> - ))} - - ); + onSelectLanguage(culture.key); }; return ( - - - - - + ); }; export { LanguageCombobox }; diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.types.ts b/packages/shared/components/language-combobox/LanguageCmbobox.types.ts index a1eacae921..65bf97cd53 100644 --- a/packages/shared/components/language-combobox/LanguageCmbobox.types.ts +++ b/packages/shared/components/language-combobox/LanguageCmbobox.types.ts @@ -32,10 +32,11 @@ export type TCulture = { export type TCultures = TCulture[]; export interface ComboboxProps { - selectedCulture: TCulture; + selectedCulture: string; cultures: string[]; tabIndex?: number | string; - isAuthenticated: boolean; /** Accepts id */ id?: string; + /** Accepts class */ + className?: string; } diff --git a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts index 9b9fc3c4d2..1aa758c0b7 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts @@ -23,98 +23,34 @@ // 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, { css } from "styled-components"; +import styled from "styled-components"; import { ComboBox } from "../combobox"; -import { DropDownItem } from "../drop-down-item"; -import { mobile } from "../../utils"; -export const LanguageComboBox = styled(ComboBox)` +export const StyledComboBox = styled(ComboBox)` width: 41px; - padding: 0; - box-sizing: border-box; - - .combo-button { - padding: 8px; - gap: 4px; - - .optionalBlock { - margin: 0; - & > div { - width: 16px; - height: 16px; - padding: 0; - display: flex; - align-items: center; - justify-content: center; - } - } - - .combo-button-label { - display: none; - } - - .combo-buttons_arrow-icon { - margin: 0; - } - } -`; - -export const SelectedItemComponent = styled(DropDownItem)` - box-sizing: border-box; - - display: flex; - align-items: center; - justify-content: center; - - .drop-down-icon { - margin: 0; - width: 16px; - height: 16px; - div { - display: flex; - align-items: center; - justify-content: center; - } - } -`; -export const ItemComponent = styled(DropDownItem)` height: 32px; - width: 41px; box-sizing: border-box; - padding: 8px; + padding: 0; - display: flex; - align-items: center; - justify-content: center; + :hover { + border-color: rgb(163, 169, 174); + } + .combo-button { + padding: 7px; + } - ${({ isSelected, theme }) => - isSelected && - css` - background-color: ${theme.dropDownItem.hoverBackgroundColor}; - `} - - .drop-down-icon { + .combo-button_selected-icon-container { + margin-right: 0px; + } + .combo-buttons_arrow-icon { margin: 0; - width: 16px; - height: 16px; - line-height: 0 !important; } - @media ${mobile} { - height: 36px; - width: 100%; - justify-content: start; - gap: 8px; - } -`; -export const WrapperComponent = styled.div` - width: 41px; - box-sizing: border-box; - .dropdown-container { - width: 100%; - box-sizing: border-box; - margin-top: 4px; + width: 41px; + .drop-down-item { + padding: 0; + } } `; diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 4fb988a1fc..8c2c6d3185 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -908,7 +908,7 @@ export function getObjectByLocation(location: Location) { if (!location.search || !location.search.length) return null; try { - const searchUrl = location.search.substring(1); + const searchUrl = location.search.substring(1); const params = Object.fromEntries(new URLSearchParams(searchUrl)); return params; } catch (e) { @@ -1047,7 +1047,7 @@ export const insertDataLayer = (id: string) => { type I18n = I18nextProviderProps["i18n"]; export const mapCulturesToArray = ( culturesArg: string[], - isAuthenticated: boolean, + isBetaBadge: boolean = true, i18nArg?: I18n, ) => { if (i18nArg) { @@ -1055,9 +1055,9 @@ export const mapCulturesToArray = ( return culturesArg.map((culture) => { return { key: culture, - ...(isAuthenticated && { label: t(`Culture_${culture}`) }), + label: t(`Culture_${culture}`), icon: flagsIcons?.get(`${culture}.react.svg`), - ...(isAuthenticated && { isBeta: isBetaLanguage(culture) }), + ...(isBetaBadge && { isBeta: isBetaLanguage(culture) }), }; }); } From d3d7fee131fa7935808eb5e9cf39fdf7ca4697fe Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 24 Apr 2024 15:17:13 +0300 Subject: [PATCH 012/126] Shared: Components: LanguageCmbobox: Deleted useless code. --- packages/shared/components/language-combobox/LanguageCmbobox.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.tsx b/packages/shared/components/language-combobox/LanguageCmbobox.tsx index e7dc846668..9c447daf32 100644 --- a/packages/shared/components/language-combobox/LanguageCmbobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCmbobox.tsx @@ -68,7 +68,6 @@ const LanguageCombobox = (props: ComboboxProps) => { displaySelectedOption manualWidth="41px" noBorder={false} - onlyIcon type="onlyIcon" optionStyle={{ padding: "0 8px" }} style={{ padding: "6px 0px" }} From c38b8397fdb34e92470432dcc20bace5af6e619a Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 24 Apr 2024 15:19:22 +0300 Subject: [PATCH 013/126] Shared: Components: Renamed. --- .../{LanguageCmbobox.tsx => LanguageCombobox.tsx} | 2 +- .../{LanguageCmbobox.types.ts => LanguageCombobox.types.ts} | 0 packages/shared/components/language-combobox/index.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename packages/shared/components/language-combobox/{LanguageCmbobox.tsx => LanguageCombobox.tsx} (97%) rename packages/shared/components/language-combobox/{LanguageCmbobox.types.ts => LanguageCombobox.types.ts} (100%) diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx similarity index 97% rename from packages/shared/components/language-combobox/LanguageCmbobox.tsx rename to packages/shared/components/language-combobox/LanguageCombobox.tsx index 9c447daf32..45d0368c90 100644 --- a/packages/shared/components/language-combobox/LanguageCmbobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -29,7 +29,7 @@ import { useTranslation } from "react-i18next"; import { mapCulturesToArray } from "../../utils/common"; import { isMobile } from "../../utils"; import { StyledComboBox } from "./LanguageCombobox.styled"; -import { TCulture, ComboboxProps } from "./LanguageCmbobox.types"; +import { TCulture, ComboboxProps } from "./LanguageCombobox.types"; const LanguageCombobox = (props: ComboboxProps) => { const { cultures, onSelectLanguage, selectedCulture, className } = props; diff --git a/packages/shared/components/language-combobox/LanguageCmbobox.types.ts b/packages/shared/components/language-combobox/LanguageCombobox.types.ts similarity index 100% rename from packages/shared/components/language-combobox/LanguageCmbobox.types.ts rename to packages/shared/components/language-combobox/LanguageCombobox.types.ts diff --git a/packages/shared/components/language-combobox/index.ts b/packages/shared/components/language-combobox/index.ts index ef8c1985b5..bd226aebfa 100644 --- a/packages/shared/components/language-combobox/index.ts +++ b/packages/shared/components/language-combobox/index.ts @@ -23,4 +23,4 @@ // 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 -export { LanguageCombobox } from "./LanguageCmbobox"; +export { LanguageCombobox } from "./LanguageCombobox"; From e3cdfe9c72e9fd81c5c4e91970adf56922e625e8 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 25 Apr 2024 10:40:21 +0300 Subject: [PATCH 014/126] Web: Client: Added language change. --- packages/client/src/HOCs/withCultureNames.tsx | 29 +-------- .../NavMenu/sub-components/header-unauth.js | 57 ++++++++++-------- .../Confirm/sub-components/createUser.js | 59 ++++++++++++------- 3 files changed, 72 insertions(+), 73 deletions(-) diff --git a/packages/client/src/HOCs/withCultureNames.tsx b/packages/client/src/HOCs/withCultureNames.tsx index c7ecfe8f74..bf5373362f 100644 --- a/packages/client/src/HOCs/withCultureNames.tsx +++ b/packages/client/src/HOCs/withCultureNames.tsx @@ -73,36 +73,9 @@ export default function withCultureNames< () => mapCulturesToArray(cultures, true, i18n), [cultures, isAuthenticated], ); - const url = new URL(window.location.href); - const culture = url.searchParams.get("culture"); - const currentCultureName = culture ?? getCookie(LANGUAGE); - const selectedCultureObj = cultureNames.find( - (item) => item.key === currentCultureName, - ); - - const onLanguageSelect = (e: KeyboardEvent) => { - i18n.changeLanguage(e.key); - - setCookie(LANGUAGE, e.key, { - "max-age": COOKIE_EXPIRATION_YEAR, - }); - - if (culture) { - window.location.href = url.replace( - `culture=${culture}`, - `culture=${e.key}`, - ); - } - }; return cultures.length > 0 && tReady ? ( - + ) : ( ); diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 0c5e283b56..b0224ff7fa 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -1,4 +1,4 @@ -// (c) Copyright Ascensio System SIA 2009-2024 +// (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 @@ -28,13 +28,14 @@ import React from "react"; import PropTypes from "prop-types"; import styled from "styled-components"; import { Box } from "@docspace/shared/components/box"; -import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; import { Base } from "@docspace/shared/themes"; import { mobile, getLogoUrl } from "@docspace/shared/utils"; import { WhiteLabelLogoType } from "@docspace/shared/enums"; -import { ComboBox } from "@docspace/shared/components/combobox"; -import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; +import { setCookie } from "@docspace/shared/utils/cookie"; +import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; +import i18n from "../../../i18n"; const Header = styled.header` align-items: left; @@ -91,13 +92,29 @@ const HeaderUnAuth = ({ isAuthenticated, isLoaded, theme, - cultureNames, - selectedCultureObj, - onLanguageSelect, + cultures, }) => { - const { t } = useTranslation("NavMenu"); const logo = getLogoUrl(WhiteLabelLogoType.LightSmall, !theme.isBase); + const currentCultureName = i18n.language; + + const onSelect = (culture) => { + i18n.changeLanguage(culture); + + setCookie(LANGUAGE, culture, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + const url = new URL(window.location.href); + const prevCulture = url.searchParams.get("culture"); + + if (prevCulture) { + const newUrl = location.href.replace(`&culture=${prevCulture}`, ``); + + window.history.pushState("", "", newUrl); + } + }; + return (
-
); @@ -149,7 +155,7 @@ HeaderUnAuth.propTypes = { export default inject(({ authStore, settingsStore }) => { const { isAuthenticated, isLoaded } = authStore; - const { enableAdmMess, wizardToken, theme } = settingsStore; + const { enableAdmMess, wizardToken, theme, cultures } = settingsStore; return { enableAdmMess, @@ -157,5 +163,6 @@ export default inject(({ authStore, settingsStore }) => { isAuthenticated, isLoaded, theme, + cultures, }; -})(withCultureNames(observer(HeaderUnAuth))); +})(observer(HeaderUnAuth)); diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 0689f28308..69b6dd9b94 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -51,7 +51,11 @@ import { getLoginLink, } from "@docspace/shared/utils/common"; import { login } from "@docspace/shared/utils/loginUtils"; -import { PROVIDERS_DATA } from "@docspace/shared/constants"; +import { + COOKIE_EXPIRATION_YEAR, + LANGUAGE, + PROVIDERS_DATA, +} from "@docspace/shared/constants"; import { combineUrl } from "@docspace/shared/utils/combineUrl"; import { getPasswordErrorMessage } from "@docspace/shared/utils/getPasswordErrorMessage"; @@ -68,6 +72,8 @@ import GreetingUserContainer from "./GreetingUserContainer"; import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; import { isMobile } from "@docspace/shared/utils"; import { ComboBox } from "@docspace/shared/components/combobox"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; +import { setCookie } from "@docspace/shared/utils/cookie"; const DEFAULT_ROOM_TEXT = "{{firstName}} {{lastName}} invites you to join the room {{roomName}} for secure document collaboration."; @@ -105,12 +111,12 @@ const CreateUserForm = (props) => { currentColorScheme, userNameRegex, defaultPage, - cultureNames, - selectedCultureObj, - currentCultureName, - onLanguageSelect, + cultures, + i18n, } = props; + const currentCultureName = i18n.language; + const inputRef = React.useRef(null); const emailFromLink = linkData?.email ? linkData.email : ""; @@ -207,6 +213,10 @@ const CreateUserForm = (props) => { await getUserByEmail(email, headerKey); + setCookie(LANGUAGE, currentCultureName, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + window.location.href = combineUrl( window.DocSpaceConfig?.proxy?.url, "/login", @@ -467,27 +477,34 @@ const CreateUserForm = (props) => { } : {}; + const onSelect = (culture) => { + i18n.changeLanguage(culture); + + setCookie(LANGUAGE, culture, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + const url = new URL(window.location.href); + const prevCulture = url.searchParams.get("culture"); + + if (prevCulture) { + const newUrl = location.href.replace(`&culture=${prevCulture}`, ``); + + window.history.pushState("", "", newUrl); + } + }; + return ( {!isMobile() && ( - )} + @@ -745,6 +762,7 @@ export default inject(({ settingsStore, authStore }) => { getPortalPasswordSettings, currentColorScheme, userNameRegex, + cultures, } = settingsStore; return { settings: passwordSettings, @@ -758,6 +776,7 @@ export default inject(({ settingsStore, authStore }) => { capabilities, currentColorScheme, userNameRegex, + cultures, }; })( withCultureNames( From 464a2b610663fb25c6c34acd663e8ee1bfed1aa2 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 25 Apr 2024 10:40:50 +0300 Subject: [PATCH 015/126] Web: Shared: LanguageCombobox: Refactoring. --- .../shared/components/language-combobox/LanguageCombobox.tsx | 5 +++++ .../components/language-combobox/LanguageCombobox.types.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index 45d0368c90..03be3ca5bc 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -23,6 +23,7 @@ // 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 React from "react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; @@ -40,17 +41,21 @@ const LanguageCombobox = (props: ComboboxProps) => { const withLabel = isMobile() ? i18n : undefined; return mapCulturesToArray(cultures, false, withLabel); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [cultures]); const currentCulture = cultureNames.find( (item) => item.key === selectedCulture, ); + const onSelect = (culture: TCulture) => { if (culture.key === selectedCulture) return; onSelectLanguage(culture.key); }; + if (!currentCulture) return <>; + return ( void; /** Accepts id */ id?: string; /** Accepts class */ From 19ad105bb1aee899efaf30f95da326840d3fe84a Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 25 Apr 2024 10:41:36 +0300 Subject: [PATCH 016/126] Web: Login: Added new component. --- .../login/src/client/components/Login.tsx | 36 ++++--------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index 4b1b170394..cfaee6a5ad 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -36,7 +36,6 @@ import { getOAuthToken, getLoginLink, getEditorTheme, - mapCulturesToArray, } from "@docspace/shared/utils/common"; import { Link } from "@docspace/shared/components/link"; import { checkIsSSR, getLogoUrl, getSystemTheme } from "@docspace/shared/utils"; @@ -60,7 +59,7 @@ import GreetingContainer from "./sub-components/GreetingContainer"; import { Scrollbar } from "@docspace/shared/components/scrollbar"; import { setCookie } from "@docspace/shared/utils/cookie"; -import { ComboBox } from "@docspace/shared/components/combobox"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; const themes = { Dark: Dark, @@ -92,11 +91,6 @@ const Login: React.FC = ({ const isRestoringPortal = portalSettings?.tenantStatus === TenantStatus.PortalRestore; - const cultureNames = useMemo( - () => mapCulturesToArray(cultures, false), - [cultures] - ); - useEffect(() => { if (search) { const firstIndex = search.indexOf("loginData="); @@ -129,6 +123,7 @@ const Login: React.FC = ({ const { t, i18n } = useTranslation(["Login", "Common"]); const currentCulture = i18n.language; + const [isLoading, setIsLoading] = useState(false); const [recoverDialogVisible, setRecoverDialogVisible] = useState(false); const [invitationLinkData, setInvitationLinkData] = useState({ @@ -151,13 +146,7 @@ const Login: React.FC = ({ cookieSettingsEnabled: false, }; - const selectedCultureObj = cultureNames.find( - (item) => item.key === currentCulture - ); - - const onLanguageSelect = (e: KeyboardEvent) => { - const culture = e.key; - + const onLanguageSelect = (culture: string) => { i18n.changeLanguage(culture); setCookie(LANGUAGE, culture, { @@ -282,22 +271,11 @@ const Login: React.FC = ({ >
- Date: Thu, 25 Apr 2024 10:42:58 +0300 Subject: [PATCH 017/126] Web: Client: ConfirmRoute: Added language check by cookie. --- packages/client/src/helpers/confirmRoute.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/client/src/helpers/confirmRoute.js b/packages/client/src/helpers/confirmRoute.js index 333821cd24..6ed2227749 100644 --- a/packages/client/src/helpers/confirmRoute.js +++ b/packages/client/src/helpers/confirmRoute.js @@ -37,6 +37,8 @@ import { combineUrl } from "@docspace/shared/utils/combineUrl"; import SectionWrapper from "SRC_DIR/components/Section"; import { AuthenticatedAction, ValidationResult } from "SRC_DIR/helpers/enums"; +import { getCookie } from "@docspace/shared/utils"; +import { LANGUAGE } from "@docspace/shared/constants"; const ConfirmRoute = ({ doAuthenticated, @@ -57,8 +59,9 @@ const ConfirmRoute = ({ React.useEffect(() => { if (location.search.includes("culture")) return; - - storeIsLoaded && i18n.changeLanguage(culture); + const lng = getCookie(LANGUAGE); + + storeIsLoaded && i18n.changeLanguage(lng); }, [storeIsLoaded]); const location = useLocation(); From 151aa7d4e4e0257c0806c40d116532164b92d036 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 25 Apr 2024 12:23:11 +0300 Subject: [PATCH 018/126] Web: Client/Shared: Added new prop. --- .../NavMenu/sub-components/header-unauth.js | 1 + .../Confirm/sub-components/createUser.js | 1 + .../login/src/client/components/Login.tsx | 1 + .../LanguageCombobox.styled.ts | 19 ++++++++++++++----- .../language-combobox/LanguageCombobox.tsx | 11 ++++++++++- .../LanguageCombobox.types.ts | 2 ++ 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index b0224ff7fa..807bfa8c57 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -139,6 +139,7 @@ const HeaderUnAuth = ({ onSelectLanguage={onSelect} cultures={cultures} selectedCulture={currentCultureName} + withBorder={false} />
); diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 69b6dd9b94..d59243b785 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -502,6 +502,7 @@ const CreateUserForm = (props) => { onSelectLanguage={onSelect} cultures={cultures} selectedCulture={currentCultureName} + withBorder={false} /> )} diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index cfaee6a5ad..d5d9882f9c 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -276,6 +276,7 @@ const Login: React.FC = ({ onSelectLanguage={onLanguageSelect} cultures={cultures} selectedCulture={currentCulture} + withBorder={false} /> ` width: 41px; height: 32px; box-sizing: border-box; padding: 0; - :hover { - border-color: rgb(163, 169, 174); - } .combo-button { padding: 7px; + + ${(props) => + !props.withBorder && + css` + border-width: 0; + background: transparent; + `}; + + :hover { + border-color: rgb(163, 169, 174); + } } .combo-button_selected-icon-container { diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index 03be3ca5bc..96d4713e16 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -33,7 +33,13 @@ import { StyledComboBox } from "./LanguageCombobox.styled"; import { TCulture, ComboboxProps } from "./LanguageCombobox.types"; const LanguageCombobox = (props: ComboboxProps) => { - const { cultures, onSelectLanguage, selectedCulture, className } = props; + const { + cultures, + onSelectLanguage, + selectedCulture, + className, + withBorder = true, + } = props; const { i18n } = useTranslation(["Common"]); @@ -54,10 +60,12 @@ const LanguageCombobox = (props: ComboboxProps) => { onSelectLanguage(culture.key); }; + console.log("currentCulture", selectedCulture, cultureNames); if (!currentCulture) return <>; return ( { style={{ padding: "6px 0px" }} isMobileView={isMobile()} withBlur={isMobile()} + withBorder={withBorder} /> ); }; diff --git a/packages/shared/components/language-combobox/LanguageCombobox.types.ts b/packages/shared/components/language-combobox/LanguageCombobox.types.ts index 728ac65624..77b3451bab 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.types.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.types.ts @@ -39,4 +39,6 @@ export interface ComboboxProps { id?: string; /** Accepts class */ className?: string; + /** Indicates that component contain border */ + withBorder?: boolean; } From 5eda0f0abb4c25557ff3eb6788db4ec9b893898b Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 25 Apr 2024 12:25:46 +0300 Subject: [PATCH 019/126] Web: Shared: Components: LanguageCombobox: Refactoring. --- .../components/language-combobox/LanguageCombobox.styled.ts | 1 - .../shared/components/language-combobox/LanguageCombobox.tsx | 2 -- 2 files changed, 3 deletions(-) diff --git a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts index 42513b9e9b..0912b86bc1 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts @@ -1,4 +1,3 @@ -import { transform } from "lodash"; // (c) Copyright Ascensio System SIA 2009-2024 // // This program is a free software product. diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index 96d4713e16..d28752d0fe 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -60,12 +60,10 @@ const LanguageCombobox = (props: ComboboxProps) => { onSelectLanguage(culture.key); }; - console.log("currentCulture", selectedCulture, cultureNames); if (!currentCulture) return <>; return ( Date: Fri, 26 Apr 2024 10:43:28 +0300 Subject: [PATCH 020/126] Web: Added getting indexes for the form gallery to restore supported language. --- .../NavMenu/sub-components/header-unauth.js | 6 ++- .../Confirm/sub-components/createUser.js | 6 ++- .../Filter/LanguageFilter/index.js | 38 +++++++++++++++---- packages/client/src/store/OformsStore.js | 16 +++----- .../login/src/client/components/Login.tsx | 8 ++-- .../language-combobox/LanguageCombobox.tsx | 2 +- .../LanguageCombobox.types.ts | 3 +- packages/shared/utils/common.ts | 33 ++-------------- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 807bfa8c57..61c69e37f6 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -99,9 +99,11 @@ const HeaderUnAuth = ({ const currentCultureName = i18n.language; const onSelect = (culture) => { - i18n.changeLanguage(culture); + const { key } = culture; - setCookie(LANGUAGE, culture, { + i18n.changeLanguage(key); + + setCookie(LANGUAGE, key, { "max-age": COOKIE_EXPIRATION_YEAR, }); diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index d59243b785..036797949a 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -478,9 +478,11 @@ const CreateUserForm = (props) => { : {}; const onSelect = (culture) => { - i18n.changeLanguage(culture); + const { key } = culture; - setCookie(LANGUAGE, culture, { + i18n.changeLanguage(key); + + setCookie(LANGUAGE, key, { "max-age": COOKIE_EXPIRATION_YEAR, }); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index aa4ec8b717..83c0645142 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -31,10 +31,28 @@ import { inject, observer } from "mobx-react"; import { RectangleSkeleton } from "@docspace/shared/skeletons"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; + +const keyedCollections = { + ar: "ar-SA", + en: "en-US", + el: "el-GR", + hy: "hy-AM", + ko: "ko-KR", + lo: "lo-LA", + pt: "pt-BR", + uk: "uk-UA", + ja: "ja-JP", + zh: "zh-CN", +}; + +const convertToCulture = (key) => { + return keyedCollections[key] ?? key; +}; + +const getOformLocaleByIndex = (index, array) => { + return array[index]; +}; const LanguageFilter = ({ - t, - oformsFilter, - defaultOformLocale, oformLocales, filterOformsByLocale, filterOformsByLocaleIsLoading, @@ -42,9 +60,14 @@ const LanguageFilter = ({ categoryFilterLoaded, languageFilterLoaded, oformFilesLoaded, + oformsCurrentLocal, }) => { + const convertedLocales = oformLocales.map((item) => convertToCulture(item)); + const onFilterByLocale = async (newLocale) => { - await filterOformsByLocale(newLocale); + const key = getOformLocaleByIndex(newLocale.index, oformLocales); + + await filterOformsByLocale(key); const [sectionScroll] = document.getElementsByClassName("section-scroll"); sectionScroll.scrollTop = 0; @@ -62,18 +85,16 @@ const LanguageFilter = ({ return ( ); }; export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - defaultOformLocale: oformsStore.defaultOformLocale, oformLocales: oformsStore.oformLocales, filterOformsByLocale: oformsStore.filterOformsByLocale, filterOformsByLocaleIsLoading: oformsStore.filterOformsByLocaleIsLoading, @@ -81,4 +102,5 @@ export default inject(({ oformsStore }) => ({ categoryFilterLoaded: oformsStore.categoryFilterLoaded, languageFilterLoaded: oformsStore.languageFilterLoaded, oformFilesLoaded: oformsStore.oformFilesLoaded, + oformsCurrentLocal: oformsStore.oformsCurrentLocal, }))(withTranslation(["Common"])(observer(LanguageFilter))); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index da7a109a99..7b6bf6256d 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -41,14 +41,10 @@ import { } from "@docspace/shared/api/oforms"; import { toastr } from "@docspace/shared/components/toast"; -import { - convertToCulture, - convertToLanguage, -} from "@docspace/shared/utils/common"; +import { convertToLanguage } from "@docspace/shared/utils/common"; import { LANGUAGE } from "@docspace/shared/constants"; import { getCookie } from "@docspace/shared/utils/cookie"; import { combineUrl } from "@docspace/shared/utils/combineUrl"; -import { flagsIcons } from "@docspace/shared/utils/image-flags"; const myDocumentsFolderId = 2; @@ -115,11 +111,7 @@ class OformsStore { this.infoPanelStore.setInfoPanelSelection(gallerySelected); }; - setOformLocales = (oformLocales) => { - const convertedLocales = oformLocales.map((item) => convertToCulture(item)); - - this.oformLocales = convertedLocales; - }; + setOformLocales = (oformLocales) => (this.oformLocales = oformLocales); setFilterOformsByLocaleIsLoading = (filterOformsByLocaleIsLoading) => { this.filterOformsByLocaleIsLoading = filterOformsByLocaleIsLoading; @@ -385,6 +377,10 @@ class OformsStore { get hasMoreForms() { return this.oformFiles.length < this.oformsFilterTotal; } + + get oformsCurrentLocal() { + return this.oformsFilter.locale; + } } export default OformsStore; diff --git a/packages/login/src/client/components/Login.tsx b/packages/login/src/client/components/Login.tsx index d5d9882f9c..66921d5a32 100644 --- a/packages/login/src/client/components/Login.tsx +++ b/packages/login/src/client/components/Login.tsx @@ -146,10 +146,12 @@ const Login: React.FC = ({ cookieSettingsEnabled: false, }; - const onLanguageSelect = (culture: string) => { - i18n.changeLanguage(culture); + const onLanguageSelect = (culture: { key: string }) => { + const { key } = culture; - setCookie(LANGUAGE, culture, { + i18n.changeLanguage(key); + + setCookie(LANGUAGE, key, { "max-age": COOKIE_EXPIRATION_YEAR, }); }; diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index d28752d0fe..41d7a1f548 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -57,7 +57,7 @@ const LanguageCombobox = (props: ComboboxProps) => { const onSelect = (culture: TCulture) => { if (culture.key === selectedCulture) return; - onSelectLanguage(culture.key); + onSelectLanguage(culture); }; if (!currentCulture) return <>; diff --git a/packages/shared/components/language-combobox/LanguageCombobox.types.ts b/packages/shared/components/language-combobox/LanguageCombobox.types.ts index 77b3451bab..a1844b8dcb 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.types.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.types.ts @@ -28,13 +28,14 @@ export type TCulture = { key: string; icon: string; label?: string; + index?: number; }; export type TCultures = TCulture[]; export interface ComboboxProps { selectedCulture: string; cultures: string[]; - onSelectLanguage: (culture: string) => void; + onSelectLanguage: (culture: TCulture) => void; /** Accepts id */ id?: string; /** Accepts class */ diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 8c2c6d3185..099b7ea922 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -481,33 +481,6 @@ export function convertLanguage(key: string) { } } -export function convertToCulture(key: string) { - switch (key) { - case "ar": - return "ar-SA"; - case "en": - return "en-US"; - case "el": - return "el-GR"; - case "hy": - return "hy-AM"; - case "ko": - return "ko-KR"; - case "lo": - return "lo-LA"; - case "pt": - return "pt-BR"; - case "uk": - return "uk-UA"; - case "ja": - return "ja-JP"; - case "zh": - return "zh-CN"; - default: - return key; - } -} - export function convertToLanguage(key: string) { if (!key) return; @@ -1052,20 +1025,22 @@ export const mapCulturesToArray = ( ) => { if (i18nArg) { const t = i18nArg.getFixedT(null, "Common"); - return culturesArg.map((culture) => { + return culturesArg.map((culture, index) => { return { key: culture, label: t(`Culture_${culture}`), icon: flagsIcons?.get(`${culture}.react.svg`), ...(isBetaBadge && { isBeta: isBetaLanguage(culture) }), + index, }; }); } - return culturesArg.map((culture) => { + return culturesArg.map((culture, index) => { return { key: culture, icon: flagsIcons?.get(`${culture}.react.svg`), + index, }; }); }; From 271b9c21a1b231be53dda67309f62ab1fada1573 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 13 May 2024 14:28:35 +0300 Subject: [PATCH 021/126] Shared: fix storybook start --- packages/shared/.storybook/main.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/shared/.storybook/main.js b/packages/shared/.storybook/main.js index af58575c23..b7eb5c0482 100644 --- a/packages/shared/.storybook/main.js +++ b/packages/shared/.storybook/main.js @@ -44,6 +44,16 @@ module.exports = { docs: { autodocs: true, }, + typescript: { + check: false, + checkOptions: {}, + reactDocgen: false, + reactDocgenTypescriptOptions: { + shouldExtractLiteralValuesFromEnum: true, + propFilter: (prop) => + prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, + }, + }, }; function getAbsolutePath(value) { From 557b43feb9c63ff7bde62363157a3aedff5af759 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 13 May 2024 14:28:56 +0300 Subject: [PATCH 022/126] Shared:Components:Selector: add NewItem and InputItem --- .../components/selector/Selector.stories.tsx | 10 +++ .../components/selector/Selector.styled.ts | 6 +- .../components/selector/Selector.types.ts | 32 +++++++++ .../selector/sub-components/InputItem.tsx | 0 .../selector/sub-components/Item.tsx | 8 +++ .../selector/sub-components/NewItem.tsx | 66 +++++++++++++++++++ 6 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 packages/shared/components/selector/sub-components/InputItem.tsx create mode 100644 packages/shared/components/selector/sub-components/NewItem.tsx diff --git a/packages/shared/components/selector/Selector.stories.tsx b/packages/shared/components/selector/Selector.stories.tsx index f811fd78d6..7561e6b63f 100644 --- a/packages/shared/components/selector/Selector.stories.tsx +++ b/packages/shared/components/selector/Selector.stories.tsx @@ -89,6 +89,16 @@ function makeName() { const getItems = (count: number) => { const items: TSelectorItem[] = []; + console.log("call"); + + items.push({ + key: "create_new", + id: "create_new_item", + label: "New folder", + isCreateNewItem: true, + onCreateClick: () => {}, + }); + for (let i = 0; i < count / 2; i += 1) { const label = makeName(); items.push({ diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index 2b3fa130c2..e7841acabe 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -186,6 +186,7 @@ const StyledItem = styled.div<{ isSelected: boolean | undefined; isDisabled?: boolean; isMultiSelect: boolean; + noHover?: boolean; }>` display: flex; align-items: center; @@ -245,12 +246,13 @@ const StyledItem = styled.div<{ ` : css` ${props.isSelected && !props.isMultiSelect && selectedCss} - @media (hover: hover) { + ${!props.noHover && + ` @media (hover: hover) { &:hover { cursor: pointer; background: ${props.theme.selector.item.hoverBackground}; } - } + }`} `} `; diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index 06de7293b6..7f7b4f7a56 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -435,6 +435,8 @@ type TSelectorItemType = security?: undefined; isGroup?: undefined; name?: undefined; + isCreateNewItem?: undefined; + onCreateClick?: undefined; } | { email?: undefined; @@ -455,6 +457,8 @@ type TSelectorItemType = security?: TFileSecurity; isGroup?: undefined; name?: undefined; + isCreateNewItem?: undefined; + onCreateClick?: undefined; } | { email?: undefined; @@ -475,6 +479,8 @@ type TSelectorItemType = security?: TRoomSecurity; isGroup?: undefined; name?: undefined; + isCreateNewItem?: undefined; + onCreateClick?: undefined; } | { email?: undefined; @@ -495,6 +501,8 @@ type TSelectorItemType = security?: TFolderSecurity; isGroup?: undefined; name?: undefined; + isCreateNewItem?: undefined; + onCreateClick?: undefined; } | { email?: undefined; @@ -515,6 +523,30 @@ type TSelectorItemType = security?: TFolderSecurity; isGroup: true; name: string; + isCreateNewItem?: undefined; + onCreateClick?: undefined; + } + | { + email?: undefined; + fileExst?: undefined; + roomType?: undefined; + shared?: undefined; + isOwner?: undefined; + isAdmin?: undefined; + isVisitor?: undefined; + isCollaborator?: undefined; + isRoomAdmin?: undefined; + access?: undefined; + isFolder?: undefined; + parentId?: undefined; + rootFolderType?: undefined; + filesCount?: undefined; + foldersCount?: undefined; + security?: undefined; + isGroup?: undefined; + name?: undefined; + isCreateNewItem: boolean; + onCreateClick: VoidFunction; }; export type TSelectorItem = TSelectorItemLogo & diff --git a/packages/shared/components/selector/sub-components/InputItem.tsx b/packages/shared/components/selector/sub-components/InputItem.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index bc67babf1f..49352bbbcc 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -36,6 +36,7 @@ import { RoomIcon } from "../../room-icon"; import { StyledItem } from "../Selector.styled"; import { ItemProps, Data, TSelectorItem } from "../Selector.types"; import { RoomsType } from "../../../enums"; +import NewItem from "./NewItem"; const compareFunction = (prevProps: ItemProps, nextProps: ItemProps) => { const prevData = prevProps.data; @@ -90,8 +91,15 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { email, isGroup, disabledText, + isCreateNewItem, + onCreateClick, } = item; + if (isCreateNewItem) + return ( + + ); + const showPlanetIcon = (item.roomType === RoomsType.PublicRoom || item.roomType === RoomsType.CustomRoom) && diff --git a/packages/shared/components/selector/sub-components/NewItem.tsx b/packages/shared/components/selector/sub-components/NewItem.tsx new file mode 100644 index 0000000000..dd6a68626c --- /dev/null +++ b/packages/shared/components/selector/sub-components/NewItem.tsx @@ -0,0 +1,66 @@ +// (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 React from "react"; + +import { Text } from "../../text"; +import { SelectorAddButton } from "../../selector-add-button"; + +import { StyledItem } from "../Selector.styled"; + +const NewItem = ({ + label, + style, + onCreateClick, +}: { + label: string; + style: React.CSSProperties; + onCreateClick: VoidFunction; +}) => { + return ( + + + + {label} + + + ); +}; + +export default NewItem; From 0bfc0dbae1a928addb2d8655a852b73acc9767aa Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Fri, 17 May 2024 12:06:57 +0300 Subject: [PATCH 023/126] Shared:ContextMenu:Fixed not having enough space when opening the list of spaces. Also in rtl format. --- .../context-menu/ContextMenu.styled.ts | 3 + .../context-menu/sub-components/SubMenu.tsx | 58 +++++++++++++++---- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/shared/components/context-menu/ContextMenu.styled.ts b/packages/shared/components/context-menu/ContextMenu.styled.ts index 74e71c727f..40bb44eb67 100644 --- a/packages/shared/components/context-menu/ContextMenu.styled.ts +++ b/packages/shared/components/context-menu/ContextMenu.styled.ts @@ -285,6 +285,9 @@ const StyledContextMenu = styled.div<{ .p-contextmenu .p-menuitem-text { line-height: 36px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .p-contextmenu .p-menu-separator { diff --git a/packages/shared/components/context-menu/sub-components/SubMenu.tsx b/packages/shared/components/context-menu/sub-components/SubMenu.tsx index 5e9b4ed5bc..812ddab76c 100644 --- a/packages/shared/components/context-menu/sub-components/SubMenu.tsx +++ b/packages/shared/components/context-menu/sub-components/SubMenu.tsx @@ -156,21 +156,55 @@ const SubMenu = (props: { subMenuRef.current.style.top = `${-1 * topOffset}px`; } + const containerOffsetLeft = parseInt(`${containerOffset.left}`, 10); + const freeSpaceRight = + viewport.width - containerOffsetLeft - itemOuterWidth; + const freeSpaceLeft = containerOffsetLeft; + const submenuListMargin = 4; + const sectionPadding = 17; + if (isRtl) { - if (subListWidth < parseInt(`${containerOffset.left}`, 10)) { + if ( + !root && + freeSpaceLeft > freeSpaceRight && + subListWidth > containerOffsetLeft + ) { + // If the menu extends beyond the screen + subMenuRef.current.style.width = `${containerOffsetLeft - submenuListMargin - sectionPadding}px`; + } + + if ( + subListWidth < containerOffsetLeft || + (!root && freeSpaceLeft > freeSpaceRight) + ) { subMenuRef.current.style.left = `${-1 * subListWidth}px`; } else { subMenuRef.current.style.left = `${itemOuterWidth}px`; } - } else if ( - parseInt(`${containerOffset.left}`, 10) + - itemOuterWidth + - subListWidth > - viewport.width - DomHelpers.calculateScrollbarWidth() - ) { - subMenuRef.current.style.left = `${-1 * subListWidth}px`; - } else { - subMenuRef.current.style.left = `${itemOuterWidth}px`; + } + + const notEnoughWidthRight = + containerOffsetLeft + itemOuterWidth + subListWidth > + viewport.width - DomHelpers.calculateScrollbarWidth(); + + if (!isRtl) { + if (notEnoughWidthRight && containerOffsetLeft > subListWidth) { + subMenuRef.current.style.left = `${-1 * subListWidth}px`; + } else { + subMenuRef.current.style.left = `${itemOuterWidth}px`; + + if (notEnoughWidthRight && !root) { + // If the menu extends beyond the screen + const newWidth = + viewport.width - + containerOffsetLeft - + itemOuterWidth - + submenuListMargin - + sectionPadding; + + subMenuRef.current.style.width = `${newWidth}px`; + } + } } } }; @@ -268,7 +302,9 @@ const SubMenu = (props: { )); const label = item.label && ( - {item.label} + + {item.label} + ); const subMenuIcon = (item.items || item.onLoad) && ( From 8b33ddf81f771c47717ded94839d4313115e1501 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Fri, 17 May 2024 17:04:58 +0500 Subject: [PATCH 024/126] Web: Client: JavascriptSDK: fixed redirection link --- .../GoogleWorkspace/Stepper/ImportCompleteStep/index.js | 2 +- .../data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js | 2 +- .../NextCloudWorkspace/Stepper/ImportCompleteStep/index.js | 2 +- .../NextCloudWorkspace/Stepper/SelectFileStep/index.js | 2 +- .../OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js | 2 +- .../OnlyofficeWorkspace/Stepper/SelectFileStep/index.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/ImportCompleteStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/ImportCompleteStep/index.js index 15b11faa0b..ec10a0d0fe 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/ImportCompleteStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/ImportCompleteStep/index.js @@ -107,7 +107,7 @@ const ImportCompleteStep = ({ setIsSaving(true); setTimeout(() => { setIsSaving(false); - navigate(-1); + navigate("/portal-settings/data-import/migration"); }, 1000); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js index e0c842b7e4..db908547f7 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js @@ -119,7 +119,7 @@ const SelectFileStep = ({ const goBack = () => { cancelMigration(); - setTimeout(() => navigate(-1), 100); + setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); }; const checkMigrationStatusAndUpdate = async () => { diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js index 7992c6f0c8..846a1a85fa 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js @@ -96,7 +96,7 @@ const ImportCompleteStep = ({ setIsSaving(true); setTimeout(() => { setIsSaving(false); - navigate(-1); + setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); }, 1000); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js index 8d4e0cef1f..a44433f408 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js @@ -127,7 +127,7 @@ const SelectFileStep = ({ const goBack = () => { cancelMigration(); - setTimeout(() => navigate(-1), 100); + setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); }; const checkMigrationStatusAndUpdate = async () => { diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js index a0ab2b0c49..8a928ddf57 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js @@ -107,7 +107,7 @@ const ImportCompleteStep = ({ setIsSaving(true); setTimeout(() => { setIsSaving(false); - navigate(-1); + setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); }, 1000); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js index 43ee986598..9d7cf46a5d 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js @@ -117,7 +117,7 @@ const SelectFileStep = ({ const goBack = () => { cancelMigration(); - setTimeout(() => navigate(-1), 100); + setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); }; const checkMigrationStatusAndUpdate = async () => { From 9efe35033bcd8eb6687d7cd5bd4fb804cf556f85 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Tue, 21 May 2024 16:04:06 +0500 Subject: [PATCH 025/126] Web: Client: Data Import: added users limit blocks --- .../Stepper/SelectUsersStep/index.js | 22 +++++++++++------ .../Stepper/AddEmailsStep/index.js | 24 +++++++++++++------ .../Stepper/SelectUsersStep/index.js | 17 ++++++++----- .../Stepper/SelectUsersStep/index.js | 24 ++++++++++++------- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js index ef7bf65dbf..3b26acf1b6 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js @@ -32,9 +32,9 @@ import { SearchInput } from "@docspace/shared/components/search-input"; import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../../sub-components/AccountsPaging"; -// import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; +import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; -// const LICENSE_LIMIT = 100; +const LICENSE_LIMIT = 1; const SelectUsersStep = ({ t, @@ -46,6 +46,7 @@ const SelectUsersStep = ({ setResultUsers, areCheckedUsersEmpty, cancelMigration, + checkedUsers, }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); @@ -92,15 +93,17 @@ const SelectUsersStep = ({ saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings={true} - saveButtonDisabled={areCheckedUsersEmpty} + saveButtonDisabled={ + areCheckedUsersEmpty || checkedUsers.withEmail.length > LICENSE_LIMIT + } /> - {/* */} + /> LICENSE_LIMIT + } /> )} @@ -146,6 +152,7 @@ export default inject(({ importAccountsStore }) => { areCheckedUsersEmpty, setResultUsers, cancelMigration, + checkedUsers, } = importAccountsStore; return { @@ -155,5 +162,6 @@ export default inject(({ importAccountsStore }) => { areCheckedUsersEmpty, setResultUsers, cancelMigration, + checkedUsers, }; })(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js index 8805976643..f8c64403d9 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js @@ -36,10 +36,10 @@ import { Text } from "@docspace/shared/components/text"; import { Wrapper } from "../StyledStepper"; -// import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; +import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; import { NoEmailUsersBlock } from "../../../sub-components/NoEmailUsersBlock"; -// const LICENSE_LIMIT = 100; +const LICENSE_LIMIT = 3; const AddEmailsStep = (props) => { const { @@ -51,6 +51,7 @@ const AddEmailsStep = (props) => { setSearchValue, setResultUsers, areCheckedUsersEmpty, + checkedUsers, } = props; const [dataPortion, setDataPortion] = useState( @@ -80,6 +81,9 @@ const AddEmailsStep = (props) => { incrementStep(); }; + const numberOfSelectedUsers = + checkedUsers.withEmail.length + checkedUsers.withoutEmail.length; + return ( {users.withoutEmail.length > 0 && ( @@ -100,15 +104,17 @@ const AddEmailsStep = (props) => { cancelButtonLabel={t("Common:Back")} showReminder displaySettings - saveButtonDisabled={areCheckedUsersEmpty} + saveButtonDisabled={ + areCheckedUsersEmpty || numberOfSelectedUsers > LICENSE_LIMIT + } /> - {/* */} + /> { cancelButtonLabel={t("Common:Back")} showReminder displaySettings - saveButtonDisabled={areCheckedUsersEmpty} + saveButtonDisabled={ + areCheckedUsersEmpty || numberOfSelectedUsers > LICENSE_LIMIT + } /> ); @@ -157,6 +165,7 @@ export default inject(({ setup, importAccountsStore }) => { users, setResultUsers, areCheckedUsersEmpty, + checkedUsers, } = importAccountsStore; return { @@ -166,5 +175,6 @@ export default inject(({ setup, importAccountsStore }) => { users, setResultUsers, areCheckedUsersEmpty, + checkedUsers, }; })(observer(AddEmailsStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js index 75e33cda38..66a7cfdc03 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js @@ -34,10 +34,10 @@ import { Text } from "@docspace/shared/components/text"; import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../../sub-components/AccountsPaging"; -// import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; +import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; import { Wrapper } from "../StyledStepper"; -// const LICENSE_LIMIT = 100; +const LICENSE_LIMIT = 3; const SelectUsersStep = (props) => { const { @@ -48,6 +48,7 @@ const SelectUsersStep = (props) => { searchValue, setSearchValue, cancelMigration, + checkedUsers, } = props; const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); @@ -94,12 +95,14 @@ const SelectUsersStep = (props) => { displaySettings /> - {/* */} + /> { searchValue, setSearchValue, cancelMigration, + checkedUsers, } = importAccountsStore; return { @@ -156,5 +160,6 @@ export default inject(({ importAccountsStore }) => { searchValue, setSearchValue, cancelMigration, + checkedUsers, }; })(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js index 3aec45a68c..9c1fb9a0e2 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js @@ -32,9 +32,9 @@ import { SearchInput } from "@docspace/shared/components/search-input"; import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../../sub-components/AccountsPaging"; -// import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; +import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; -// const LICENSE_LIMIT = 100; +const LICENSE_LIMIT = 10; const SelectUsersStep = ({ t, @@ -46,6 +46,7 @@ const SelectUsersStep = ({ searchValue, setSearchValue, cancelMigration, + checkedUsers, }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); @@ -92,15 +93,17 @@ const SelectUsersStep = ({ saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings - saveButtonDisabled={areCheckedUsersEmpty} + saveButtonDisabled={ + areCheckedUsersEmpty || checkedUsers.withEmail.length > LICENSE_LIMIT + } /> - {/* */} + /> LICENSE_LIMIT + } /> )} @@ -146,6 +152,7 @@ export default inject(({ importAccountsStore }) => { setResultUsers, areCheckedUsersEmpty, cancelMigration, + checkedUsers, } = importAccountsStore; return { @@ -155,5 +162,6 @@ export default inject(({ importAccountsStore }) => { searchValue, setSearchValue, cancelMigration, + checkedUsers, }; })(observer(SelectUsersStep)); From 27679f7b5e5ec718708130de010064254d0b303f Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 14:27:02 +0300 Subject: [PATCH 026/126] Shared:Selector: refactoring types --- .../components/selector/Selector.styled.ts | 5 +- .../components/selector/Selector.types.ts | 342 +++++++----------- .../selector/sub-components/Body.tsx | 29 +- .../selector/sub-components/BreadCrumbs.tsx | 19 +- .../selector/sub-components/Item.tsx | 12 +- .../selector/sub-components/SelectAll.tsx | 67 ++-- packages/shared/selectors/Groups/index.tsx | 1 - packages/shared/types/index.ts | 2 + 8 files changed, 212 insertions(+), 265 deletions(-) diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index e7841acabe..477725c895 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -327,7 +327,10 @@ const StyledBreadCrumbs = styled.div<{ StyledBreadCrumbs.defaultProps = { theme: Base }; -const StyledItemText = styled(Text)<{ isCurrent: boolean; isLoading: boolean }>` +const StyledItemText = styled(Text)<{ + isCurrent: boolean; + isLoading?: boolean; +}>` ${(props) => !props.isCurrent && css` diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index 7f7b4f7a56..e3d14e78c9 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -26,10 +26,14 @@ import React from "react"; import { RoomsType, ShareAccessRights } from "../../enums"; -import { AvatarRole } from "../avatar"; +import { MergeTypes } from "../../types"; + import { TFileSecurity, TFolderSecurity } from "../../api/files/types"; import { TRoomSecurity } from "../../api/rooms/types"; + +import { AvatarRole } from "../avatar"; import { TSubmenuItem } from "../submenu"; + import { SelectorAccessRightsMode } from "./Selector.enums"; // header @@ -56,12 +60,12 @@ export type TSelectorHeader = | { withHeader?: undefined; headerProps?: undefined }; // bread crumbs - export type TBreadCrumb = { id: string | number; label: string; isRoom?: boolean; minWidth?: string; + roomType?: RoomsType; onClick?: ({ e, open, @@ -71,49 +75,41 @@ export type TBreadCrumb = { open: boolean; item: TBreadCrumb; }) => void; - roomType?: RoomsType; }; -export interface BreadCrumbsProps { - breadCrumbs: TBreadCrumb[]; - onSelectBreadCrumb: (item: TBreadCrumb) => void; - isLoading: boolean; -} +export type TDisplayedItem = { + id: string | number; + label: string; + isArrow: boolean; + isList: boolean; + isRoom?: boolean; + listItems?: TBreadCrumb[]; +}; export type TSelectorBreadCrumbs = | { withBreadCrumbs: true; - breadCrumbs: TBreadCrumb[]; - onSelectBreadCrumb: (item: TBreadCrumb) => void; - breadCrumbsLoader: React.ReactNode; isBreadCrumbsLoading: boolean; + breadCrumbs: TBreadCrumb[]; + breadCrumbsLoader: React.ReactNode; + + onSelectBreadCrumb: (item: TBreadCrumb) => void; } | { withBreadCrumbs?: undefined; - breadCrumbs?: undefined; - onSelectBreadCrumb?: undefined; - breadCrumbsLoader?: undefined; isBreadCrumbsLoading?: undefined; + breadCrumbs?: undefined; + breadCrumbsLoader?: undefined; + + onSelectBreadCrumb?: undefined; }; // tabs - export type TWithTabs = | { withTabs: true; tabsData: TSubmenuItem[]; activeTabId: string } | { withTabs?: undefined; tabsData?: undefined; activeTabId?: undefined }; // select all - -export interface SelectAllProps { - label: string; - icon: string; - onSelectAll: () => void; - isChecked: boolean; - isIndeterminate: boolean; - isLoading: boolean; - rowLoader: React.ReactNode; -} - export type TSelectorSelectAll = { isAllIndeterminate?: boolean; isAllChecked?: boolean; @@ -389,178 +385,127 @@ export type FooterProps = TSelectorFooterSubmitButton & requestRunning?: boolean; }; -type TSelectorItemLogo = - | { - avatar: string; - color?: undefined; - hasAvatar?: boolean; - icon?: undefined; - iconOriginal?: string; - role?: AvatarRole; - } - | { - avatar?: undefined; - color: string; - hasAvatar?: undefined; - icon?: undefined; - iconOriginal?: string; - role?: undefined; - } - | { - avatar?: undefined; - color?: undefined; - hasAvatar?: undefined; - icon: string; - iconOriginal: string; - role?: undefined; - }; +type TSelectorItemEmpty = { + avatar?: undefined; + color?: undefined; + hasAvatar?: undefined; + icon?: undefined; + iconOriginal?: undefined; + role?: undefined; + email?: undefined; + isOwner?: undefined; + isAdmin?: undefined; + isVisitor?: undefined; + isCollaborator?: undefined; + isRoomAdmin?: undefined; + access?: undefined; + fileExst?: undefined; + shared?: undefined; + parentId?: undefined; + rootFolderType?: undefined; + security?: undefined; + isFolder?: undefined; + filesCount?: undefined; + foldersCount?: undefined; + roomType?: undefined; + isGroup?: undefined; + name?: undefined; + isCreateNewItem?: undefined; + onCreateClick?: undefined; +}; + +export type TSelectorItemUser = MergeTypes< + TSelectorItemEmpty, + { + email: string; + isOwner: boolean; + isAdmin: boolean; + isVisitor: boolean; + isCollaborator: boolean; + isRoomAdmin: boolean; + avatar: string; + hasAvatar: boolean; + role: AvatarRole; + + access?: ShareAccessRights | string | number; + } +>; + +export type TSelectorItemFile = MergeTypes< + TSelectorItemEmpty, + { + fileExst: string; + parentId: string | number; + rootFolderType: string | number; + security: TFileSecurity; + icon: string; + } +>; + +export type TSelectorItemFolder = MergeTypes< + TSelectorItemEmpty, + { + isFolder: boolean; + parentId: string | number; + rootFolderType: string | number; + filesCount: number; + foldersCount: number; + security: TFolderSecurity; + icon: string; + } +>; + +export type TSelectorItemRoom = MergeTypes< + TSelectorItemEmpty, + { + isFolder: boolean; + roomType: RoomsType; + shared: boolean; + parentId: string | number; + rootFolderType: string | number; + filesCount: number; + foldersCount: number; + security: TRoomSecurity; + icon?: string; + color?: string; + iconOriginal?: string; + } +>; + +export type TSelectorItemGroup = MergeTypes< + TSelectorItemEmpty, + { + isGroup: boolean; + name: string; + } +>; + +export type TSelectorItemNew = MergeTypes< + TSelectorItemEmpty, + { + isCreateNewItem: boolean; + onCreateClick: VoidFunction; + } +>; type TSelectorItemType = - | { - email: string; - fileExst?: undefined; - roomType?: undefined; - shared?: undefined; - isOwner: boolean; - isAdmin: boolean; - isVisitor: boolean; - isCollaborator: boolean; - isRoomAdmin: boolean; - access?: ShareAccessRights | string | number; - isFolder?: undefined; - parentId?: undefined; - rootFolderType?: undefined; - filesCount?: undefined; - foldersCount?: undefined; - security?: undefined; - isGroup?: undefined; - name?: undefined; - isCreateNewItem?: undefined; - onCreateClick?: undefined; - } - | { - email?: undefined; - fileExst: string; - roomType?: undefined; - shared?: boolean; - isOwner?: undefined; - isAdmin?: undefined; - isVisitor?: undefined; - isCollaborator?: undefined; - isRoomAdmin?: undefined; - access?: undefined; - isFolder?: undefined; - parentId?: string | number; - rootFolderType?: string | number; - filesCount?: undefined; - foldersCount?: undefined; - security?: TFileSecurity; - isGroup?: undefined; - name?: undefined; - isCreateNewItem?: undefined; - onCreateClick?: undefined; - } - | { - email?: undefined; - fileExst?: undefined; - roomType: RoomsType; - shared?: boolean; - isOwner?: undefined; - isAdmin?: undefined; - isVisitor?: undefined; - isCollaborator?: undefined; - isRoomAdmin?: undefined; - access?: undefined; - isFolder: boolean; - parentId?: string | number; - rootFolderType?: string | number; - filesCount?: number; - foldersCount?: number; - security?: TRoomSecurity; - isGroup?: undefined; - name?: undefined; - isCreateNewItem?: undefined; - onCreateClick?: undefined; - } - | { - email?: undefined; - fileExst?: undefined; - roomType?: undefined; - shared?: boolean; - isOwner?: undefined; - isAdmin?: undefined; - isVisitor?: undefined; - isCollaborator?: undefined; - isRoomAdmin?: undefined; - access?: undefined; - isFolder: boolean; - parentId?: string | number; - rootFolderType?: string | number; - filesCount?: number; - foldersCount?: number; - security?: TFolderSecurity; - isGroup?: undefined; - name?: undefined; - isCreateNewItem?: undefined; - onCreateClick?: undefined; - } - | { - email?: undefined; - fileExst?: undefined; - roomType?: undefined; - shared?: boolean; - isOwner?: undefined; - isAdmin?: undefined; - isVisitor?: undefined; - isCollaborator?: undefined; - isRoomAdmin?: undefined; - access?: undefined; - isFolder?: undefined; - parentId?: string | number; - rootFolderType?: string | number; - filesCount?: number; - foldersCount?: number; - security?: TFolderSecurity; - isGroup: true; - name: string; - isCreateNewItem?: undefined; - onCreateClick?: undefined; - } - | { - email?: undefined; - fileExst?: undefined; - roomType?: undefined; - shared?: undefined; - isOwner?: undefined; - isAdmin?: undefined; - isVisitor?: undefined; - isCollaborator?: undefined; - isRoomAdmin?: undefined; - access?: undefined; - isFolder?: undefined; - parentId?: undefined; - rootFolderType?: undefined; - filesCount?: undefined; - foldersCount?: undefined; - security?: undefined; - isGroup?: undefined; - name?: undefined; - isCreateNewItem: boolean; - onCreateClick: VoidFunction; - }; + | TSelectorItemUser + | TSelectorItemFile + | TSelectorItemFolder + | TSelectorItemRoom + | TSelectorItemGroup + | TSelectorItemNew; -export type TSelectorItem = TSelectorItemLogo & - TSelectorItemType & { - key?: string; - id?: string | number; - label: string; - displayName?: string; +export type TSelectorItem = TSelectorItemType & { + label: string; - isSelected?: boolean; - - isDisabled?: boolean; - disabledText?: string; - }; + key?: string; + id?: string | number; + displayName?: string; + isSelected?: boolean; + isDisabled?: boolean; + disabledText?: string; +}; export type Data = { items: TSelectorItem[]; @@ -581,12 +526,3 @@ export interface ItemProps { style: React.CSSProperties; data: Data; } - -export type TDisplayedItem = { - id: string | number; - label: string; - isArrow: boolean; - isList: boolean; - isRoom?: boolean; - listItems?: TBreadCrumb[]; -}; diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index 7ebbb2e13f..413fd60c45 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -184,9 +184,11 @@ const Body = ({ breadCrumbsLoader ) : ( ) ) : null} @@ -232,17 +234,20 @@ const Body = ({ {!!descriptionText && ( {descriptionText} )} - {isMultiSelect && withSelectAll && !isSearch && ( - - )} + {isMultiSelect && withSelectAll && !isSearch ? ( + isLoading ? ( + rowLoader + ) : ( + + ) + ) : null} {bodyHeight && ( { +}: TSelectorBreadCrumbs) => { const [displayedItems, setDisplayedItems] = React.useState( [], ); const onClickItem = React.useCallback( ({ item }: { item: TBreadCrumb }) => { - if (isLoading) return; + if (isBreadCrumbsLoading) return; - onSelectBreadCrumb(item); + onSelectBreadCrumb?.(item); }, - [isLoading, onSelectBreadCrumb], + [isBreadCrumbsLoading, onSelectBreadCrumb], ); const calculateDisplayedItems = React.useCallback( @@ -214,11 +214,12 @@ const BreadCrumbs = ({ noSelect truncate isCurrent={index === displayedItems.length - 1} - isLoading={isLoading || false} + isLoading={isBreadCrumbsLoading} onClick={() => { - if (index === displayedItems.length - 1 || isLoading) return; + if (index === displayedItems.length - 1 || isBreadCrumbsLoading) + return; - onSelectBreadCrumb({ + onSelectBreadCrumb?.({ id: item.id, label: item.label, isRoom: item.isRoom, diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index 49352bbbcc..251ba24f3a 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -82,6 +82,8 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { const { label, + isCreateNewItem, + onCreateClick, avatar, icon, role, @@ -91,14 +93,13 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { email, isGroup, disabledText, - isCreateNewItem, - onCreateClick, } = item; - if (isCreateNewItem) + if (isCreateNewItem) { return ( ); + } const showPlanetIcon = (item.roomType === RoomsType.PublicRoom || @@ -109,7 +110,10 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { const currentRole = role || AvatarRole.user; - const typeLabel = getUserTypeLabel(role, t); + const typeLabel = getUserTypeLabel( + role as "owner" | "admin" | "user" | "collaborator" | "manager", + t, + ); const onChangeAction = () => { onSelect?.(item, false); diff --git a/packages/shared/components/selector/sub-components/SelectAll.tsx b/packages/shared/components/selector/sub-components/SelectAll.tsx index 4d11bf4625..aec954ff31 100644 --- a/packages/shared/components/selector/sub-components/SelectAll.tsx +++ b/packages/shared/components/selector/sub-components/SelectAll.tsx @@ -31,18 +31,22 @@ import { Text } from "../../text"; import { Checkbox } from "../../checkbox"; import { StyledSelectAll } from "../Selector.styled"; -import { SelectAllProps } from "../Selector.types"; +import { TSelectorSelectAll } from "../Selector.types"; const SelectAll = React.memo( ({ - label, - icon, + withSelectAll, + + selectAllLabel, + selectAllIcon, + + isAllChecked, + isAllIndeterminate, + onSelectAll, - isChecked, - isIndeterminate, - isLoading, - rowLoader, - }: SelectAllProps) => { + }: TSelectorSelectAll) => { + if (!withSelectAll) return; + const onClick = (e: React.MouseEvent) => { if (e.target instanceof HTMLElement && e.target.closest(".checkbox")) return; @@ -52,35 +56,28 @@ const SelectAll = React.memo( return ( - {isLoading ? ( - rowLoader - ) : ( - <> - + - - {label} - + + {selectAllLabel} + - - - )} + ); }, diff --git a/packages/shared/selectors/Groups/index.tsx b/packages/shared/selectors/Groups/index.tsx index 8e29ec8bac..d0795434e9 100644 --- a/packages/shared/selectors/Groups/index.tsx +++ b/packages/shared/selectors/Groups/index.tsx @@ -121,7 +121,6 @@ const GroupsSelector = (props: GroupsSelectorProps) => { label: group.name, name: group.name, isGroup: true, - avatar: "", })); if (isFirstLoad.current) { diff --git a/packages/shared/types/index.ts b/packages/shared/types/index.ts index c83f5d33bc..37f4831c10 100644 --- a/packages/shared/types/index.ts +++ b/packages/shared/types/index.ts @@ -55,6 +55,8 @@ export type NonFunctionProperties = Pick< NonFunctionPropertyNames >; +export type MergeTypes = Omit & MergedType; + export type TPathParts = { id: number; title: string; From 2a04f2caf20df058b95890ea257b37719d7d8f2a Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 14:44:43 +0300 Subject: [PATCH 027/126] Shared: fix ts and eslint problems --- .../article-item/ArticleItem.types.ts | 2 +- .../campaigns-banner/CampaignsBanner.test.tsx | 1 + .../components/docspace-logo/DocspaceLogo.tsx | 2 +- .../components/email-input/EmailInput.tsx | 2 +- .../shared/components/filter/Filter.styled.ts | 1 - .../components/input-block/InputBlock.tsx | 1 - .../DesktopDetails/DesktopDetails.type.ts | 2 +- .../section/sub-components/InfoPanel.tsx | 3 +-- .../components/selector/Selector.stories.tsx | 24 +++++-------------- .../components/selector/Selector.types.ts | 3 ++- .../share/sub-components/LinkRow.tsx | 4 ++-- .../social-button/SocialButton.types.ts | 3 +++ .../components/textarea/Textarea.styled.tsx | 2 ++ 13 files changed, 21 insertions(+), 29 deletions(-) diff --git a/packages/shared/components/article-item/ArticleItem.types.ts b/packages/shared/components/article-item/ArticleItem.types.ts index 20ec210f17..77f0b848e2 100644 --- a/packages/shared/components/article-item/ArticleItem.types.ts +++ b/packages/shared/components/article-item/ArticleItem.types.ts @@ -40,7 +40,7 @@ export interface ArticleItemProps { /** Sets the catalog item to display text */ showText?: boolean; /** Invokes a function upon clicking on a catalog item */ - onClick?: (id?: string) => void; + onClick?: (e: React.MouseEvent, id?: string) => void; /** Invokes a function upon dragging and dropping a catalog item */ onDrop?: (id?: string, text?: string) => void; /** Tells when the catalog item should display initial on icon, text should be hidden */ diff --git a/packages/shared/components/campaigns-banner/CampaignsBanner.test.tsx b/packages/shared/components/campaigns-banner/CampaignsBanner.test.tsx index 59cb0ef958..8ecacd0870 100644 --- a/packages/shared/components/campaigns-banner/CampaignsBanner.test.tsx +++ b/packages/shared/components/campaigns-banner/CampaignsBanner.test.tsx @@ -37,6 +37,7 @@ describe("", () => { render( null} diff --git a/packages/shared/components/docspace-logo/DocspaceLogo.tsx b/packages/shared/components/docspace-logo/DocspaceLogo.tsx index f95acf4449..522d56a4c1 100644 --- a/packages/shared/components/docspace-logo/DocspaceLogo.tsx +++ b/packages/shared/components/docspace-logo/DocspaceLogo.tsx @@ -63,7 +63,7 @@ const DocspaceLogo = ({ const logo = getLogoUrl(logoSize, !theme.isBase); return ( - + {logo && ( { const items: TSelectorItem[] = []; - console.log("call"); - items.push({ key: "create_new", id: "create_new_item", @@ -110,21 +109,10 @@ const getItems = (count: number) => { isAdmin: false, isVisitor: false, isCollaborator: false, + isRoomAdmin: false, avatar: "", - }); - } - - for (let i = 0; i < count / 2; i += 1) { - const label = makeName(); - - items.push({ - key: `room_${i}`, - id: `room_${i}`, - label: `${label} ${i}`, - icon: CustomSvgUrl, - shared: false, - isFolder: true, - roomType: RoomsType.CustomRoom, + role: AvatarRole.owner, + hasAvatar: false, }); } diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index e3d14e78c9..1a782e613b 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -451,7 +451,8 @@ export type TSelectorItemFolder = MergeTypes< filesCount: number; foldersCount: number; security: TFolderSecurity; - icon: string; + icon?: string; + avatar?: string; } >; diff --git a/packages/shared/components/share/sub-components/LinkRow.tsx b/packages/shared/components/share/sub-components/LinkRow.tsx index 46931f87c5..6b36ac4b63 100644 --- a/packages/shared/components/share/sub-components/LinkRow.tsx +++ b/packages/shared/components/share/sub-components/LinkRow.tsx @@ -40,13 +40,13 @@ import { ComboBox, ComboBoxSize, TOption } from "../../combobox"; import { IconButton } from "../../icon-button"; import { toastr } from "../../toast"; import { Loader, LoaderTypes } from "../../loader"; +import { Text } from "../../text"; import { StyledLinkRow, StyledSquare } from "../Share.styled"; import { getShareOptions, getAccessOptions } from "../Share.helpers"; import { LinkRowProps } from "../Share.types"; import ExpiredComboBox from "./ExpiredComboBox"; -import { Text } from "@docspace/shared/components/text"; const LinkRow = ({ onAddClick, @@ -149,7 +149,7 @@ const LinkRow = ({ scaledOptions={false} showDisabledItems size={ComboBoxSize.content} - fillIcon={true} + fillIcon modernView type="onlyIcon" isDisabled={isExpiredLink || isLoaded} diff --git a/packages/shared/components/social-button/SocialButton.types.ts b/packages/shared/components/social-button/SocialButton.types.ts index 43ed035e89..49748c75c3 100644 --- a/packages/shared/components/social-button/SocialButton.types.ts +++ b/packages/shared/components/social-button/SocialButton.types.ts @@ -58,5 +58,8 @@ export interface SocialButtonProps extends Partial { /** Button icon */ iconName?: string; + "data-url"?: string; + "data-providername"?: string; + IconComponent?: JSX.ElementType; } diff --git a/packages/shared/components/textarea/Textarea.styled.tsx b/packages/shared/components/textarea/Textarea.styled.tsx index 2e8896eaff..b20c0b858b 100644 --- a/packages/shared/components/textarea/Textarea.styled.tsx +++ b/packages/shared/components/textarea/Textarea.styled.tsx @@ -50,6 +50,8 @@ const ClearScrollbar = ({ hasError?: boolean; heightTextAreaProp?: string; ref?: React.Ref; + isFullHeight?: boolean; + fullHeight?: number; // @ts-expect-error error from custom scrollbar } & ScrollbarProps) => ; From 7c1e90d2e08254840e031591658edd237630713a Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 14:51:06 +0300 Subject: [PATCH 028/126] Shared:Selector: fix stories --- packages/shared/components/selector/Selector.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/components/selector/Selector.stories.tsx b/packages/shared/components/selector/Selector.stories.tsx index f78cedc972..a78de45e9b 100644 --- a/packages/shared/components/selector/Selector.stories.tsx +++ b/packages/shared/components/selector/Selector.stories.tsx @@ -98,7 +98,7 @@ const getItems = (count: number) => { onCreateClick: () => {}, }); - for (let i = 0; i < count / 2; i += 1) { + for (let i = 0; i < count; i += 1) { const label = makeName(); items.push({ key: `${label} ${i}`, From ed41266757af6637c77fe3add6febf34c266af8b Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 16:33:31 +0300 Subject: [PATCH 029/126] Shared:Selectors: refactoring --- packages/shared/selectors/People/index.tsx | 4 +-- .../selectors/Room/RoomSelector.types.ts | 2 +- .../selectors/Room/RoomSelector.utils.ts | 32 +++++++++++++++++-- packages/shared/selectors/Room/index.tsx | 4 +-- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/packages/shared/selectors/People/index.tsx b/packages/shared/selectors/People/index.tsx index be6b82f925..5dd7eda4f5 100644 --- a/packages/shared/selectors/People/index.tsx +++ b/packages/shared/selectors/People/index.tsx @@ -86,7 +86,7 @@ const toListItem = ( ? t("Common:Disabled") : ""; - const i = { + const i: TSelectorItem = { id: userId, email, avatar: userAvatar, @@ -100,7 +100,7 @@ const toListItem = ( hasAvatar, isDisabled: isInvited || isDisabled, disabledText, - } as TSelectorItem; + }; return i; }; diff --git a/packages/shared/selectors/Room/RoomSelector.types.ts b/packages/shared/selectors/Room/RoomSelector.types.ts index f37de4d20c..bfa38caf8f 100644 --- a/packages/shared/selectors/Room/RoomSelector.types.ts +++ b/packages/shared/selectors/Room/RoomSelector.types.ts @@ -42,7 +42,7 @@ export type RoomSelectorProps = TSelectorHeader & onSubmit: (items: TSelectorItem[]) => void | Promise; roomType?: RoomsType; - excludeItems?: number[]; + excludeItems?: (number | string | undefined)[]; setIsDataReady?: (value: boolean) => void; submitButtonLabel?: string; withSearch?: boolean; diff --git a/packages/shared/selectors/Room/RoomSelector.utils.ts b/packages/shared/selectors/Room/RoomSelector.utils.ts index 2e039dbd86..8cf861784a 100644 --- a/packages/shared/selectors/Room/RoomSelector.utils.ts +++ b/packages/shared/selectors/Room/RoomSelector.utils.ts @@ -25,16 +25,42 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import { TRoom } from "../../api/rooms/types"; +import { TSelectorItem } from "../../components/selector"; export const convertToItems = (folders: TRoom[]) => { - const items = folders.map((folder) => { - const { id, title, roomType, logo, shared } = folder; + const items: TSelectorItem[] = folders.map((folder) => { + const { + id, + title, + roomType, + logo, + shared, + parentId, + filesCount, + foldersCount, + rootFolderType, + security, + } = folder; const icon = logo.medium; const iconOriginal = logo.original; const color = logo.color; - return { id, label: title, icon, iconOriginal, color, roomType, shared }; + return { + id, + label: title, + icon, + iconOriginal, + color, + roomType, + shared, + isFolder: true, + parentId, + filesCount, + foldersCount, + rootFolderType, + security, + }; }); return items; diff --git a/packages/shared/selectors/Room/index.tsx b/packages/shared/selectors/Room/index.tsx index 7b4f95cd97..aa73fc615c 100644 --- a/packages/shared/selectors/Room/index.tsx +++ b/packages/shared/selectors/Room/index.tsx @@ -159,10 +159,10 @@ const RoomSelector = ({ if (isFirstLoad) { setTotal(totalCount); - setItems([...rooms] as TSelectorItem[]); + setItems([...rooms]); } else { setItems((prevItems) => { - const newItems = [...rooms] as TSelectorItem[]; + const newItems = [...rooms]; return [...prevItems, ...newItems]; }); From e77b80f2275a19d7ac78506bb7313ef62ba631be Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 17:03:58 +0300 Subject: [PATCH 030/126] Add images for selector input item --- public/images/selector.input.accept.svg | 3 +++ public/images/selector.input.cancel.svg | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 public/images/selector.input.accept.svg create mode 100644 public/images/selector.input.cancel.svg diff --git a/public/images/selector.input.accept.svg b/public/images/selector.input.accept.svg new file mode 100644 index 0000000000..3d5add8ba3 --- /dev/null +++ b/public/images/selector.input.accept.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/selector.input.cancel.svg b/public/images/selector.input.cancel.svg new file mode 100644 index 0000000000..1c0db52fe6 --- /dev/null +++ b/public/images/selector.input.cancel.svg @@ -0,0 +1,10 @@ + + + + + + + + + + From 73fd154d6d674c5c877cdfe5168eac18f59cec96 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 17:04:16 +0300 Subject: [PATCH 031/126] Shared:Storybook: add current color scheme --- packages/shared/.storybook/globals/theme-wrapper.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/shared/.storybook/globals/theme-wrapper.js b/packages/shared/.storybook/globals/theme-wrapper.js index 168b4e00d4..099b86f2a1 100644 --- a/packages/shared/.storybook/globals/theme-wrapper.js +++ b/packages/shared/.storybook/globals/theme-wrapper.js @@ -2,7 +2,16 @@ import PropTypes from "prop-types"; import { ThemeProvider } from "../../components/theme-provider"; const ThemeWrapper = ({ theme, children }) => { - return {children}; + return ( + + {children} + + ); }; ThemeWrapper.propTypes = { From 679fbbdc26a2fb9319e27c9fdde13b504de1b9e9 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 17:04:37 +0300 Subject: [PATCH 032/126] Shared:Components:SelectorAddButton: add action state --- .../SelectorAddButton.styled.ts | 52 ++++++++++++++++++- .../selector-add-button/SelectorAddButton.tsx | 2 + .../SelectorAddButton.types.tsx | 2 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/packages/shared/components/selector-add-button/SelectorAddButton.styled.ts b/packages/shared/components/selector-add-button/SelectorAddButton.styled.ts index f1da13cbad..d7d445c549 100644 --- a/packages/shared/components/selector-add-button/SelectorAddButton.styled.ts +++ b/packages/shared/components/selector-add-button/SelectorAddButton.styled.ts @@ -27,7 +27,7 @@ import styled, { css } from "styled-components"; import { Base } from "../../themes"; -const StyledButton = styled.div<{ isDisabled?: boolean }>` +const StyledButton = styled.div<{ isDisabled?: boolean; isAction?: boolean }>` display: inline-block; background: ${(props) => props.theme.selectorAddButton.background}; border: ${(props) => props.theme.selectorAddButton.border}; @@ -79,6 +79,56 @@ const StyledButton = styled.div<{ isDisabled?: boolean }>` } -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + + ${(props) => + props.isAction && + css` + // convert into 0.1 opacity + background-color: ${props.theme.currentColorScheme?.main.accent}1A; + + svg { + path { + ${!props.isDisabled && + css` + fill: ${props.theme.currentColorScheme?.main.accent}; + `} + } + } + + :hover { + background-color: ${props.theme.currentColorScheme?.main.accent}1A; + + svg { + path { + ${!props.isDisabled && + css` + fill: ${props.theme.currentColorScheme?.main.accent}; + opacity: 0.85; + `} + } + } + } + + :active { + background-color: ${props.theme.currentColorScheme?.main.accent}1A; + svg { + path { + ${!props.isDisabled && + css` + fill: ${props.theme.currentColorScheme?.main.accent}; + opacity: 1; + filter: ${props.theme.isBase + ? "brightness(90%)" + : "brightness(82%)"}; + `} + } + } + } + + div { + opacity: 1; + } + `} `; StyledButton.defaultProps = { theme: Base }; diff --git a/packages/shared/components/selector-add-button/SelectorAddButton.tsx b/packages/shared/components/selector-add-button/SelectorAddButton.tsx index 1914c20938..a6a90c4370 100644 --- a/packages/shared/components/selector-add-button/SelectorAddButton.tsx +++ b/packages/shared/components/selector-add-button/SelectorAddButton.tsx @@ -36,6 +36,7 @@ import { SelectorAddButtonProps } from "./SelectorAddButton.types"; const SelectorAddButton = (props: SelectorAddButtonProps) => { const { isDisabled = false, + isAction, title, className, id, @@ -52,6 +53,7 @@ const SelectorAddButton = (props: SelectorAddButtonProps) => { Date: Wed, 22 May 2024 17:04:56 +0300 Subject: [PATCH 033/126] Shared:Components:Selector: add NewItem and InputItem --- .../components/selector/Selector.stories.tsx | 10 +++ .../components/selector/Selector.styled.ts | 32 +++++++ .../components/selector/Selector.types.ts | 17 +++- .../selector/sub-components/InputItem.tsx | 86 +++++++++++++++++++ .../selector/sub-components/Item.tsx | 16 ++++ .../selector/sub-components/NewItem.tsx | 2 +- packages/shared/themes/base.ts | 3 + packages/shared/themes/dark.ts | 3 + 8 files changed, 167 insertions(+), 2 deletions(-) diff --git a/packages/shared/components/selector/Selector.stories.tsx b/packages/shared/components/selector/Selector.stories.tsx index a78de45e9b..c1c8906d19 100644 --- a/packages/shared/components/selector/Selector.stories.tsx +++ b/packages/shared/components/selector/Selector.stories.tsx @@ -98,6 +98,16 @@ const getItems = (count: number) => { onCreateClick: () => {}, }); + items.push({ + key: "input_item", + id: "input_item", + label: "", + isInputItem: true, + defaultInputValue: "New folder", + onAcceptInput: () => {}, + onCancelInput: () => {}, + }); + for (let i = 0; i < count; i += 1) { const label = makeName(); items.push({ diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index 477725c895..296696217c 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -445,6 +445,36 @@ const StyledInfo = styled.div` } `; +const StyledInputWrapper = styled.div` + width: 32px; + height: 32px; + + margin-inline-start: 8px; + + border: 1px solid ${(props) => props.theme.selector.item.inputButtonBorder}; + border-radius: 3px; + + display: flex; + align-items: center; + justify-content: center; + + box-sizing: border-box; + + :hover { + div { + cursor: pointer; + } + cursor: pointer; + + border-color: ${(props) => + props.theme.selector.item.inputButtonBorderHover}; + + path { + fill: ${(props) => props.theme.selector.item.inputButtonBorderHover}; + } + } +`; + StyledSelector.defaultProps = { theme: Base }; StyledHeader.defaultProps = { theme: Base }; StyledBody.defaultProps = { theme: Base }; @@ -454,6 +484,7 @@ StyledEmptyScreen.defaultProps = { theme: Base }; StyledArrowRightSvg.defaultProps = { theme: Base }; StyledComboBox.defaultProps = { theme: Base }; StyledInfo.defaultProps = { theme: Base }; +StyledInputWrapper.defaultProps = { theme: Base }; export { StyledSelector, @@ -473,4 +504,5 @@ export { StyledTabs, StyledInfo, StyledAccessSelector, + StyledInputWrapper, }; diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index 1a782e613b..074eb7950e 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -412,6 +412,10 @@ type TSelectorItemEmpty = { name?: undefined; isCreateNewItem?: undefined; onCreateClick?: undefined; + isInputItem?: undefined; + defaultInputValue?: undefined; + onAcceptInput?: undefined; + onCancelInput?: undefined; }; export type TSelectorItemUser = MergeTypes< @@ -489,13 +493,24 @@ export type TSelectorItemNew = MergeTypes< } >; +export type TSelectorItemInput = MergeTypes< + TSelectorItemEmpty, + { + isInputItem: boolean; + defaultInputValue: string; + onAcceptInput: (value: string) => void; + onCancelInput: VoidFunction; + } +>; + type TSelectorItemType = | TSelectorItemUser | TSelectorItemFile | TSelectorItemFolder | TSelectorItemRoom | TSelectorItemGroup - | TSelectorItemNew; + | TSelectorItemNew + | TSelectorItemInput; export type TSelectorItem = TSelectorItemType & { label: string; diff --git a/packages/shared/components/selector/sub-components/InputItem.tsx b/packages/shared/components/selector/sub-components/InputItem.tsx index e69de29bb2..90d5cb8bb9 100644 --- a/packages/shared/components/selector/sub-components/InputItem.tsx +++ b/packages/shared/components/selector/sub-components/InputItem.tsx @@ -0,0 +1,86 @@ +// (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 React from "react"; + +import AcceptIconSvgUrl from "PUBLIC_DIR/images/selector.input.accept.svg?url"; +import CancelIconSvgUrl from "PUBLIC_DIR/images/selector.input.cancel.svg?url"; + +import { InputSize, InputType, TextInput } from "../../text-input"; +import { IconButton } from "../../icon-button"; + +import { StyledInputWrapper, StyledItem } from "../Selector.styled"; + +const InputItem = ({ + defaultInputValue, + onAcceptInput, + onCancelInput, + style, +}: { + defaultInputValue: string; + onAcceptInput: (value: string) => void; + onCancelInput: VoidFunction; + style: React.CSSProperties; +}) => { + const [value, setValue] = React.useState(""); + + const onAcceptInputAction = () => { + onAcceptInput(value); + }; + + const onChange = (e: React.ChangeEvent) => { + const newVal = e.target.value; + + setValue(newVal); + }; + + return ( + + + + + + + + + + ); +}; + +export default InputItem; diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index 251ba24f3a..6d4075168e 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -37,6 +37,7 @@ import { StyledItem } from "../Selector.styled"; import { ItemProps, Data, TSelectorItem } from "../Selector.types"; import { RoomsType } from "../../../enums"; import NewItem from "./NewItem"; +import InputItem from "./InputItem"; const compareFunction = (prevProps: ItemProps, nextProps: ItemProps) => { const prevData = prevProps.data; @@ -84,6 +85,10 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { label, isCreateNewItem, onCreateClick, + isInputItem, + defaultInputValue, + onAcceptInput, + onCancelInput, avatar, icon, role, @@ -95,6 +100,17 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { disabledText, } = item; + if (isInputItem) { + return ( + + ); + } + if (isCreateNewItem) { return ( diff --git a/packages/shared/components/selector/sub-components/NewItem.tsx b/packages/shared/components/selector/sub-components/NewItem.tsx index dd6a68626c..e396cf56c2 100644 --- a/packages/shared/components/selector/sub-components/NewItem.tsx +++ b/packages/shared/components/selector/sub-components/NewItem.tsx @@ -48,7 +48,7 @@ const NewItem = ({ isMultiSelect={false} noHover > - + { item: { hoverBackground: grayLight, selectedBackground: lightHover, + + inputButtonBorder: "#D0D5DA", + inputButtonBorderHover: grayMain, }, emptyScreen: { diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index 363891c81f..f5b0f55f32 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -2370,6 +2370,9 @@ const Dark: TTheme = { item: { hoverBackground: "#3d3d3d", selectedBackground: "#3d3d3d", + + inputButtonBorder: "#474747", + inputButtonBorderHover: grayMaxLight, }, emptyScreen: { From 1cc2500a63e4e011e4c43fb0b6f70308fe6421ae Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 22 May 2024 18:09:57 +0300 Subject: [PATCH 034/126] Shared:Components:Selector: add icon for input item --- .../components/selector/Selector.stories.tsx | 2 ++ .../components/selector/Selector.styled.ts | 4 +++ .../components/selector/Selector.types.ts | 3 ++ .../selector/sub-components/InputItem.tsx | 35 +++++++++++++++++-- .../selector/sub-components/Item.tsx | 2 ++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/shared/components/selector/Selector.stories.tsx b/packages/shared/components/selector/Selector.stories.tsx index c1c8906d19..9b1c183eab 100644 --- a/packages/shared/components/selector/Selector.stories.tsx +++ b/packages/shared/components/selector/Selector.stories.tsx @@ -29,6 +29,7 @@ import styled from "styled-components"; import { Meta, StoryObj } from "@storybook/react"; import ArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url"; +import FolderSvgUrl from "PUBLIC_DIR/images/icons/32/folder.svg?url"; import EmptyScreenFilter from "PUBLIC_DIR/images/empty_screen_filter.png"; import { AvatarRole } from "../avatar"; @@ -103,6 +104,7 @@ const getItems = (count: number) => { id: "input_item", label: "", isInputItem: true, + icon: FolderSvgUrl, defaultInputValue: "New folder", onAcceptInput: () => {}, onCancelInput: () => {}, diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index 296696217c..17458f8d43 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -222,6 +222,10 @@ const StyledItem = styled.div<{ `} } + .input-component { + margin-inline-start: 8px; + } + .checkbox { svg { margin-inline-end: 0px; diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index 074eb7950e..db2c29f286 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -498,6 +498,9 @@ export type TSelectorItemInput = MergeTypes< { isInputItem: boolean; defaultInputValue: string; + icon?: string; + color?: string; + onAcceptInput: (value: string) => void; onCancelInput: VoidFunction; } diff --git a/packages/shared/components/selector/sub-components/InputItem.tsx b/packages/shared/components/selector/sub-components/InputItem.tsx index 90d5cb8bb9..db4a8661ef 100644 --- a/packages/shared/components/selector/sub-components/InputItem.tsx +++ b/packages/shared/components/selector/sub-components/InputItem.tsx @@ -31,6 +31,7 @@ import CancelIconSvgUrl from "PUBLIC_DIR/images/selector.input.cancel.svg?url"; import { InputSize, InputType, TextInput } from "../../text-input"; import { IconButton } from "../../icon-button"; +import { RoomIcon } from "../../room-icon"; import { StyledInputWrapper, StyledItem } from "../Selector.styled"; @@ -39,13 +40,20 @@ const InputItem = ({ onAcceptInput, onCancelInput, style, + + color, + icon, }: { defaultInputValue: string; onAcceptInput: (value: string) => void; onCancelInput: VoidFunction; style: React.CSSProperties; + + color?: string; + icon?: string; }) => { - const [value, setValue] = React.useState(""); + const [value, setValue] = React.useState(defaultInputValue); + const inputRef = React.useRef(null); const onAcceptInputAction = () => { onAcceptInput(value); @@ -57,6 +65,13 @@ const InputItem = ({ setValue(newVal); }; + React.useEffect(() => { + if (inputRef.current) { + inputRef.current.focus(); + inputRef.current.select(); + } + }, []); + return ( + {color ? ( + + ) : icon ? ( + + ) : null} diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index 6d4075168e..08dc90cfb5 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -107,6 +107,8 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { onAcceptInput={onAcceptInput} onCancelInput={onCancelInput} style={style} + color={color} + icon={icon} /> ); } From e5a3b7ac103f7c83a765403631577782799dd673 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 09:05:08 +0300 Subject: [PATCH 035/126] Login: Added language combobox. --- packages/login/src/app/(root)/page.tsx | 25 +++++++++++------ packages/login/src/components/Login/index.tsx | 28 +++++++++++++++++-- .../login/src/components/LoginForm/index.tsx | 24 ++++++++-------- packages/login/src/types/index.ts | 2 ++ packages/login/src/utils/actions.ts | 17 +++++++++++ packages/shared/api/settings/types.ts | 2 ++ 6 files changed, 76 insertions(+), 22 deletions(-) diff --git a/packages/login/src/app/(root)/page.tsx b/packages/login/src/app/(root)/page.tsx index 9797dde823..ff70f6bda0 100644 --- a/packages/login/src/app/(root)/page.tsx +++ b/packages/login/src/app/(root)/page.tsx @@ -43,6 +43,7 @@ import { getSSO, checkIsAuthenticated, getColorTheme, + getPortalCultures, } from "@/utils/actions"; async function Page({ @@ -54,14 +55,21 @@ async function Page({ const startOtherOperationsDate = new Date(); - const [settings, thirdParty, capabilities, ssoSettings, colorTheme] = - await Promise.all([ - getSettings(), - getThirdPartyProviders(), - getCapabilities(), - getSSO(), - getColorTheme(), - ]); + const [ + settings, + thirdParty, + capabilities, + ssoSettings, + colorTheme, + cultures, + ] = await Promise.all([ + getSettings(), + getThirdPartyProviders(), + getCapabilities(), + getSSO(), + getColorTheme(), + getPortalCultures(), + ]); timers.otherOperations = new Date().getTime() - startOtherOperationsDate.getTime(); @@ -110,6 +118,7 @@ async function Page({ isAuthenticated={false} systemTheme={systemTheme?.value as ThemeKeys} timers={timers} + cultures={cultures} /> ); diff --git a/packages/login/src/components/Login/index.tsx b/packages/login/src/components/Login/index.tsx index 4be3cc7dfe..1ea79241c8 100644 --- a/packages/login/src/components/Login/index.tsx +++ b/packages/login/src/components/Login/index.tsx @@ -31,12 +31,17 @@ import { useTranslation } from "react-i18next"; import { useTheme } from "styled-components"; import { ThemeKeys, WhiteLabelLogoType } from "@docspace/shared/enums"; -import { PROVIDERS_DATA } from "@docspace/shared/constants"; +import { + COOKIE_EXPIRATION_YEAR, + LANGUAGE, + PROVIDERS_DATA, +} from "@docspace/shared/constants"; import { getBgPattern, getLoginLink, getLogoUrl, getOAuthToken, + setLanguageWithoutReload, } from "@docspace/shared/utils/common"; import RecoverAccessModalDialog from "@docspace/shared/components/recover-access-modal-dialog/RecoverAccessModalDialog"; import { Scrollbar } from "@docspace/shared/components/scrollbar"; @@ -45,6 +50,7 @@ import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import { Link, LinkType } from "@docspace/shared/components/link"; import { SocialButtonsGroup } from "@docspace/shared/components/social-buttons-group"; import { Text } from "@docspace/shared/components/text"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; import SSOIcon from "PUBLIC_DIR/images/sso.react.svg?url"; @@ -56,6 +62,7 @@ import Register from "../Register"; import LoginForm from "../LoginForm"; import { LoginContent, LoginFormWrapper } from "./Login.styled"; +import { setCookie } from "@docspace/shared/utils/cookie"; const Login = ({ searchParams, @@ -65,6 +72,7 @@ const Login = ({ isAuthenticated, timers, systemTheme, + cultures, }: LoginProps) => { const [isLoading, setIsLoading] = useState(false); @@ -78,7 +86,8 @@ const Login = ({ console.log("api res", settings, capabilities, thirdPartyProvider); - const { t } = useTranslation(["Login", "Common"]); + const { t, i18n } = useTranslation(["Login", "Common"]); + const currentCulture = i18n.language; const { recoverDialogVisible, @@ -118,6 +127,12 @@ const Login = ({ } }, [searchParams]); + const onLanguageSelect = (culture: { key: string }) => { + const { key } = culture; + + setLanguageWithoutReload(key, i18n); + }; + const ssoExists = () => { if (capabilities?.ssoUrl) return true; else return false; @@ -204,6 +219,14 @@ const Login = ({ return ( <> + + {(oauthDataExists() || ssoExists()) && ( <> diff --git a/packages/login/src/components/LoginForm/index.tsx b/packages/login/src/components/LoginForm/index.tsx index 8f574c0eeb..01b2ccc3bb 100644 --- a/packages/login/src/components/LoginForm/index.tsx +++ b/packages/login/src/components/LoginForm/index.tsx @@ -88,7 +88,7 @@ const LoginForm = ({ const inputRef = useRef(null); const captchaRef = useRef(null); - const { t, ready, i18n } = useTranslation(["Login", "Common"]); + const { t, ready } = useTranslation(["Login", "Common"]); const theme = useTheme(); const { message, confirmedEmail, authError } = match || { @@ -98,8 +98,8 @@ const LoginForm = ({ }; const authCallback = useCallback( async (profile: string) => { - localStorage.removeItem("profile"); - localStorage.removeItem("code"); + localStorage.removeItem("profile"); + localStorage.removeItem("code"); try { const response = (await thirdPartyLogin(profile, currentCulture)) as { @@ -370,15 +370,15 @@ const LoginForm = ({ onChange={onChangeCheckbox} label={t("Common:Remember")} helpButton={ - {t("RememberHelper")} - } - tooltipMaxWidth={isMobileOnly ? "240px" : "340px"} - /> + {t("RememberHelper")} + } + tooltipMaxWidth={isMobileOnly ? "240px" : "340px"} + /> } /> )} diff --git a/packages/login/src/types/index.ts b/packages/login/src/types/index.ts index 225709492d..36e2d1dba4 100644 --- a/packages/login/src/types/index.ts +++ b/packages/login/src/types/index.ts @@ -58,6 +58,7 @@ export type LoginProps = { thirdPartyProvider?: TThirdPartyProvider[]; ssoSettings?: TGetSsoSettings; systemTheme?: ThemeKeys; + cultures: string[]; }; export type RegisterProps = { @@ -96,6 +97,7 @@ export type LoginFormProps = { recaptchaPublicKey?: string; emailFromInvitation?: string; cookieSettingsEnabled: boolean; + currentCulture: string; }; export type ForgotPasswordModalDialogProps = { diff --git a/packages/login/src/utils/actions.ts b/packages/login/src/utils/actions.ts index 4edc5c616b..1abfba48c1 100644 --- a/packages/login/src/utils/actions.ts +++ b/packages/login/src/utils/actions.ts @@ -34,6 +34,7 @@ import { TCapabilities, TGetColorTheme, TGetSsoSettings, + TPortalCultures, TSettings, TThirdPartyProvider, TVersionBuild, @@ -176,3 +177,19 @@ export const updateCookie = (name: string, value: string, options: object) => { cookieStore.set(name, value, options); }; + +export async function getPortalCultures() { + const [getPortalCultures] = createRequest( + [`/settings/cultures`], + [["", ""]], + "GET", + ); + + const res = await fetch(getPortalCultures); + + if (!res.ok) return; + + const cultures = await res.json(); + + return cultures.response as TPortalCultures; +} diff --git a/packages/shared/api/settings/types.ts b/packages/shared/api/settings/types.ts index ddc65ff68d..a7d9adf61a 100644 --- a/packages/shared/api/settings/types.ts +++ b/packages/shared/api/settings/types.ts @@ -239,3 +239,5 @@ export type TPaymentSettings = { }; max: number; }; + +export type TPortalCultures = string[]; From 011b4e8a1b853c82edb4bc893d2d6c04eb1eee6f Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 09:06:13 +0300 Subject: [PATCH 036/126] Shared/Client: Added common function. --- .../NavMenu/sub-components/header-unauth.js | 17 ++--------- .../Confirm/sub-components/createUser.js | 16 ++--------- packages/shared/utils/common.ts | 28 +++++++++++++++++-- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 61c69e37f6..c79303cad7 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -36,6 +36,7 @@ import { LanguageCombobox } from "@docspace/shared/components/language-combobox" import { setCookie } from "@docspace/shared/utils/cookie"; import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; import i18n from "../../../i18n"; +import { setLanguageWithoutReload } from "@docspace/shared/utils/common"; const Header = styled.header` align-items: left; @@ -100,21 +101,7 @@ const HeaderUnAuth = ({ const onSelect = (culture) => { const { key } = culture; - - i18n.changeLanguage(key); - - setCookie(LANGUAGE, key, { - "max-age": COOKIE_EXPIRATION_YEAR, - }); - - const url = new URL(window.location.href); - const prevCulture = url.searchParams.get("culture"); - - if (prevCulture) { - const newUrl = location.href.replace(`&culture=${prevCulture}`, ``); - - window.history.pushState("", "", newUrl); - } + setLanguageWithoutReload(key, i18n); }; return ( diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 036797949a..c81e1375d4 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -49,6 +49,7 @@ import { createPasswordHash, getOAuthToken, getLoginLink, + setLanguageWithoutReload, } from "@docspace/shared/utils/common"; import { login } from "@docspace/shared/utils/loginUtils"; import { @@ -480,20 +481,7 @@ const CreateUserForm = (props) => { const onSelect = (culture) => { const { key } = culture; - i18n.changeLanguage(key); - - setCookie(LANGUAGE, key, { - "max-age": COOKIE_EXPIRATION_YEAR, - }); - - const url = new URL(window.location.href); - const prevCulture = url.searchParams.get("culture"); - - if (prevCulture) { - const newUrl = location.href.replace(`&culture=${prevCulture}`, ``); - - window.history.pushState("", "", newUrl); - } + setLanguageWithoutReload(key, i18n); }; return ( diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 945560e3fe..249392b93b 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -62,7 +62,12 @@ import { ErrorKeys, WhiteLabelLogoType, } from "../enums"; -import { LANGUAGE, PUBLIC_MEDIA_VIEW_URL, RTL_LANGUAGES } from "../constants"; +import { + COOKIE_EXPIRATION_YEAR, + LANGUAGE, + PUBLIC_MEDIA_VIEW_URL, + RTL_LANGUAGES, +} from "../constants"; import { TI18n, TTranslation } from "../types"; import { TUser } from "../api/people/types"; @@ -73,7 +78,7 @@ import TopLoaderService from "../components/top-loading-indicator"; import { Encoder } from "./encoder"; import { combineUrl } from "./combineUrl"; -import { getCookie } from "./cookie"; +import { getCookie, setCookie } from "./cookie"; import { checkIsSSR } from "./device"; export const desktopConstants = Object.freeze({ @@ -83,6 +88,7 @@ export const desktopConstants = Object.freeze({ }); let timer: null | ReturnType = null; +type I18n = I18nextProviderProps["i18n"]; export function changeLanguage(i18n: TI18n, currentLng = getCookie(LANGUAGE)) { return currentLng @@ -1042,7 +1048,6 @@ export const insertDataLayer = (id: string) => { window.dataLayer.push({ user_id: id }); }; -type I18n = I18nextProviderProps["i18n"]; export const mapCulturesToArray = ( culturesArg: string[], isBetaBadge: boolean = true, @@ -1077,3 +1082,20 @@ export function getLogoUrl( ) { return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`; } + +export function setLanguageWithoutReload(culture: string, i18n: I18n) { + i18n.changeLanguage(culture); + + setCookie(LANGUAGE, culture, { + "max-age": COOKIE_EXPIRATION_YEAR, + }); + + const url = new URL(window.location.href); + const prevCulture = url.searchParams.get("culture"); + + if (prevCulture) { + const newUrl = window.location.href.replace(`&culture=${prevCulture}`, ``); + + window.history.pushState("", "", newUrl); + } +} From 7b9834f769fe972dc5cac9c3cb742f9967e104c2 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 11:34:24 +0300 Subject: [PATCH 037/126] Login: Added wrapper to eliminate re-rendering of children. --- .../login/src/providers/ErrorBoundary.tsx | 37 +++++++++++++++++++ .../src/providers/ErrorBoundary.types.ts | 36 ++++++++++++++++++ packages/login/src/providers/index.tsx | 10 ++--- 3 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 packages/login/src/providers/ErrorBoundary.tsx create mode 100644 packages/login/src/providers/ErrorBoundary.types.ts diff --git a/packages/login/src/providers/ErrorBoundary.tsx b/packages/login/src/providers/ErrorBoundary.tsx new file mode 100644 index 0000000000..fc33baf38e --- /dev/null +++ b/packages/login/src/providers/ErrorBoundary.tsx @@ -0,0 +1,37 @@ +// (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 useDeviceType from "@/hooks/useDeviceType"; +import ErrorBoundary from "@docspace/shared/components/error-boundary/ErrorBoundary"; +import { ErrorBoundaryProps } from "./ErrorBoundary.types"; + +const ErrorBoundaryWrapper = (props: ErrorBoundaryProps) => { + const { currentDeviceType } = useDeviceType(); + + return ; +}; + +export default ErrorBoundaryWrapper; diff --git a/packages/login/src/providers/ErrorBoundary.types.ts b/packages/login/src/providers/ErrorBoundary.types.ts new file mode 100644 index 0000000000..f9ef68e650 --- /dev/null +++ b/packages/login/src/providers/ErrorBoundary.types.ts @@ -0,0 +1,36 @@ +// (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 type { PropsWithChildren } from "react"; + +import type { TUser } from "@docspace/shared/api/people/types"; +import type FirebaseHelper from "@docspace/shared/utils/firebase"; + +export interface ErrorBoundaryProps extends PropsWithChildren { + user: TUser; + version: string; + firebaseHelper: FirebaseHelper; +} diff --git a/packages/login/src/providers/index.tsx b/packages/login/src/providers/index.tsx index 65c0738fc3..695cc24bec 100644 --- a/packages/login/src/providers/index.tsx +++ b/packages/login/src/providers/index.tsx @@ -30,7 +30,6 @@ import React from "react"; import { I18nextProvider } from "react-i18next"; import { ThemeProvider } from "@docspace/shared/components/theme-provider"; -import ErrorBoundary from "@docspace/shared/components/error-boundary/ErrorBoundary"; import { TFirebaseSettings } from "@docspace/shared/api/settings/types"; import FirebaseHelper from "@docspace/shared/utils/firebase"; import { TUser } from "@docspace/shared/api/people/types"; @@ -40,9 +39,9 @@ import { Base, Dark } from "@docspace/shared/themes"; import { TDataContext } from "@/types"; import useI18N from "@/hooks/useI18N"; import useTheme from "@/hooks/useTheme"; -import useDeviceType from "@/hooks/useDeviceType"; import pkgFile from "../../package.json"; +import ErrorBoundaryWrapper from "./ErrorBoundary"; export const Providers = ({ children, @@ -68,8 +67,6 @@ export const Providers = ({ if (redirectURL) window.location.replace("/"); }, [redirectURL]); - const { currentDeviceType } = useDeviceType(); - const { i18n } = useI18N({ settings: value.settings, }); @@ -89,14 +86,13 @@ export const Providers = ({ return ( - {children} - + ); From 3b59d01a80648375ecb3791f89ef0beba8339d14 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 11:46:01 +0300 Subject: [PATCH 038/126] Shared: Components: LanguageCombobox: New prop added. --- .../language-combobox/LanguageCombobox.tsx | 12 +++++------- .../language-combobox/LanguageCombobox.types.ts | 1 + packages/shared/utils/common.ts | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index 41d7a1f548..8812904afc 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -28,7 +28,6 @@ import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { mapCulturesToArray } from "../../utils/common"; -import { isMobile } from "../../utils"; import { StyledComboBox } from "./LanguageCombobox.styled"; import { TCulture, ComboboxProps } from "./LanguageCombobox.types"; @@ -39,16 +38,15 @@ const LanguageCombobox = (props: ComboboxProps) => { selectedCulture, className, withBorder = true, + isMobileView = false, } = props; const { i18n } = useTranslation(["Common"]); + const withLabel = isMobileView ? i18n : undefined; const cultureNames = useMemo(() => { - const withLabel = isMobile() ? i18n : undefined; - return mapCulturesToArray(cultures, false, withLabel); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [cultures]); + }, [cultures, withLabel]); const currentCulture = cultureNames.find( (item) => item.key === selectedCulture, @@ -82,8 +80,8 @@ const LanguageCombobox = (props: ComboboxProps) => { type="onlyIcon" optionStyle={{ padding: "0 8px" }} style={{ padding: "6px 0px" }} - isMobileView={isMobile()} - withBlur={isMobile()} + isMobileView={isMobileView} + withBlur={isMobileView} withBorder={withBorder} /> ); diff --git a/packages/shared/components/language-combobox/LanguageCombobox.types.ts b/packages/shared/components/language-combobox/LanguageCombobox.types.ts index a1844b8dcb..53b66579d3 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.types.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.types.ts @@ -42,4 +42,5 @@ export interface ComboboxProps { className?: string; /** Indicates that component contain border */ withBorder?: boolean; + isMobileView?: boolean; } diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 249392b93b..0277f7766e 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -1083,7 +1083,7 @@ export function getLogoUrl( return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`; } -export function setLanguageWithoutReload(culture: string, i18n: I18n) { +export function setLanguageWithoutReload(culture: string, i18n: TI18n) { i18n.changeLanguage(culture); setCookie(LANGUAGE, culture, { From 2e565d076a16fc69c26b8b006f3a763a74a73f0d Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 11:47:37 +0300 Subject: [PATCH 039/126] Login: Added change to combobox in mobile view. --- .../src/components/Login/LanguageCombobox.tsx | 62 +++++++++++++++++++ packages/login/src/components/Login/index.tsx | 19 ++---- 2 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 packages/login/src/components/Login/LanguageCombobox.tsx diff --git a/packages/login/src/components/Login/LanguageCombobox.tsx b/packages/login/src/components/Login/LanguageCombobox.tsx new file mode 100644 index 0000000000..2ed0fda3ca --- /dev/null +++ b/packages/login/src/components/Login/LanguageCombobox.tsx @@ -0,0 +1,62 @@ +// (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 { setLanguageWithoutReload } from "@docspace/shared/utils/common"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; +import useDeviceType from "@/hooks/useDeviceType"; +import { DeviceType } from "@docspace/shared/enums"; +import { TI18n } from "@docspace/shared/types"; + +export interface TLanguageCombobox { + currentCulture: string; + cultures: string[]; + i18n: TI18n; +} + +const LanguageComboboxWrapper = (props: TLanguageCombobox) => { + const { currentCulture, cultures, i18n } = props; + + const onLanguageSelect = (culture: { key: string }) => { + const { key } = culture; + + setLanguageWithoutReload(key, i18n); + }; + + const { currentDeviceType } = useDeviceType(); + const isMobileView = currentDeviceType === DeviceType.mobile; + + return ( + + ); +}; +export default LanguageComboboxWrapper; diff --git a/packages/login/src/components/Login/index.tsx b/packages/login/src/components/Login/index.tsx index 1ea79241c8..92d90b371b 100644 --- a/packages/login/src/components/Login/index.tsx +++ b/packages/login/src/components/Login/index.tsx @@ -41,7 +41,6 @@ import { getLoginLink, getLogoUrl, getOAuthToken, - setLanguageWithoutReload, } from "@docspace/shared/utils/common"; import RecoverAccessModalDialog from "@docspace/shared/components/recover-access-modal-dialog/RecoverAccessModalDialog"; import { Scrollbar } from "@docspace/shared/components/scrollbar"; @@ -50,7 +49,6 @@ import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import { Link, LinkType } from "@docspace/shared/components/link"; import { SocialButtonsGroup } from "@docspace/shared/components/social-buttons-group"; import { Text } from "@docspace/shared/components/text"; -import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; import SSOIcon from "PUBLIC_DIR/images/sso.react.svg?url"; @@ -62,7 +60,8 @@ import Register from "../Register"; import LoginForm from "../LoginForm"; import { LoginContent, LoginFormWrapper } from "./Login.styled"; -import { setCookie } from "@docspace/shared/utils/cookie"; + +import LanguageCombobox from "./LanguageCombobox"; const Login = ({ searchParams, @@ -127,12 +126,6 @@ const Login = ({ } }, [searchParams]); - const onLanguageSelect = (culture: { key: string }) => { - const { key } = culture; - - setLanguageWithoutReload(key, i18n); - }; - const ssoExists = () => { if (capabilities?.ssoUrl) return true; else return false; @@ -220,13 +213,11 @@ const Login = ({ <> - + Date: Thu, 23 May 2024 13:07:34 +0300 Subject: [PATCH 040/126] Login: Fixed styles. --- packages/login/src/components/Login/Login.styled.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/login/src/components/Login/Login.styled.ts b/packages/login/src/components/Login/Login.styled.ts index 8249f1b56b..5bdecc6def 100644 --- a/packages/login/src/components/Login/Login.styled.ts +++ b/packages/login/src/components/Login/Login.styled.ts @@ -97,7 +97,6 @@ export const LoginFormWrapper = styled.div<{ bgPattern: string }>` margin-bottom: 16px; .back-title { position: absolute; - max-width: 60px; text-overflow: ellipsis; overflow: hidden; From 3c11ddfb3baed6dd318c582e776828c9a6e917d2 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 13:08:35 +0300 Subject: [PATCH 041/126] Web: Renamed function. --- .../NavMenu/sub-components/header-unauth.js | 5 +++-- .../Confirm/sub-components/StyledConfirm.js | 4 ++++ .../Confirm/sub-components/createUser.js | 19 ++++++++----------- .../src/components/Login/LanguageCombobox.tsx | 4 ++-- packages/shared/utils/common.ts | 6 +++--- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index c79303cad7..9623331733 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -36,7 +36,7 @@ import { LanguageCombobox } from "@docspace/shared/components/language-combobox" import { setCookie } from "@docspace/shared/utils/cookie"; import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; import i18n from "../../../i18n"; -import { setLanguageWithoutReload } from "@docspace/shared/utils/common"; +import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; const Header = styled.header` align-items: left; @@ -101,7 +101,7 @@ const HeaderUnAuth = ({ const onSelect = (culture) => { const { key } = culture; - setLanguageWithoutReload(key, i18n); + setLanguageForUnauthorized(key, i18n); }; return ( @@ -129,6 +129,7 @@ const HeaderUnAuth = ({ cultures={cultures} selectedCulture={currentCultureName} withBorder={false} + isMobileView /> ); diff --git a/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js b/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js index ce54cba268..fbce0280b8 100644 --- a/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js +++ b/packages/client/src/pages/Confirm/sub-components/StyledConfirm.js @@ -47,6 +47,10 @@ export const StyledPage = styled.div` width: 100%; padding: ${({ theme }) => getCorrectFourValuesStyle("32px 8px 0 16px", theme.interfaceDirection)}; + + .language-combo-box { + display: none; + } } .subtitle { diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index c81e1375d4..836a634161 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -49,7 +49,7 @@ import { createPasswordHash, getOAuthToken, getLoginLink, - setLanguageWithoutReload, + setLanguageForUnauthorized, } from "@docspace/shared/utils/common"; import { login } from "@docspace/shared/utils/loginUtils"; import { @@ -72,7 +72,6 @@ import { import GreetingUserContainer from "./GreetingUserContainer"; import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; import { isMobile } from "@docspace/shared/utils"; -import { ComboBox } from "@docspace/shared/components/combobox"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; import { setCookie } from "@docspace/shared/utils/cookie"; @@ -481,20 +480,18 @@ const CreateUserForm = (props) => { const onSelect = (culture) => { const { key } = culture; - setLanguageWithoutReload(key, i18n); + setLanguageForUnauthorized(key, i18n); }; return ( - {!isMobile() && ( - - )} + onSelectLanguage={onSelect} + cultures={cultures} + selectedCulture={currentCultureName} + withBorder={false} + /> diff --git a/packages/login/src/components/Login/LanguageCombobox.tsx b/packages/login/src/components/Login/LanguageCombobox.tsx index 2ed0fda3ca..6d14ada772 100644 --- a/packages/login/src/components/Login/LanguageCombobox.tsx +++ b/packages/login/src/components/Login/LanguageCombobox.tsx @@ -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 { setLanguageWithoutReload } from "@docspace/shared/utils/common"; +import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; import useDeviceType from "@/hooks/useDeviceType"; import { DeviceType } from "@docspace/shared/enums"; @@ -42,7 +42,7 @@ const LanguageComboboxWrapper = (props: TLanguageCombobox) => { const onLanguageSelect = (culture: { key: string }) => { const { key } = culture; - setLanguageWithoutReload(key, i18n); + setLanguageForUnauthorized(key, i18n); }; const { currentDeviceType } = useDeviceType(); diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 0277f7766e..942d2d8406 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -1083,9 +1083,7 @@ export function getLogoUrl( return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`; } -export function setLanguageWithoutReload(culture: string, i18n: TI18n) { - i18n.changeLanguage(culture); - +export function setLanguageForUnauthorized(culture: string) { setCookie(LANGUAGE, culture, { "max-age": COOKIE_EXPIRATION_YEAR, }); @@ -1098,4 +1096,6 @@ export function setLanguageWithoutReload(culture: string, i18n: TI18n) { window.history.pushState("", "", newUrl); } + + window.location.reload(); } From c54a4eb8ed1ad97e4c17a5d7823635c48c966238 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 13:09:14 +0300 Subject: [PATCH 042/126] Login: Added getting language from cookies. --- packages/login/src/hooks/useI18N.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/login/src/hooks/useI18N.ts b/packages/login/src/hooks/useI18N.ts index 55c48657bd..bb9c0e888f 100644 --- a/packages/login/src/hooks/useI18N.ts +++ b/packages/login/src/hooks/useI18N.ts @@ -40,7 +40,8 @@ interface UseI18NProps { const useI18N = ({ settings }: UseI18NProps) => { const [i18n, setI18N] = React.useState( - getI18NInstance(settings?.culture ?? "en") ?? ({} as i18n), + getI18NInstance(getCookie(LANGUAGE) ?? settings?.culture ?? "en") ?? + ({} as i18n), ); const isInit = React.useRef(false); From dd40faeb7df09124d287b81e5aeaf0e0adeb89ad Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 13:18:52 +0300 Subject: [PATCH 043/126] Login: Refactoring. --- packages/login/src/components/Login/index.tsx | 6 +----- packages/login/src/components/LoginForm/index.tsx | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/login/src/components/Login/index.tsx b/packages/login/src/components/Login/index.tsx index 92d90b371b..a0fa685369 100644 --- a/packages/login/src/components/Login/index.tsx +++ b/packages/login/src/components/Login/index.tsx @@ -212,11 +212,7 @@ const Login = ({ return ( <> - + { From 1605862273845fc24497a8f1a198edbbc73b621c Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 13:35:07 +0300 Subject: [PATCH 044/126] Deleted useless code. --- .../Filter/LanguageFilter/index.js | 37 +++++++++++++------ packages/client/src/store/OformsStore.js | 4 -- .../src/components/Login/LanguageCombobox.tsx | 6 +-- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 83c0645142..a4804c7be0 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -60,7 +60,7 @@ const LanguageFilter = ({ categoryFilterLoaded, languageFilterLoaded, oformFilesLoaded, - oformsCurrentLocal, + oformsLocal, }) => { const convertedLocales = oformLocales.map((item) => convertToCulture(item)); @@ -88,19 +88,32 @@ const LanguageFilter = ({ cultures={convertedLocales} isAuthenticated onSelectLanguage={onFilterByLocale} - selectedCulture={convertToCulture(oformsCurrentLocal)} + selectedCulture={convertToCulture(oformsLocal)} id="comboBoxLanguage" /> ); }; -export default inject(({ oformsStore }) => ({ - oformLocales: oformsStore.oformLocales, - filterOformsByLocale: oformsStore.filterOformsByLocale, - filterOformsByLocaleIsLoading: oformsStore.filterOformsByLocaleIsLoading, - setLanguageFilterLoaded: oformsStore.setLanguageFilterLoaded, - categoryFilterLoaded: oformsStore.categoryFilterLoaded, - languageFilterLoaded: oformsStore.languageFilterLoaded, - oformFilesLoaded: oformsStore.oformFilesLoaded, - oformsCurrentLocal: oformsStore.oformsCurrentLocal, -}))(withTranslation(["Common"])(observer(LanguageFilter))); +export default inject(({ oformsStore }) => { + const { + oformLocales, + filterOformsByLocale, + filterOformsByLocaleIsLoading, + setLanguageFilterLoaded, + languageFilterLoaded, + oformFilesLoaded, + categoryFilterLoaded, + oformsFilter, + } = oformsStore; + + return { + oformLocales, + filterOformsByLocale, + filterOformsByLocaleIsLoading, + setLanguageFilterLoaded, + categoryFilterLoaded, + languageFilterLoaded, + oformFilesLoaded, + oformsLocal: oformsFilter.locale, + }; +})(withTranslation(["Common"])(observer(LanguageFilter))); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 7b6bf6256d..0f3748e064 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -377,10 +377,6 @@ class OformsStore { get hasMoreForms() { return this.oformFiles.length < this.oformsFilterTotal; } - - get oformsCurrentLocal() { - return this.oformsFilter.locale; - } } export default OformsStore; diff --git a/packages/login/src/components/Login/LanguageCombobox.tsx b/packages/login/src/components/Login/LanguageCombobox.tsx index 6d14ada772..bcc6a5f072 100644 --- a/packages/login/src/components/Login/LanguageCombobox.tsx +++ b/packages/login/src/components/Login/LanguageCombobox.tsx @@ -28,21 +28,19 @@ import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; import useDeviceType from "@/hooks/useDeviceType"; import { DeviceType } from "@docspace/shared/enums"; -import { TI18n } from "@docspace/shared/types"; export interface TLanguageCombobox { currentCulture: string; cultures: string[]; - i18n: TI18n; } const LanguageComboboxWrapper = (props: TLanguageCombobox) => { - const { currentCulture, cultures, i18n } = props; + const { currentCulture, cultures } = props; const onLanguageSelect = (culture: { key: string }) => { const { key } = culture; - setLanguageForUnauthorized(key, i18n); + setLanguageForUnauthorized(key); }; const { currentDeviceType } = useDeviceType(); From 594e3eba89e715ce726ed04b92a5e2f68ea09a39 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Thu, 23 May 2024 14:44:57 +0300 Subject: [PATCH 045/126] Shared:Selectors:Files: add create folder --- .../src/components/FilesSelector/index.tsx | 27 +++++-- packages/shared/api/files/index.ts | 5 +- .../selectors/Files/FilesSelector.types.ts | 4 + .../selectors/Files/hooks/useFilesHelper.ts | 81 ++++++++++++++++++- .../selectors/Files/hooks/useSocketHelper.ts | 26 +++++- packages/shared/selectors/Files/index.tsx | 3 + 6 files changed, 129 insertions(+), 17 deletions(-) diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 9e21878dd2..0ce43b4598 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -34,6 +34,7 @@ import FilesSelector from "@docspace/shared/selectors/Files"; import { toastr } from "@docspace/shared/components/toast"; import { SettingsStore } from "@docspace/shared/store/SettingsStore"; import { + TFile, TFileSecurity, TFolder, TFolderSecurity, @@ -41,7 +42,7 @@ import { import { TBreadCrumb } from "@docspace/shared/components/selector/Selector.types"; import { TData } from "@docspace/shared/components/toast/Toast.type"; import { TSelectedFileInfo } from "@docspace/shared/selectors/Files/FilesSelector.types"; -import { TRoomSecurity } from "@docspace/shared/api/rooms/types"; +import { TRoom, TRoomSecurity } from "@docspace/shared/api/rooms/types"; import { TTranslation } from "@docspace/shared/types"; import SelectedFolderStore from "SRC_DIR/store/SelectedFolderStore"; @@ -55,6 +56,8 @@ import InfoPanelStore from "SRC_DIR/store/InfoPanelStore"; import { FilesSelectorProps } from "./FilesSelector.types"; import { getAcceptButtonLabel, getHeaderLabel, getIsDisabled } from "./utils"; +const disabledItems: (string | number)[] = []; + const FilesSelectorWrapper = ({ isPanelVisible = false, // withoutImmediatelyClose = false, @@ -87,7 +90,7 @@ const FilesSelectorWrapper = ({ treeFolders, selection, - disabledItems, + // disabledItems, setConflictDialogData, checkFileConflicts, itemOperationToFolder, @@ -169,8 +172,10 @@ const FilesSelectorWrapper = ({ onCloseAction(); }; - const getFilesArchiveError = (name: string) => - t("Common:ArchivedRoomAction", { name }); + const getFilesArchiveError = React.useCallback( + (name: string) => t("Common:ArchivedRoomAction", { name }), + [t], + ); const onAccept = async ( selectedItemId: string | number | undefined, @@ -375,6 +380,9 @@ const FilesSelectorWrapper = ({ isMove || isCopy || isRestore ? "select-file-modal-cancel" : "" } getFilesArchiveError={getFilesArchiveError} + withCreateFolder={ + (isMove || isCopy || isRestore || isRestoreAll) ?? false + } /> ); }; @@ -471,10 +479,13 @@ export default inject( ? selections : selections.filter((f) => f && !f?.isEditing); - const disabledItems: (string | number)[] = []; - - selectionsWithoutEditing.forEach((item) => { - if ((item?.isFolder || item?.parentId) && item?.id) { + selectionsWithoutEditing.forEach((item: TFile | TFolder | TRoom) => { + if ( + (("isFolder" in item && item?.isFolder) || + ("parentId" in item && item?.parentId)) && + item?.id && + !disabledItems.includes(item.id) + ) { disabledItems.push(item.id); } }); diff --git a/packages/shared/api/files/index.ts b/packages/shared/api/files/index.ts index 1aa3136fd4..2addde50f4 100644 --- a/packages/shared/api/files/index.ts +++ b/packages/shared/api/files/index.ts @@ -337,7 +337,10 @@ export async function getTrashFolderList() { // return request(options); // } -export async function createFolder(parentFolderId: number, title: string) { +export async function createFolder( + parentFolderId: number | string, + title: string, +) { const data = { title }; const options: AxiosRequestConfig = { method: "post", diff --git a/packages/shared/selectors/Files/FilesSelector.types.ts b/packages/shared/selectors/Files/FilesSelector.types.ts index cf5165b351..671a362789 100644 --- a/packages/shared/selectors/Files/FilesSelector.types.ts +++ b/packages/shared/selectors/Files/FilesSelector.types.ts @@ -62,6 +62,7 @@ export type UseSocketHelperProps = { disabledItems: (string | number)[]; filterParam?: string; getIcon: (fileExst: string) => string; + withCreateFolder: boolean; }; export type UseRoomsHelperProps = { @@ -119,6 +120,7 @@ export type UseFilesHelpersProps = { getFilesArchiveError: (name: string) => string; isInit: boolean; setIsFirstLoad: (value: boolean) => void; + withCreateFolder: boolean; }; export type TSelectedFileInfo = { @@ -199,4 +201,6 @@ export type FilesSelectorProps = ( isPanelVisible: boolean; currentDeviceType: DeviceType; getFilesArchiveError: (name: string) => string; + + withCreateFolder: boolean; }; diff --git a/packages/shared/selectors/Files/hooks/useFilesHelper.ts b/packages/shared/selectors/Files/hooks/useFilesHelper.ts index 4b58368c66..1a71902e6b 100644 --- a/packages/shared/selectors/Files/hooks/useFilesHelper.ts +++ b/packages/shared/selectors/Files/hooks/useFilesHelper.ts @@ -25,8 +25,16 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import React from "react"; +import { useTranslation } from "react-i18next"; -import { getFolder, getFolderInfo, getSettingsFiles } from "../../../api/files"; +import FolderSvgUrl from "PUBLIC_DIR/images/icons/32/folder.svg?url"; + +import { + createFolder, + getFolder, + getFolderInfo, + getSettingsFiles, +} from "../../../api/files"; import FilesFilter from "../../../api/files/filter"; import { ApplyFilterOption, @@ -75,7 +83,10 @@ const useFilesHelper = ({ isInit, setIsInit, setIsFirstLoad, + withCreateFolder, }: UseFilesHelpersProps) => { + const { t } = useTranslation(["Common"]); + const requestRunning = React.useRef(false); const initRef = React.useRef(isInit); const firstLoadRef = React.useRef(isFirstLoad); @@ -93,6 +104,55 @@ const useFilesHelper = ({ initRef.current = isInit; }, [isInit]); + const onCancelInput = React.useCallback(() => { + if (!withCreateFolder) return; + + setItems((value) => { + if (!value[1].isInputItem) return value; + + const newValue = [...value]; + + newValue.splice(1, 1); + + return newValue; + }); + }, [setItems, withCreateFolder]); + + const onAcceptInput = React.useCallback( + async (value: string) => { + if (!withCreateFolder || !selectedItemId) return; + + await createFolder(selectedItemId, value); + + onCancelInput(); + }, + [onCancelInput, selectedItemId, withCreateFolder], + ); + + const addInputItem = React.useCallback(() => { + if (!withCreateFolder) return; + + const inputItem: TSelectorItem = { + label: "", + id: "new-folder-input", + isInputItem: true, + onAcceptInput, + onCancelInput, + defaultInputValue: t("NewFolder"), + icon: FolderSvgUrl, + }; + + setItems((value) => { + if (value[1].isInputItem) return value; + + const newValue = [...value]; + + newValue.splice(1, 0, inputItem); + + return newValue; + }); + }, [onAcceptInput, onCancelInput, setItems, t, withCreateFolder]); + const getFileList = React.useCallback( async (startIndex: number) => { if (requestRunning.current) return; @@ -310,7 +370,18 @@ const useFilesHelper = ({ } if (firstLoadRef.current || startIndex === 0) { - setTotal(total); + if (withCreateFolder) { + setTotal(total + 1); + itemList.unshift({ + isCreateNewItem: true, + label: "New folder", + id: "create-folder-item", + key: "create-folder-item", + onCreateClick: addInputItem, + }); + } else { + setTotal(total); + } setItems(itemList); } else { setItems((prevState) => { @@ -361,8 +432,8 @@ const useFilesHelper = ({ setIsNextPageLoading, searchValue, filterParam, - isUserOnly, selectedItemId, + isUserOnly, getRootData, setSelectedItemSecurity, getIcon, @@ -380,8 +451,10 @@ const useFilesHelper = ({ setIsBreadCrumbsLoading, roomsFolderId, setIsSelectedParentFolder, - setTotal, + withCreateFolder, setItems, + setTotal, + addInputItem, rootThirdPartyId, ], ); diff --git a/packages/shared/selectors/Files/hooks/useSocketHelper.ts b/packages/shared/selectors/Files/hooks/useSocketHelper.ts index 9439f064b0..e9784dc369 100644 --- a/packages/shared/selectors/Files/hooks/useSocketHelper.ts +++ b/packages/shared/selectors/Files/hooks/useSocketHelper.ts @@ -43,6 +43,7 @@ const useSocketHelper = ({ socketSubscribers, disabledItems, filterParam, + withCreateFolder, setItems, setBreadCrumbs, setTotal, @@ -109,9 +110,9 @@ const useSocketHelper = ({ if (opt?.type === "file" && "folderId" in data) { item = convertFilesToItems([data], getIcon, filterParam)[0]; - } else if (opt?.type === "folder" && "roomType" in data) { + } else if (opt?.type === "folder" && !("folderId" in data)) { item = - data.roomType && "tags" in data + "roomType" in data && data.roomType && "tags" in data ? convertRoomsToItems([data])[0] : convertFoldersToItems([data], disabledItems, filterParam)[0]; } @@ -122,6 +123,18 @@ const useSocketHelper = ({ if (opt.type === "folder") { setTotal((v) => v + 1); + if (withCreateFolder) { + const newValue = [...value]; + + let idx = 1; + + if (value[1].isInputItem) idx = 2; + + newValue.splice(idx, 0, item); + + return newValue; + } + return [item, ...value]; } @@ -129,7 +142,12 @@ const useSocketHelper = ({ let idx = 0; for (let i = 0; i < value.length - 1; i += 1) { - if (!value[i].isFolder) break; + if ( + !value[i].isFolder && + !value[i].isCreateNewItem && + !value[i].isInputItem + ) + break; idx = i + 1; } @@ -146,7 +164,7 @@ const useSocketHelper = ({ return value; }); }, - [disabledItems, filterParam, getIcon, setItems, setTotal], + [disabledItems, filterParam, getIcon, setItems, setTotal, withCreateFolder], ); const updateItem = React.useCallback( diff --git a/packages/shared/selectors/Files/index.tsx b/packages/shared/selectors/Files/index.tsx index 713334d467..ba93b305ef 100644 --- a/packages/shared/selectors/Files/index.tsx +++ b/packages/shared/selectors/Files/index.tsx @@ -107,6 +107,7 @@ const FilesSelector = ({ withBreadCrumbs: withBreadCrumbsProp, filesSettings, cancelButtonLabel, + withCreateFolder, }: FilesSelectorProps) => { const theme = useTheme(); const { t } = useTranslation(["Common"]); @@ -148,6 +149,7 @@ const FilesSelector = ({ socketSubscribers, disabledItems, filterParam, + withCreateFolder, getIcon, setItems, setBreadCrumbs, @@ -224,6 +226,7 @@ const FilesSelector = ({ getFilesArchiveError, isInit, setIsInit, + withCreateFolder, }); const onSelectAction = React.useCallback( From a18a99bf8159902eac918e631e7f0e412b0690c3 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 23 May 2024 15:05:07 +0300 Subject: [PATCH 046/126] Fixed after merge. --- packages/login/src/app/(root)/layout.tsx | 7 +++++-- .../index.tsx} | 15 +++++++++++---- packages/login/src/components/LoginForm/index.tsx | 15 +++++++-------- packages/login/src/hooks/useI18N.ts | 4 +++- packages/login/src/types/index.ts | 1 - packages/shared/api/settings/index.ts | 3 ++- 6 files changed, 28 insertions(+), 17 deletions(-) rename packages/login/src/components/{Login/LanguageCombobox.tsx => LanguageCombobox/index.tsx} (89%) diff --git a/packages/login/src/app/(root)/layout.tsx b/packages/login/src/app/(root)/layout.tsx index 34cc4cbb0f..4f9fb71f60 100644 --- a/packages/login/src/app/(root)/layout.tsx +++ b/packages/login/src/app/(root)/layout.tsx @@ -36,16 +36,18 @@ import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import SimpleNav from "@/components/SimpleNav"; import { LoginContent, LoginFormWrapper } from "@/components/Login"; import GreetingContainer from "@/components/GreetingContainer"; -import { getColorTheme, getSettings } from "@/utils/actions"; +import { getColorTheme, getPortalCultures, getSettings } from "@/utils/actions"; +import LanguageComboboxWrapper from "@/components/LanguageCombobox"; export default async function Layout({ children, }: { children: React.ReactNode; }) { - const [settings, colorTheme] = await Promise.all([ + const [settings, colorTheme, cultures] = await Promise.all([ getSettings(), getColorTheme(), + getPortalCultures(), ]); const cookieStore = cookies(); @@ -69,6 +71,7 @@ export default async function Layout({
+ { - const { currentCulture, cultures } = props; + const { cultures } = props; + const { i18n } = useTranslation(["Login", "Common"]); + + const currentCulture = i18n.language; const onLanguageSelect = (culture: { key: string }) => { const { key } = culture; diff --git a/packages/login/src/components/LoginForm/index.tsx b/packages/login/src/components/LoginForm/index.tsx index bab4f5dc9b..713c17b1b9 100644 --- a/packages/login/src/components/LoginForm/index.tsx +++ b/packages/login/src/components/LoginForm/index.tsx @@ -63,7 +63,6 @@ const LoginForm = ({ hashSettings, cookieSettingsEnabled, reCaptchaPublicKey, - currentCulture, }: LoginFormProps) => { const { isLoading, isModalOpen } = useContext(LoginValueContext); const { setIsLoading } = useContext(LoginDispatchContext); @@ -72,8 +71,9 @@ const LoginForm = ({ const theme = useTheme(); - const { t, ready } = useTranslation(["Login", "Common"]); - + const { t, ready, i18n } = useTranslation(["Login", "Common"]); + const currentCulture = i18n.language; + const message = searchParams.get("message"); const confirmedEmail = searchParams.get("confirmedEmail"); const authError = searchParams.get("authError"); @@ -176,8 +176,6 @@ const LoginForm = ({ if (confirmedEmail && ready) toastr.success(text); if (authError && ready) toastr.error(t("Common:ProviderLoginError")); - - }, [message, confirmedEmail, t, ready, authError, authCallback]); const onChangeLogin = (e: React.ChangeEvent) => { @@ -287,6 +285,7 @@ const LoginForm = ({ reCaptchaPublicKey, setIsLoading, referenceUrl, + currentCulture, ]); const onBlurEmail = () => { @@ -358,14 +357,14 @@ const LoginForm = ({ passwordErrorMessage={passwordErrorMessage} password={password} onChangePassword={onChangePassword} - /> + /> + /> {reCaptchaPublicKey && isCaptcha && ( diff --git a/packages/login/src/hooks/useI18N.ts b/packages/login/src/hooks/useI18N.ts index c9136c9284..808a192f23 100644 --- a/packages/login/src/hooks/useI18N.ts +++ b/packages/login/src/hooks/useI18N.ts @@ -44,7 +44,9 @@ const useI18N = ({ settings }: UseI18NProps) => { window.timezone = settings.timezone; }, [settings?.timezone]); - return { i18n: getI18NInstance(settings?.culture ?? "en") }; + return { + i18n: getI18NInstance(getCookie(LANGUAGE) ?? settings?.culture ?? "en"), + }; }; export default useI18N; diff --git a/packages/login/src/types/index.ts b/packages/login/src/types/index.ts index 1bd6a4f129..9c1ceed271 100644 --- a/packages/login/src/types/index.ts +++ b/packages/login/src/types/index.ts @@ -86,7 +86,6 @@ export type LoginFormProps = { hashSettings?: TPasswordHash; reCaptchaPublicKey?: string; cookieSettingsEnabled: boolean; - currentCulture: string; }; export type ForgotPasswordModalDialogProps = { diff --git a/packages/shared/api/settings/index.ts b/packages/shared/api/settings/index.ts index efc69c4224..41ac7ae9d4 100644 --- a/packages/shared/api/settings/index.ts +++ b/packages/shared/api/settings/index.ts @@ -46,6 +46,7 @@ import { TThirdPartyProvider, TPaymentSettings, TGetSsoSettings, + TPortalCultures, } from "./types"; export async function getSettings(withPassword = false, headers = null) { @@ -67,7 +68,7 @@ export async function getPortalCultures() { const res = (await request({ method: "get", url: "/settings/cultures", - })) as string[]; + })) as TPortalCultures; return res; } From 6ff08972c2e54298e11d84a50c762bd332028180 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Thu, 23 May 2024 17:19:28 +0300 Subject: [PATCH 047/126] Shared:Selectors:Files: open new folder after create --- .../selectors/Files/FilesSelector.types.ts | 3 +- .../selectors/Files/hooks/useFilesHelper.ts | 21 ++- .../selectors/Files/hooks/useSocketHelper.ts | 3 +- packages/shared/selectors/Files/index.tsx | 133 +++++++++--------- 4 files changed, 86 insertions(+), 74 deletions(-) diff --git a/packages/shared/selectors/Files/FilesSelector.types.ts b/packages/shared/selectors/Files/FilesSelector.types.ts index 671a362789..943b15a599 100644 --- a/packages/shared/selectors/Files/FilesSelector.types.ts +++ b/packages/shared/selectors/Files/FilesSelector.types.ts @@ -86,7 +86,7 @@ export type UseRoomsHelperProps = { export type UseFilesHelpersProps = { roomsFolderId?: number; - setBreadCrumbs: (items: TBreadCrumb[]) => void; + setBreadCrumbs: React.Dispatch>; setIsBreadCrumbsLoading: (value: boolean) => void; setIsSelectedParentFolder: (value: boolean) => void; setIsNextPageLoading: (value: boolean) => void; @@ -121,6 +121,7 @@ export type UseFilesHelpersProps = { isInit: boolean; setIsFirstLoad: (value: boolean) => void; withCreateFolder: boolean; + setSelectedItemId: (value: number | string) => void; }; export type TSelectedFileInfo = { diff --git a/packages/shared/selectors/Files/hooks/useFilesHelper.ts b/packages/shared/selectors/Files/hooks/useFilesHelper.ts index 1a71902e6b..777ab91e3e 100644 --- a/packages/shared/selectors/Files/hooks/useFilesHelper.ts +++ b/packages/shared/selectors/Files/hooks/useFilesHelper.ts @@ -84,6 +84,7 @@ const useFilesHelper = ({ setIsInit, setIsFirstLoad, withCreateFolder, + setSelectedItemId, }: UseFilesHelpersProps) => { const { t } = useTranslation(["Common"]); @@ -108,11 +109,15 @@ const useFilesHelper = ({ if (!withCreateFolder) return; setItems((value) => { - if (!value[1].isInputItem) return value; + if (!value[1]?.isInputItem && !value[0]?.isInputItem) return value; + + let idx = 1; + + if (value[0].isInputItem) idx = 0; const newValue = [...value]; - newValue.splice(1, 1); + newValue.splice(idx, 1); return newValue; }); @@ -122,11 +127,15 @@ const useFilesHelper = ({ async (value: string) => { if (!withCreateFolder || !selectedItemId) return; - await createFolder(selectedItemId, value); + const folder = await createFolder(selectedItemId, value); - onCancelInput(); + setBreadCrumbs((val) => { + return [...val, { id: folder.id, label: folder.title }]; + }); + + setSelectedItemId(folder.id); }, - [onCancelInput, selectedItemId, withCreateFolder], + [withCreateFolder, selectedItemId, setBreadCrumbs, setSelectedItemId], ); const addInputItem = React.useCallback(() => { @@ -143,7 +152,7 @@ const useFilesHelper = ({ }; setItems((value) => { - if (value[1].isInputItem) return value; + if (value[1]?.isInputItem || value[0]?.isInputItem) return value; const newValue = [...value]; diff --git a/packages/shared/selectors/Files/hooks/useSocketHelper.ts b/packages/shared/selectors/Files/hooks/useSocketHelper.ts index e9784dc369..46057c9bfa 100644 --- a/packages/shared/selectors/Files/hooks/useSocketHelper.ts +++ b/packages/shared/selectors/Files/hooks/useSocketHelper.ts @@ -126,8 +126,9 @@ const useSocketHelper = ({ if (withCreateFolder) { const newValue = [...value]; - let idx = 1; + let idx = 0; + if (value[0].isInputItem) idx = 1; if (value[1].isInputItem) idx = 2; newValue.splice(idx, 0, item); diff --git a/packages/shared/selectors/Files/index.tsx b/packages/shared/selectors/Files/index.tsx index ba93b305ef..c301cf5fd3 100644 --- a/packages/shared/selectors/Files/index.tsx +++ b/packages/shared/selectors/Files/index.tsx @@ -197,6 +197,72 @@ const FilesSelector = ({ setIsFirstLoad, }); + const onClickBreadCrumb = React.useCallback( + (item: TBreadCrumb) => { + if (!isFirstLoad) { + afterSearch.current = false; + setSearchValue(""); + setIsFirstLoad(true); + if (+item.id === 0) { + setSelectedItemSecurity(undefined); + setSelectedItemType(undefined); + getRootData(); + } else { + setItems([]); + + setBreadCrumbs((bc) => { + const idx = bc.findIndex( + (value) => value.id.toString() === item.id.toString(), + ); + + const maxLength = bc.length - 1; + let foundParentId = false; + let currentFolderIndex = -1; + + const newBreadCrumbs = bc.map((i, index) => { + if (!foundParentId) { + currentFolderIndex = disabledItems.findIndex( + (id) => id === i?.id, + ); + } + + if (index !== maxLength && currentFolderIndex !== -1) { + foundParentId = true; + if (!isSelectedParentFolder) setIsSelectedParentFolder(true); + } + + if ( + index === maxLength && + !foundParentId && + isSelectedParentFolder + ) + setIsSelectedParentFolder(false); + + return { ...i }; + }); + + newBreadCrumbs.splice(idx + 1, newBreadCrumbs.length - idx - 1); + return newBreadCrumbs; + }); + + setSelectedItemId(item.id); + if (item.isRoom) { + setSelectedItemType("rooms"); + } else { + setSelectedItemType("files"); + } + } + } + }, + [ + disabledItems, + getRootData, + isFirstLoad, + isSelectedParentFolder, + setIsFirstLoad, + ], + ); + const { getFileList } = useFilesHelper({ setIsBreadCrumbsLoading, setBreadCrumbs, @@ -227,6 +293,7 @@ const FilesSelector = ({ isInit, setIsInit, withCreateFolder, + setSelectedItemId, }); const onSelectAction = React.useCallback( @@ -326,72 +393,6 @@ const FilesSelector = ({ setIsFirstLoad, ]); - const onClickBreadCrumb = React.useCallback( - (item: TBreadCrumb) => { - if (!isFirstLoad) { - afterSearch.current = false; - setSearchValue(""); - setIsFirstLoad(true); - if (+item.id === 0) { - setSelectedItemSecurity(undefined); - setSelectedItemType(undefined); - getRootData(); - } else { - setItems([]); - - setBreadCrumbs((bc) => { - const idx = bc.findIndex( - (value) => value.id.toString() === item.id.toString(), - ); - - const maxLength = bc.length - 1; - let foundParentId = false; - let currentFolderIndex = -1; - - const newBreadCrumbs = bc.map((i, index) => { - if (!foundParentId) { - currentFolderIndex = disabledItems.findIndex( - (id) => id === i?.id, - ); - } - - if (index !== maxLength && currentFolderIndex !== -1) { - foundParentId = true; - if (!isSelectedParentFolder) setIsSelectedParentFolder(true); - } - - if ( - index === maxLength && - !foundParentId && - isSelectedParentFolder - ) - setIsSelectedParentFolder(false); - - return { ...i }; - }); - - newBreadCrumbs.splice(idx + 1, newBreadCrumbs.length - idx - 1); - return newBreadCrumbs; - }); - - setSelectedItemId(item.id); - if (item.isRoom) { - setSelectedItemType("rooms"); - } else { - setSelectedItemType("files"); - } - } - } - }, - [ - disabledItems, - getRootData, - isFirstLoad, - isSelectedParentFolder, - setIsFirstLoad, - ], - ); - const onSearchAction = React.useCallback( (value: string, callback?: Function) => { setIsFirstLoad(true); From 9af68dbd947adbcf3e4173ec3ed8f04684961d5b Mon Sep 17 00:00:00 2001 From: namushka Date: Fri, 24 May 2024 14:02:49 +0300 Subject: [PATCH 048/126] updated icons for RoomIcon component --- public/images/icons/32/room/custom.svg | 6 +++--- public/images/icons/32/room/editing.svg | 6 +++--- public/images/icons/32/room/form.svg | 2 +- public/images/icons/32/room/public.svg | 9 +-------- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/public/images/icons/32/room/custom.svg b/public/images/icons/32/room/custom.svg index 570fc932d0..3033654a3d 100644 --- a/public/images/icons/32/room/custom.svg +++ b/public/images/icons/32/room/custom.svg @@ -1,10 +1,10 @@ - + + - - + diff --git a/public/images/icons/32/room/editing.svg b/public/images/icons/32/room/editing.svg index ca6b8d9045..a01fae0d38 100644 --- a/public/images/icons/32/room/editing.svg +++ b/public/images/icons/32/room/editing.svg @@ -1,10 +1,10 @@ - + + - - + diff --git a/public/images/icons/32/room/form.svg b/public/images/icons/32/room/form.svg index 05dda31953..d036241507 100644 --- a/public/images/icons/32/room/form.svg +++ b/public/images/icons/32/room/form.svg @@ -1,5 +1,5 @@ + - diff --git a/public/images/icons/32/room/public.svg b/public/images/icons/32/room/public.svg index c69a5473f2..d61c035682 100644 --- a/public/images/icons/32/room/public.svg +++ b/public/images/icons/32/room/public.svg @@ -1,11 +1,4 @@ - - + - - - - - - From 99b7339a835517fd421d731162c7da9696fab976 Mon Sep 17 00:00:00 2001 From: namushka Date: Fri, 24 May 2024 14:03:27 +0300 Subject: [PATCH 049/126] added hover effects for RoomType ListItem and DropdownButton components --- .../sub-components/RoomType.js | 30 ++++++++++++++++--- packages/shared/themes/base.ts | 3 ++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js index 5701347ad6..63614361be 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js @@ -98,10 +98,21 @@ const StyledRoomType = styled.div` const StyledListItem = styled(StyledRoomType)` background-color: ${(props) => props.theme.createEditRoomDialog.roomType.listItem.background}; + + &:hover { + background-color: ${(props) => + props.theme.createEditRoomDialog.roomType.listItem.hoverBackground}; + } + border: 1px solid ${(props) => props.theme.createEditRoomDialog.roomType.listItem.borderColor}; border-radius: 6px; + &:active { + border-color: ${(props) => + props.theme.createEditRoomDialog.roomType.listItem.activeBorderColor}; + } + .choose_room-description { color: ${(props) => props.theme.createEditRoomDialog.roomType.listItem.descriptionText}; @@ -112,12 +123,23 @@ const StyledDropdownButton = styled(StyledRoomType)` border-radius: 6px; background-color: ${(props) => props.theme.createEditRoomDialog.roomType.dropdownButton.background}; + + ${({ isOpen }) => + !isOpen && + css` + &:hover { + background-color: ${(props) => + props.theme.createEditRoomDialog.roomType.dropdownButton + .hoverBackground}; + } + `} + border: 1px solid ${(props) => - props.isOpen - ? props.theme.createEditRoomDialog.roomType.dropdownButton - .isOpenBorderColor - : props.theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; + props.isOpen + ? props.theme.createEditRoomDialog.roomType.dropdownButton + .isOpenBorderColor + : props.theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; .choose_room-description { color: ${(props) => diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index c999e45c33..367fd59331 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -2467,11 +2467,14 @@ export const getBaseTheme = () => { roomType: { listItem: { background: "none", + hoverBackground: "#F8F9F9", borderColor: "#ECEEF1", + activeBorderColor: "#5299E0", descriptionText: "#A3A9AE", }, dropdownButton: { background: "none", + hoverBackground: "#f3f4f4", borderColor: "#ECEEF1", isOpenBorderColor: "#2DA7DB", descriptionText: "#A3A9AE", From 0e0341325a203a06aba35f7f4849707a2b3dd56c Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 24 May 2024 14:06:29 +0300 Subject: [PATCH 050/126] Client:Confirm: Added a culture field for registration via social networks. --- packages/client/src/pages/Confirm/sub-components/createUser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 836a634161..649eb9684a 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -324,6 +324,7 @@ const CreateUserForm = (props) => { Email: linkData.email, Key: linkData.key, SerializedProfile: profile, + culture: currentCultureName, }; signupOAuth(signupAccount) @@ -486,7 +487,7 @@ const CreateUserForm = (props) => { return ( Date: Fri, 24 May 2024 16:55:00 +0300 Subject: [PATCH 051/126] fixed :active styling --- .../sub-components/RoomType.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js index 63614361be..84976d2a44 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js @@ -98,16 +98,15 @@ const StyledRoomType = styled.div` const StyledListItem = styled(StyledRoomType)` background-color: ${(props) => props.theme.createEditRoomDialog.roomType.listItem.background}; - - &:hover { - background-color: ${(props) => - props.theme.createEditRoomDialog.roomType.listItem.hoverBackground}; - } - border: 1px solid ${(props) => props.theme.createEditRoomDialog.roomType.listItem.borderColor}; border-radius: 6px; + &:hover:not(:active) { + background-color: ${(props) => + props.theme.createEditRoomDialog.roomType.listItem.hoverBackground}; + } + &:active { border-color: ${(props) => props.theme.createEditRoomDialog.roomType.listItem.activeBorderColor}; @@ -127,7 +126,7 @@ const StyledDropdownButton = styled(StyledRoomType)` ${({ isOpen }) => !isOpen && css` - &:hover { + &:hover:not(:active) { background-color: ${(props) => props.theme.createEditRoomDialog.roomType.dropdownButton .hoverBackground}; @@ -141,6 +140,12 @@ const StyledDropdownButton = styled(StyledRoomType)` .isOpenBorderColor : props.theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; + &:active { + border-color: ${(props) => + props.theme.createEditRoomDialog.roomType.dropdownButton + .isOpenBorderColor}; + } + .choose_room-description { color: ${(props) => props.theme.createEditRoomDialog.roomType.dropdownButton.descriptionText}; From afadcf2a38058f23d1bbb3cbe7d6fbf1c95950de Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 24 May 2024 18:45:22 +0300 Subject: [PATCH 052/126] Shared: Components: Combobox: Added prop. --- packages/shared/components/combobox/ComboBox.tsx | 8 ++++---- packages/shared/components/combobox/Combobox.types.ts | 1 + .../components/language-combobox/LanguageCombobox.tsx | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/shared/components/combobox/ComboBox.tsx b/packages/shared/components/combobox/ComboBox.tsx index 15ec83f66e..e9f59125f7 100644 --- a/packages/shared/components/combobox/ComboBox.tsx +++ b/packages/shared/components/combobox/ComboBox.tsx @@ -166,6 +166,7 @@ const ComboBoxPure = (props: ComboboxProps) => { plusBadgeValue, optionStyle, style, + withLabel = true, } = props; const { tabIndex, onClickSelectedItem } = props; @@ -227,10 +228,9 @@ const ComboBoxPure = (props: ComboboxProps) => { option.disabled || (!displaySelectedOption && option.label === selectedOption.label); - const isActiveOption = - typeof option.label === "string" - ? option.label === selectedOption.label - : option.key === selectedOption.key; + const isActiveOption = withLabel + ? option.label === selectedOption.label + : option.key === selectedOption.key; const isActive = displaySelectedOption && isActiveOption; diff --git a/packages/shared/components/combobox/Combobox.types.ts b/packages/shared/components/combobox/Combobox.types.ts index 7704ea3815..2e545cdebe 100644 --- a/packages/shared/components/combobox/Combobox.types.ts +++ b/packages/shared/components/combobox/Combobox.types.ts @@ -166,6 +166,7 @@ export interface ComboboxProps { withBlur?: boolean; title?: string; plusBadgeValue?: number; + withLabel?: boolean; } export interface ComboButtonProps { diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx index 8812904afc..a658fd4848 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.tsx +++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx @@ -83,6 +83,7 @@ const LanguageCombobox = (props: ComboboxProps) => { isMobileView={isMobileView} withBlur={isMobileView} withBorder={withBorder} + withLabel={!!withLabel} /> ); }; From 8f205d5c6762554f08a3521169bd26bea2192f21 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 24 May 2024 18:54:34 +0300 Subject: [PATCH 053/126] Client: FormGallery: Fixed mobile view. --- .../pages/FormGallery/Filter/LanguageFilter/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index a4804c7be0..8abe69536e 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -31,6 +31,7 @@ import { inject, observer } from "mobx-react"; import { RectangleSkeleton } from "@docspace/shared/skeletons"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; +import { DeviceType } from "@docspace/shared/enums"; const keyedCollections = { ar: "ar-SA", @@ -61,6 +62,7 @@ const LanguageFilter = ({ languageFilterLoaded, oformFilesLoaded, oformsLocal, + isMobileView, }) => { const convertedLocales = oformLocales.map((item) => convertToCulture(item)); @@ -90,11 +92,12 @@ const LanguageFilter = ({ onSelectLanguage={onFilterByLocale} selectedCulture={convertToCulture(oformsLocal)} id="comboBoxLanguage" + isMobileView={isMobileView} /> ); }; -export default inject(({ oformsStore }) => { +export default inject(({ oformsStore, settingsStore }) => { const { oformLocales, filterOformsByLocale, @@ -106,6 +109,10 @@ export default inject(({ oformsStore }) => { oformsFilter, } = oformsStore; + const { currentDeviceType } = settingsStore; + + const isMobileView = currentDeviceType === DeviceType.mobile; + return { oformLocales, filterOformsByLocale, @@ -115,5 +122,7 @@ export default inject(({ oformsStore }) => { languageFilterLoaded, oformFilesLoaded, oformsLocal: oformsFilter.locale, + + isMobileView, }; })(withTranslation(["Common"])(observer(LanguageFilter))); From 2440be2675d4a0ec36b359b9e1712c5d7f81d381 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 10:41:45 +0300 Subject: [PATCH 054/126] Shared: Components: Combobox: Added closing of the drop-down menu when changing screen size from mobile to tablet. --- packages/shared/components/combobox/ComboBox.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shared/components/combobox/ComboBox.tsx b/packages/shared/components/combobox/ComboBox.tsx index e9f59125f7..f516098fab 100644 --- a/packages/shared/components/combobox/ComboBox.tsx +++ b/packages/shared/components/combobox/ComboBox.tsx @@ -180,6 +180,10 @@ const ComboBoxPure = (props: ComboboxProps) => { setSelectedOption(selectedOptionProps); }, [selectedOptionProps]); + React.useEffect(() => { + setIsOpen(false); + }, [withLabel]); + const dropDownMaxHeightProp = dropDownMaxHeight ? { maxHeight: dropDownMaxHeight } : {}; From 5af949b406c183d805afb198088a27310ef29e80 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 10:45:56 +0300 Subject: [PATCH 055/126] Shared: Components: LanguageCombobox: Deleted useless code. --- .../language-combobox/LanguageCombobox.styled.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts index 0912b86bc1..4235c7c7ce 100644 --- a/packages/shared/components/language-combobox/LanguageCombobox.styled.ts +++ b/packages/shared/components/language-combobox/LanguageCombobox.styled.ts @@ -54,11 +54,4 @@ export const StyledComboBox = styled(ComboBox)<{ withBorder: boolean }>` .combo-buttons_arrow-icon { margin: 0; } - - .dropdown-container { - width: 41px; - .drop-down-item { - padding: 0; - } - } `; From 4618e8a1007fab1caa3cd4df146bbb9a6340a096 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 27 May 2024 10:52:23 +0300 Subject: [PATCH 056/126] Shared:Selectors:Files: remove opening folder after creation, now it add to top of list --- .../shared/selectors/Files/FilesSelector.types.ts | 1 - .../selectors/Files/hooks/useFilesHelper.ts | 15 ++++++++------- packages/shared/selectors/Files/index.tsx | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/shared/selectors/Files/FilesSelector.types.ts b/packages/shared/selectors/Files/FilesSelector.types.ts index 943b15a599..30ac26bfa8 100644 --- a/packages/shared/selectors/Files/FilesSelector.types.ts +++ b/packages/shared/selectors/Files/FilesSelector.types.ts @@ -121,7 +121,6 @@ export type UseFilesHelpersProps = { isInit: boolean; setIsFirstLoad: (value: boolean) => void; withCreateFolder: boolean; - setSelectedItemId: (value: number | string) => void; }; export type TSelectedFileInfo = { diff --git a/packages/shared/selectors/Files/hooks/useFilesHelper.ts b/packages/shared/selectors/Files/hooks/useFilesHelper.ts index 777ab91e3e..6f6dc2e4bd 100644 --- a/packages/shared/selectors/Files/hooks/useFilesHelper.ts +++ b/packages/shared/selectors/Files/hooks/useFilesHelper.ts @@ -84,7 +84,6 @@ const useFilesHelper = ({ setIsInit, setIsFirstLoad, withCreateFolder, - setSelectedItemId, }: UseFilesHelpersProps) => { const { t } = useTranslation(["Common"]); @@ -127,15 +126,17 @@ const useFilesHelper = ({ async (value: string) => { if (!withCreateFolder || !selectedItemId) return; - const folder = await createFolder(selectedItemId, value); + await createFolder(selectedItemId, value); - setBreadCrumbs((val) => { - return [...val, { id: folder.id, label: folder.title }]; - }); + onCancelInput(); - setSelectedItemId(folder.id); + // setBreadCrumbs((val) => { + // return [...val, { id: folder.id, label: folder.title }]; + // }); + + // setSelectedItemId(folder.id); }, - [withCreateFolder, selectedItemId, setBreadCrumbs, setSelectedItemId], + [withCreateFolder, selectedItemId, onCancelInput], ); const addInputItem = React.useCallback(() => { diff --git a/packages/shared/selectors/Files/index.tsx b/packages/shared/selectors/Files/index.tsx index c301cf5fd3..0886dbe53a 100644 --- a/packages/shared/selectors/Files/index.tsx +++ b/packages/shared/selectors/Files/index.tsx @@ -293,7 +293,6 @@ const FilesSelector = ({ isInit, setIsInit, withCreateFolder, - setSelectedItemId, }); const onSelectAction = React.useCallback( From 2583d4af163c5642443b5eb22923096f907abba6 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 27 May 2024 10:52:40 +0300 Subject: [PATCH 057/126] Shared:Components:Selector: add hotkeys for input item --- .../shared/components/selector/Selector.tsx | 6 ++- .../components/selector/Selector.types.ts | 3 ++ .../selector/sub-components/Body.tsx | 2 + .../selector/sub-components/InputItem.tsx | 40 +++++++++++++++++-- .../selector/sub-components/Item.tsx | 2 + 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/packages/shared/components/selector/Selector.tsx b/packages/shared/components/selector/Selector.tsx index d433386e66..26f1dd1054 100644 --- a/packages/shared/components/selector/Selector.tsx +++ b/packages/shared/components/selector/Selector.tsx @@ -158,6 +158,8 @@ const Selector = ({ return null; }); + const [inputItemVisible, setInputItemVisible] = React.useState(false); + const [requestRunning, setRequestRunning] = React.useState(false); const onSubmitAction = async ( @@ -386,6 +388,7 @@ const Selector = ({ React.useEffect(() => { const onKeyboardAction = (e: KeyboardEvent) => { + if (inputItemVisible) return; if (e.key === ButtonKeys.esc) { onCancel?.(); } @@ -395,7 +398,7 @@ const Selector = ({ return () => { window.removeEventListener("keydown", onKeyboardAction); }; - }, [onCancel]); + }, [inputItemVisible, onCancel]); React.useLayoutEffect(() => { if (items) { @@ -596,6 +599,7 @@ const Selector = ({ withFooterInput={withFooterInput} withFooterCheckbox={withFooterCheckbox} descriptionText={descriptionText} + setInputItemVisible={setInputItemVisible} // bread crumbs {...breadCrumbsProps} // select all diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index db2c29f286..a5b249e4b3 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -354,6 +354,8 @@ export type BodyProps = TSelectorBreadCrumbs & isMultiSelect: boolean; + setInputItemVisible: (value: boolean) => void; + items: TSelectorItem[]; renderCustomItem?: ( label: string, @@ -538,6 +540,7 @@ export type Data = { email?: string, isGroup?: boolean, ) => React.ReactNode | null; + setInputItemVisible: (value: boolean) => void; }; export interface ItemProps { diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index c8a45d1761..32e5ef516b 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -102,6 +102,7 @@ const Body = ({ withInfo, infoText, + setInputItemVisible, }: BodyProps) => { const [bodyHeight, setBodyHeight] = React.useState(0); @@ -270,6 +271,7 @@ const Body = ({ rowLoader, isItemLoaded, renderCustomItem, + setInputItemVisible, }} itemSize={48} onItemsRendered={onItemsRendered} diff --git a/packages/shared/components/selector/sub-components/InputItem.tsx b/packages/shared/components/selector/sub-components/InputItem.tsx index db4a8661ef..4eafb3378d 100644 --- a/packages/shared/components/selector/sub-components/InputItem.tsx +++ b/packages/shared/components/selector/sub-components/InputItem.tsx @@ -43,6 +43,8 @@ const InputItem = ({ color, icon, + + setInputItemVisible, }: { defaultInputValue: string; onAcceptInput: (value: string) => void; @@ -51,13 +53,45 @@ const InputItem = ({ color?: string; icon?: string; + + setInputItemVisible: (value: boolean) => void; }) => { const [value, setValue] = React.useState(defaultInputValue); + + const requestRunning = React.useRef(false); const inputRef = React.useRef(null); - const onAcceptInputAction = () => { - onAcceptInput(value); - }; + const onAcceptInputAction = React.useCallback(async () => { + if (requestRunning.current) return; + requestRunning.current = true; + await onAcceptInput(value); + + requestRunning.current = false; + }, [onAcceptInput, value]); + + React.useEffect(() => { + setInputItemVisible(true); + + return () => { + setInputItemVisible(false); + }; + }, [setInputItemVisible]); + + React.useEffect(() => { + const onKeyDown = (e: KeyboardEvent) => { + e.preventDefault(); + e.stopPropagation(); + + if (e.key === "Enter") onAcceptInputAction(); + else if (e.key === "Escape") onCancelInput(); + }; + + window.addEventListener("keydown", onKeyDown); + + return () => { + window.removeEventListener("keydown", onKeyDown); + }; + }, [onAcceptInputAction, onCancelInput]); const onChange = (e: React.ChangeEvent) => { const newVal = e.target.value; diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index 08dc90cfb5..35b3e77090 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -66,6 +66,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { isItemLoaded, rowLoader, renderCustomItem, + setInputItemVisible, }: Data = data; const { t } = useTranslation(["Common"]); @@ -109,6 +110,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { style={style} color={color} icon={icon} + setInputItemVisible={setInputItemVisible} /> ); } From 994c41e030ef27f357d8d8d705cb42e06a324c38 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 12:02:29 +0300 Subject: [PATCH 058/126] updated room type action color --- .../sub-components/RoomType.js | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js index 84976d2a44..5bbde85009 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js @@ -24,6 +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 { inject, observer } from "mobx-react"; import ArrowReactSvgUrl from "PUBLIC_DIR/images/arrow.react.svg?url"; import React from "react"; import PropTypes from "prop-types"; @@ -107,9 +108,10 @@ const StyledListItem = styled(StyledRoomType)` props.theme.createEditRoomDialog.roomType.listItem.hoverBackground}; } + ${(props) => console.log(props.accentColor)} + &:active { - border-color: ${(props) => - props.theme.createEditRoomDialog.roomType.listItem.activeBorderColor}; + border-color: ${({ accentColor }) => accentColor}; } .choose_room-description { @@ -134,16 +136,15 @@ const StyledDropdownButton = styled(StyledRoomType)` `} border: 1px solid - ${(props) => - props.isOpen - ? props.theme.createEditRoomDialog.roomType.dropdownButton - .isOpenBorderColor - : props.theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; + ${({ isOpen, accentColor, theme }) => + isOpen + ? accentColor + : theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; + + ${(props) => console.log(props.accentColor)} &:active { - border-color: ${(props) => - props.theme.createEditRoomDialog.roomType.dropdownButton - .isOpenBorderColor}; + border-color: ${({ accentColor }) => accentColor}; } .choose_room-description { @@ -205,6 +206,7 @@ const RoomType = ({ isOpen, id, selectedId, + currentColorScheme, }) => { const room = { type: roomType, @@ -212,6 +214,8 @@ const RoomType = ({ description: getRoomTypeDescriptionTranslation(roomType, t), }; + const accentColor = currentColorScheme?.main?.accent; + const arrowClassName = type === "dropdownButton" ? "choose_room-forward_btn dropdown-button" @@ -246,7 +250,12 @@ const RoomType = ({ ); return type === "listItem" ? ( - + {content} ) : type === "dropdownButton" ? ( @@ -256,6 +265,7 @@ const RoomType = ({ onClick={onClick} isOpen={isOpen} data-selected-id={selectedId} + accentColor={accentColor} > {content} @@ -266,6 +276,7 @@ const RoomType = ({ onClick={onClick} isOpen={isOpen} data-selected-id={selectedId} + currentColorScheme={currentColorScheme} > {content} @@ -274,6 +285,7 @@ const RoomType = ({ id={id} title={t(room.title)} data-selected-id={selectedId} + currentColorScheme={currentColorScheme} > {content} @@ -295,6 +307,9 @@ RoomType.propTypes = { "dropdownItem", ]), isOpen: PropTypes.bool, + currentColorScheme: PropTypes.object, }; -export default RoomType; +export default inject(({ settingsStore }) => ({ + currentColorScheme: settingsStore.currentColorScheme, +}))(observer(RoomType)); From 50b820d4a7a919f49b4dc18cbd4a7608bb4642a1 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 14:48:35 +0300 Subject: [PATCH 059/126] Client/Shared: Components: Added background realization through portals. --- .../NavMenu/sub-components/profile-menu.js | 11 +-- .../shared/components/drop-down/DropDown.tsx | 87 ++++++++++++------- .../shared/components/drop-down/index.tsx | 24 ++--- 3 files changed, 62 insertions(+), 60 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/profile-menu.js b/packages/client/src/components/NavMenu/sub-components/profile-menu.js index 480b142692..2312c08722 100644 --- a/packages/client/src/components/NavMenu/sub-components/profile-menu.js +++ b/packages/client/src/components/NavMenu/sub-components/profile-menu.js @@ -208,7 +208,6 @@ class ProfileMenu extends React.Component { open={open} clickOutsideAction={clickOutsideAction} forwardedRef={forwardedRef} - isDefaultMode={false} withBlur={true} isBannerVisible={isBannerVisible} withPortal={true} @@ -237,15 +236,7 @@ class ProfileMenu extends React.Component { }; render() { - const { open } = this.props; - - const element = this.renderDropDown(); - - const root = document.getElementById("root"); - - const wrapper = {element}; - - return <>{}; + return {this.renderDropDown()}; } } diff --git a/packages/shared/components/drop-down/DropDown.tsx b/packages/shared/components/drop-down/DropDown.tsx index cad6c53d90..1cbef7033a 100644 --- a/packages/shared/components/drop-down/DropDown.tsx +++ b/packages/shared/components/drop-down/DropDown.tsx @@ -37,6 +37,7 @@ import { Row } from "./sub-components/Row"; import { DropDownProps } from "./DropDown.types"; import { DEFAULT_PARENT_HEIGHT } from "./DropDown.constants"; +import { Backdrop } from "../backdrop"; const DropDown = ({ directionY = "bottom", @@ -67,6 +68,11 @@ const DropDown = ({ manualY, className, style, + withoutBackground, + withBackground, + withBackdrop, + isAside, + withBlur, }: DropDownProps) => { const theme = useTheme(); @@ -382,42 +388,59 @@ const DropDown = ({ ? { height: `${calculatedHeight}px` } : {}; + const toggleDropDown = () => { + clickOutsideAction?.({} as Event, !open); + }; + return ( - - + {withBackdrop ? ( + + ) : null} + - {children} - - + + {children} + + + ); }; diff --git a/packages/shared/components/drop-down/index.tsx b/packages/shared/components/drop-down/index.tsx index e3867e8e99..611e40a969 100644 --- a/packages/shared/components/drop-down/index.tsx +++ b/packages/shared/components/drop-down/index.tsx @@ -33,23 +33,11 @@ import { DropDownProps } from "./DropDown.types"; import { EnhancedComponent } from "./DropDown"; const DropDown = (props: DropDownProps) => { - const { - clickOutsideAction, - open, - withBackdrop = true, + const { eventTypes, forceCloseClickOutside } = props; - withBlur = false, - - isAside, - withBackground, - eventTypes, - forceCloseClickOutside, - withoutBackground, - } = props; - - const toggleDropDown = () => { - clickOutsideAction?.({} as Event, !open); - }; + // const toggleDropDown = () => { + // clickOutsideAction?.({} as Event, !open); + // }; const eventTypesProp = forceCloseClickOutside ? {} @@ -61,7 +49,7 @@ const DropDown = (props: DropDownProps) => { return ( <> - {withBackdrop ? ( + {/* {withBackdrop ? ( { withBackground={withBackground} withoutBackground={withoutBackground} /> - ) : null} + ) : null} */} ); From 5ca93a01745fbb6fe9461c2ea987304768a630d3 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Mon, 27 May 2024 17:17:36 +0500 Subject: [PATCH 060/126] fix Bug 67844 - users limit was added --- .../Stepper/SelectUsersStep/index.js | 35 ++++++++----- .../Stepper/AddEmailsStep/index.js | 43 +++++++++++----- .../Stepper/SelectUsersStep/index.js | 35 +++++++++---- .../Stepper/SelectUsersStep/index.js | 35 ++++++++----- .../sub-components/UsersInfoBlock.js | 5 +- .../categories/data-import/utils/index.js | 50 +++++++++++++++++++ 6 files changed, 152 insertions(+), 51 deletions(-) create mode 100644 packages/client/src/pages/PortalSettings/categories/data-import/utils/index.js diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js index 3b26acf1b6..c180fc36b1 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js @@ -34,7 +34,7 @@ import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../../sub-components/AccountsPaging"; import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; -const LICENSE_LIMIT = 1; +import { parseQuota } from "../../../utils"; const SelectUsersStep = ({ t, @@ -47,11 +47,14 @@ const SelectUsersStep = ({ areCheckedUsersEmpty, cancelMigration, checkedUsers, + quotaCharacteristics, }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); + const [quota, setQuota] = useState({ used: 0, max: 0 }); useEffect(() => { setSearchValue(""); + setQuota(parseQuota(quotaCharacteristics[1])); }, []); const handleDataChange = (leftBoundary, rightBoundary) => { @@ -83,6 +86,10 @@ const SelectUsersStep = ({ setTimeout(onPrevStep, 100); }; + const totalUsedUsers = + quota.used + + checkedUsers.withEmail.filter((user) => !user.isDuplicate).length; + return ( <> LICENSE_LIMIT - } + saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} /> - + {quota.max && ( + + )} LICENSE_LIMIT + areCheckedUsersEmpty || totalUsedUsers > quota.max } /> )} @@ -144,7 +151,7 @@ const SelectUsersStep = ({ ); }; -export default inject(({ importAccountsStore }) => { +export default inject(({ importAccountsStore, currentQuotaStore }) => { const { withEmailUsers, searchValue, @@ -154,6 +161,7 @@ export default inject(({ importAccountsStore }) => { cancelMigration, checkedUsers, } = importAccountsStore; + const { quotaCharacteristics } = currentQuotaStore; return { withEmailUsers, @@ -163,5 +171,6 @@ export default inject(({ importAccountsStore }) => { setResultUsers, cancelMigration, checkedUsers, + quotaCharacteristics, }; })(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js index f8c64403d9..aa754983de 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/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 { useState } from "react"; +import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons"; @@ -39,7 +39,7 @@ import { Wrapper } from "../StyledStepper"; import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; import { NoEmailUsersBlock } from "../../../sub-components/NoEmailUsersBlock"; -const LICENSE_LIMIT = 3; +import { parseQuota } from "../../../utils"; const AddEmailsStep = (props) => { const { @@ -52,11 +52,14 @@ const AddEmailsStep = (props) => { setResultUsers, areCheckedUsersEmpty, checkedUsers, + quotaCharacteristics, + withEmailUsers, } = props; const [dataPortion, setDataPortion] = useState( users.withoutEmail.slice(0, 25), ); + const [quota, setQuota] = useState({ used: 0, max: 0 }); const handleDataChange = (leftBoundary, rightBoundary) => { setDataPortion(users.withoutEmail.slice(leftBoundary, rightBoundary)); @@ -84,6 +87,15 @@ const AddEmailsStep = (props) => { const numberOfSelectedUsers = checkedUsers.withEmail.length + checkedUsers.withoutEmail.length; + useEffect(() => { + setQuota(parseQuota(quotaCharacteristics[1])); + }); + + const totalUsedUsers = + quota.used + + checkedUsers.withEmail.filter((user) => !user.isDuplicate).length + + checkedUsers.withoutEmail.length; + return ( {users.withoutEmail.length > 0 && ( @@ -105,16 +117,19 @@ const AddEmailsStep = (props) => { showReminder displaySettings saveButtonDisabled={ - areCheckedUsersEmpty || numberOfSelectedUsers > LICENSE_LIMIT + areCheckedUsersEmpty || totalUsedUsers > quota.max } /> - + {quota.max && ( + + )} { cancelButtonLabel={t("Common:Back")} showReminder displaySettings - saveButtonDisabled={ - areCheckedUsersEmpty || numberOfSelectedUsers > LICENSE_LIMIT - } + saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} /> ); }; -export default inject(({ setup, importAccountsStore }) => { +export default inject(({ setup, importAccountsStore, currentQuotaStore }) => { const { viewAs } = setup; const { searchValue, @@ -166,7 +179,9 @@ export default inject(({ setup, importAccountsStore }) => { setResultUsers, areCheckedUsersEmpty, checkedUsers, + withEmailUsers, } = importAccountsStore; + const { quotaCharacteristics } = currentQuotaStore; return { viewAs, @@ -176,5 +191,7 @@ export default inject(({ setup, importAccountsStore }) => { setResultUsers, areCheckedUsersEmpty, checkedUsers, + quotaCharacteristics, + withEmailUsers, }; })(observer(AddEmailsStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js index 66a7cfdc03..b8d2aea6a8 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js @@ -37,7 +37,7 @@ import AccountsPaging from "../../../sub-components/AccountsPaging"; import UsersInfoBlock from "../../../sub-components/UsersInfoBlock"; import { Wrapper } from "../StyledStepper"; -const LICENSE_LIMIT = 3; +import { parseQuota } from "../../../utils"; const SelectUsersStep = (props) => { const { @@ -49,12 +49,16 @@ const SelectUsersStep = (props) => { setSearchValue, cancelMigration, checkedUsers, + quotaCharacteristics, + users, } = props; const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); + const [quota, setQuota] = useState({ used: 0, max: 0 }); useEffect(() => { setSearchValue(""); + setQuota(parseQuota(quotaCharacteristics[1])); }, []); const handleDataChange = (leftBoundary, rightBoundary) => { @@ -81,6 +85,14 @@ const SelectUsersStep = (props) => { setTimeout(decrementStep, 100); }; + const numberOfSelectedUsers = + checkedUsers.withEmail.length + checkedUsers.withoutEmail.length; + + const totalUsedUsers = + quota.used + + checkedUsers.withEmail.filter((user) => !user.isDuplicate).length + + checkedUsers.withoutEmail.length; + return ( {withEmailUsers.length > 0 ? ( @@ -95,14 +107,15 @@ const SelectUsersStep = (props) => { displaySettings /> - + {quota.max && ( + + )} { ); }; -export default inject(({ importAccountsStore }) => { +export default inject(({ importAccountsStore, currentQuotaStore }) => { const { users, withEmailUsers, @@ -153,6 +166,7 @@ export default inject(({ importAccountsStore }) => { cancelMigration, checkedUsers, } = importAccountsStore; + const { quotaCharacteristics } = currentQuotaStore; return { users, @@ -161,5 +175,6 @@ export default inject(({ importAccountsStore }) => { setSearchValue, cancelMigration, checkedUsers, + quotaCharacteristics, }; })(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js index 9c1fb9a0e2..68eb887c8d 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js @@ -34,7 +34,7 @@ import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../../sub-components/AccountsPaging"; import UsersInfoBlock from "./../../../sub-components/UsersInfoBlock"; -const LICENSE_LIMIT = 10; +import { parseQuota } from "../../../utils"; const SelectUsersStep = ({ t, @@ -47,11 +47,14 @@ const SelectUsersStep = ({ setSearchValue, cancelMigration, checkedUsers, + quotaCharacteristics, }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); + const [quota, setQuota] = useState({ used: 0, max: 0 }); useEffect(() => { setSearchValue(""); + setQuota(parseQuota(quotaCharacteristics[1])); }, []); const handleDataChange = (leftBoundary, rightBoundary) => { @@ -83,6 +86,10 @@ const SelectUsersStep = ({ setTimeout(onPrevStep, 100); }; + const totalUsedUsers = + quota.used + + checkedUsers.withEmail.filter((user) => !user.isDuplicate).length; + return ( <> LICENSE_LIMIT - } + saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} /> - + {quota.max && ( + + )} LICENSE_LIMIT + areCheckedUsersEmpty || totalUsedUsers > quota.max } /> )} @@ -144,7 +151,7 @@ const SelectUsersStep = ({ ); }; -export default inject(({ importAccountsStore }) => { +export default inject(({ importAccountsStore, currentQuotaStore }) => { const { withEmailUsers, searchValue, @@ -154,6 +161,7 @@ export default inject(({ importAccountsStore }) => { cancelMigration, checkedUsers, } = importAccountsStore; + const { quotaCharacteristics } = currentQuotaStore; return { setResultUsers, @@ -163,5 +171,6 @@ export default inject(({ importAccountsStore }) => { setSearchValue, cancelMigration, checkedUsers, + quotaCharacteristics, }; })(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/UsersInfoBlock.js b/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/UsersInfoBlock.js index 69552169cf..002f5a82d6 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/UsersInfoBlock.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/UsersInfoBlock.js @@ -87,6 +87,7 @@ const UsersInfoBlock = ({ t, selectedUsers, totalUsers, + totalUsedUsers, totalLicenceLimit, }) => { return ( @@ -98,7 +99,7 @@ const UsersInfoBlock = ({ )} @@ -107,7 +108,7 @@ const UsersInfoBlock = ({ {t("Settings:LicenseLimitCounter")} - {selectedUsers}/{totalLicenceLimit} + {totalUsedUsers}/{totalLicenceLimit} { + const maxValue = quotaCharacteristics.value; + const usedValue = quotaCharacteristics.used.value; + + if (maxValue === PortalFeaturesLimitations.Unavailable) return; + + const isExistsMaxValue = maxValue !== PortalFeaturesLimitations.Limitless; + + const resultingMaxValue = + quotaCharacteristics.type === "size" && isExistsMaxValue + ? getConvertedSize(t, maxValue) + : isExistsMaxValue + ? maxValue + : null; + + const resultingUsedValue = + quotaCharacteristics.type === "size" + ? getConvertedSize(t, usedValue) + : usedValue; + + return { used: resultingUsedValue, max: resultingMaxValue }; +}; From 13e2576d503f68476941c66a05337306495e1786 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 15:58:57 +0300 Subject: [PATCH 061/126] Client: Confirm: Fixed closing of the drop-down menu during resize. --- .../sub-components/LanguageCombobox.tsx | 69 +++++++++++++++++++ .../Confirm/sub-components/createUser.js | 18 ++--- 2 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 packages/client/src/pages/Confirm/sub-components/LanguageCombobox.tsx diff --git a/packages/client/src/pages/Confirm/sub-components/LanguageCombobox.tsx b/packages/client/src/pages/Confirm/sub-components/LanguageCombobox.tsx new file mode 100644 index 0000000000..e69c84a573 --- /dev/null +++ b/packages/client/src/pages/Confirm/sub-components/LanguageCombobox.tsx @@ -0,0 +1,69 @@ +// (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 { inject, observer } from "mobx-react"; +import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; +import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; +import { TPortalCultures } from "@docspace/shared/api/settings/types"; +import { DeviceType } from "@docspace/shared/enums"; + +export interface TLanguageCombobox { + cultures: TPortalCultures; + currentDeviceType: string; + currentCultureName: string; +} + +const LanguageComboboxWrapper = (props: TLanguageCombobox) => { + const { cultures, currentCultureName, currentDeviceType } = props; + + const onLanguageSelect = (culture: { key: string }) => { + const { key } = culture; + + setLanguageForUnauthorized(key); + }; + + const isMobileView = currentDeviceType === DeviceType.mobile; + + if (isMobileView) return <>; + + return ( + + ); +}; + +export default inject(({ settingsStore }) => { + const { currentDeviceType } = settingsStore; + + return { + currentDeviceType, + }; +})(observer(LanguageComboboxWrapper)); diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 649eb9684a..d092c772ac 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -49,7 +49,6 @@ import { createPasswordHash, getOAuthToken, getLoginLink, - setLanguageForUnauthorized, } from "@docspace/shared/utils/common"; import { login } from "@docspace/shared/utils/loginUtils"; import { @@ -70,9 +69,9 @@ import { StyledCreateUserContent, } from "./StyledCreateUser"; import GreetingUserContainer from "./GreetingUserContainer"; +import LanguageComboboxWrapper from "./LanguageCombobox"; import withCultureNames from "SRC_DIR/HOCs/withCultureNames"; -import { isMobile } from "@docspace/shared/utils"; -import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; + import { setCookie } from "@docspace/shared/utils/cookie"; const DEFAULT_ROOM_TEXT = @@ -478,20 +477,11 @@ const CreateUserForm = (props) => { } : {}; - const onSelect = (culture) => { - const { key } = culture; - - setLanguageForUnauthorized(key, i18n); - }; - return ( - From bf8f0a59730d441c0a5f0c6a5e0fef8dbf78540a Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Mon, 27 May 2024 18:21:30 +0500 Subject: [PATCH 062/126] Web: Client: Data Import: added quota check --- .../GoogleWorkspace/Stepper/SelectUsersStep/index.js | 6 ++++-- .../NextCloudWorkspace/Stepper/AddEmailsStep/index.js | 6 ++++-- .../OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js index c180fc36b1..b1eeb487b6 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js @@ -100,7 +100,9 @@ const SelectUsersStep = ({ saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings={true} - saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} + saveButtonDisabled={ + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) + } /> {quota.max && ( @@ -143,7 +145,7 @@ const SelectUsersStep = ({ cancelButtonLabel={t("Common:Back")} displaySettings={true} saveButtonDisabled={ - areCheckedUsersEmpty || totalUsedUsers > quota.max + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } /> )} diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js index aa754983de..049b073ea5 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js @@ -117,7 +117,7 @@ const AddEmailsStep = (props) => { showReminder displaySettings saveButtonDisabled={ - areCheckedUsersEmpty || totalUsedUsers > quota.max + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } /> @@ -164,7 +164,9 @@ const AddEmailsStep = (props) => { cancelButtonLabel={t("Common:Back")} showReminder displaySettings - saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} + saveButtonDisabled={ + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) + } /> ); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js index 68eb887c8d..b36085c306 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js @@ -100,7 +100,9 @@ const SelectUsersStep = ({ saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings - saveButtonDisabled={areCheckedUsersEmpty || totalUsedUsers > quota.max} + saveButtonDisabled={ + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) + } /> {quota.max && ( @@ -143,7 +145,7 @@ const SelectUsersStep = ({ cancelButtonLabel={t("Common:Back")} displaySettings saveButtonDisabled={ - areCheckedUsersEmpty || totalUsedUsers > quota.max + areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } /> )} From 62ecc7952dda60dbf81814494878e914017c76b5 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 16:29:25 +0300 Subject: [PATCH 063/126] fixed dark theme --- packages/shared/themes/dark.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index 363891c81f..3ac1edd60a 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -2446,18 +2446,20 @@ const Dark: TTheme = { roomType: { listItem: { background: "none", + hoverBackground: "#282828", borderColor: "#474747", descriptionText: "#A3A9AE", }, dropdownButton: { background: "none", + hoverBackground: "#282828", borderColor: "#474747", isOpenBorderColor: "#F97A0B", descriptionText: "#A3A9AE", }, dropdownItem: { background: "#333333", - hoverBackground: "#474747", + hoverBackground: "#282828", descriptionText: "#A3A9AE", }, displayItem: { @@ -2492,7 +2494,7 @@ const Dark: TTheme = { background: "#333333", borderColor: "#474747", item: { - hoverBackground: "#474747", + hoverBackground: "#282828", }, }, From 9ec645ba5c3e1721c88d5fbca6e4b2984f143fda Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 16:29:54 +0300 Subject: [PATCH 064/126] removed unused theme keys --- packages/shared/themes/base.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index 367fd59331..888e35590e 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -2469,7 +2469,6 @@ export const getBaseTheme = () => { background: "none", hoverBackground: "#F8F9F9", borderColor: "#ECEEF1", - activeBorderColor: "#5299E0", descriptionText: "#A3A9AE", }, dropdownButton: { From fa900eef9466a0767910393f363a188702a404ef Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 16:31:38 +0300 Subject: [PATCH 065/126] updated light color --- packages/shared/themes/base.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index 888e35590e..2d7ef72ae4 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -2473,14 +2473,14 @@ export const getBaseTheme = () => { }, dropdownButton: { background: "none", - hoverBackground: "#f3f4f4", + hoverBackground: "#F8F9F9", borderColor: "#ECEEF1", isOpenBorderColor: "#2DA7DB", descriptionText: "#A3A9AE", }, dropdownItem: { background: "#ffffff", - hoverBackground: "#f3f4f4", + hoverBackground: "#F8F9F9", descriptionText: "#A3A9AE", }, displayItem: { From 094ae26c7210ea94a140195c2c462e1a4b24bd4e Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 16:38:52 +0300 Subject: [PATCH 066/126] fixed dark theme for EditRoom dialog --- packages/shared/themes/dark.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index 3ac1edd60a..04df54c3f6 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -2463,8 +2463,8 @@ const Dark: TTheme = { descriptionText: "#A3A9AE", }, displayItem: { - background: "#474747", - borderColor: "#474747", + background: "#282828", + borderColor: "#282828", descriptionText: "#a3a9ae", }, }, From 0b0ba31920ec9176c34fca2664ac0ada366a3c63 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 16:50:00 +0300 Subject: [PATCH 067/126] code cleanup --- .../dialogs/CreateEditRoomDialog/sub-components/RoomType.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js index 5bbde85009..c701a6c281 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomType.js @@ -108,8 +108,6 @@ const StyledListItem = styled(StyledRoomType)` props.theme.createEditRoomDialog.roomType.listItem.hoverBackground}; } - ${(props) => console.log(props.accentColor)} - &:active { border-color: ${({ accentColor }) => accentColor}; } @@ -141,8 +139,6 @@ const StyledDropdownButton = styled(StyledRoomType)` ? accentColor : theme.createEditRoomDialog.roomType.dropdownButton.borderColor}; - ${(props) => console.log(props.accentColor)} - &:active { border-color: ${({ accentColor }) => accentColor}; } From 22fb66b76aab526ef09326e694d5ef4e9ffc1ff0 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 17:11:04 +0300 Subject: [PATCH 068/126] fixed FormGallery SortFilter icon not centered --- .../src/pages/FormGallery/Filter/SortFilter/index.styled.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js index 2ccfb87496..c4a58858b8 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -31,6 +31,7 @@ import { ComboBox } from "@docspace/shared/components/combobox"; export const SortButton = styled.div` .combo-button { + padding-right: 4px; background: ${(props) => props.theme.filterInput.sort.background} !important; @@ -67,6 +68,7 @@ export const SortButton = styled.div` align-items: center; justify-content: center; margin: 0; + padding: 0 16px; } .combo-buttons_arrow-icon { From 9ae31db1e9677016b7996ce0685356cc2a7984d6 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 27 May 2024 17:12:29 +0300 Subject: [PATCH 069/126] fixed FormGallery CategoryFilter unable to select category on screen size > 100% --- .../Filter/CategoryFilter/DesktopView/index.styled.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index a6fe0f74e4..4d0f1e3ab7 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -127,14 +127,14 @@ export const CategoryFilterSubList = styled(DropDown)` ${({ theme }) => theme.interfaceDirection !== "rtl" ? css` - left: -5px; + left: -4px; ` : css` - right: -5px; + right: -4px; `}; top: 0; - width: 4px; + width: 6px; height: 100%; } `; From 94d65b63b9c9acba68e9956acca5a392f6acbc42 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 27 May 2024 17:22:08 +0300 Subject: [PATCH 070/126] Shared:Components:Selector: add buttons for empty screen --- .../components/selector/Selector.styled.ts | 30 ++++++++++++ .../components/selector/Selector.types.ts | 4 ++ .../selector/sub-components/Body.tsx | 14 +++++- .../selector/sub-components/EmptyScreen.tsx | 47 +++++++++++++++++++ .../selector/sub-components/InputItem.tsx | 3 -- .../selector/sub-components/Item.tsx | 9 +++- packages/shared/themes/base.ts | 4 ++ packages/shared/themes/dark.ts | 3 ++ 8 files changed, 108 insertions(+), 6 deletions(-) diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index 17458f8d43..ae9043b775 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -272,6 +272,36 @@ const StyledEmptyScreen = styled.div<{ withSearch: boolean }>` box-sizing: border-box; + .buttons { + margin-top: 32px; + + display: flex; + gap: 16px; + align-items: center; + justify-content: center; + + .empty-folder_container-links { + display: flex; + align-items: center; + gap: 8px; + + .empty-folder_link { + color: ${(props) => props.theme.selector.emptyScreen.buttonColor}; + } + + &:hover { + .empty-folder_link { + color: ${(props) => + props.theme.selector.emptyScreen.hoverButtonColor}; + } + + svg path { + fill: ${(props) => props.theme.selector.emptyScreen.hoverButtonColor}; + } + } + } + } + .empty-image { max-width: 72px; max-height: 72px; diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts index a5b249e4b3..e7e06269b1 100644 --- a/packages/shared/components/selector/Selector.types.ts +++ b/packages/shared/components/selector/Selector.types.ts @@ -171,6 +171,8 @@ export interface EmptyScreenProps { searchHeader: string; searchDescription: string; withSearch: boolean; + + items: TSelectorItem[]; } type TSelectorEmptyScreen = { @@ -414,6 +416,7 @@ type TSelectorItemEmpty = { name?: undefined; isCreateNewItem?: undefined; onCreateClick?: undefined; + onBackClick?: undefined; isInputItem?: undefined; defaultInputValue?: undefined; onAcceptInput?: undefined; @@ -492,6 +495,7 @@ export type TSelectorItemNew = MergeTypes< { isCreateNewItem: boolean; onCreateClick: VoidFunction; + onBackClick: VoidFunction; } >; diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index 32e5ef516b..273fbcdefa 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -109,7 +109,16 @@ const Body = ({ const bodyRef = React.useRef(null); const listOptionsRef = React.useRef(null); - const itemsCount = hasNextPage ? items.length + 1 : items.length; + const isEmptyInput = + items.length === 2 && items[1].isInputItem && items[0].isCreateNewItem; + + const itemsCount = hasNextPage + ? items.length + 1 + : items.length === 1 && items[0].isCreateNewItem + ? 0 + : isEmptyInput + ? 1 + : items.length; const resetCache = React.useCallback(() => { if (listOptionsRef && listOptionsRef.current) { @@ -230,6 +239,7 @@ const Body = ({ searchImage={searchEmptyScreenImage} searchHeader={searchEmptyScreenHeader} searchDescription={searchEmptyScreenDescription} + items={items} /> ) : ( <> @@ -265,7 +275,7 @@ const Body = ({ width="100%" itemCount={itemsCount} itemData={{ - items, + items: isEmptyInput ? [items[1]] : items, onSelect, isMultiSelect: isMultiSelect || false, rowLoader, diff --git a/packages/shared/components/selector/sub-components/EmptyScreen.tsx b/packages/shared/components/selector/sub-components/EmptyScreen.tsx index 116cb579dd..0c73163a7e 100644 --- a/packages/shared/components/selector/sub-components/EmptyScreen.tsx +++ b/packages/shared/components/selector/sub-components/EmptyScreen.tsx @@ -25,13 +25,27 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import React from "react"; +import { useTranslation } from "react-i18next"; + +import PlusSvgUrl from "PUBLIC_DIR/images/plus.svg?url"; +import UpSvgUrl from "PUBLIC_DIR/images/up.svg?url"; import { Heading } from "../../heading"; import { Text } from "../../text"; +import { IconButton } from "../../icon-button"; +import { Link, LinkType } from "../../link"; import { StyledEmptyScreen } from "../Selector.styled"; import { EmptyScreenProps } from "../Selector.types"; +const linkStyles = { + isHovered: true, + type: LinkType.action, + fontWeight: "600", + className: "empty-folder_link", + display: "flex", +}; + const EmptyScreen = ({ image, header, @@ -40,11 +54,16 @@ const EmptyScreen = ({ searchHeader, searchDescription, withSearch, + items, }: EmptyScreenProps) => { + const { t } = useTranslation(["Common"]); + const currentImage = withSearch ? searchImage : image; const currentHeader = withSearch ? searchHeader : header; const currentDescription = withSearch ? searchDescription : description; + const createItem = items.length > 0 ? items[0] : null; + return ( empty-screen @@ -56,6 +75,34 @@ const EmptyScreen = ({ {currentDescription} + {createItem && ( +
+
+ + + {items[0].label} + +
+
+ + + {t("Common:Back")} + +
+
+ )} ); }; diff --git a/packages/shared/components/selector/sub-components/InputItem.tsx b/packages/shared/components/selector/sub-components/InputItem.tsx index 4eafb3378d..5d9f90a1be 100644 --- a/packages/shared/components/selector/sub-components/InputItem.tsx +++ b/packages/shared/components/selector/sub-components/InputItem.tsx @@ -79,9 +79,6 @@ const InputItem = ({ React.useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { - e.preventDefault(); - e.stopPropagation(); - if (e.key === "Enter") onAcceptInputAction(); else if (e.key === "Escape") onCancelInput(); }; diff --git a/packages/shared/components/selector/sub-components/Item.tsx b/packages/shared/components/selector/sub-components/Item.tsx index 35b3e77090..30a38fba1c 100644 --- a/packages/shared/components/selector/sub-components/Item.tsx +++ b/packages/shared/components/selector/sub-components/Item.tsx @@ -86,6 +86,7 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { label, isCreateNewItem, onCreateClick, + isInputItem, defaultInputValue, onAcceptInput, @@ -115,11 +116,17 @@ const Item = React.memo(({ index, style, data }: ItemProps) => { ); } - if (isCreateNewItem) { + if ( + isCreateNewItem && + (items.length > 2 || (items.length === 2 && !items[1].isInputItem)) + ) { return ( ); } + if (isCreateNewItem) { + return null; + } const showPlanetIcon = (item.roomType === RoomsType.PublicRoom || diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index 94d30def2a..31d8aeafc9 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -2398,6 +2398,10 @@ export const getBaseTheme = () => { emptyScreen: { descriptionColor: cyanBlueDarkShade, + + buttonColor: "#657077", + hoverButtonColor: "#333333", + pressedButtonColor: "#555F65", }, }, diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index f5b0f55f32..f0bd392c00 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -2377,6 +2377,9 @@ const Dark: TTheme = { emptyScreen: { descriptionColor: "#ADADAD", + buttonColor: "#ADADAD", + hoverButtonColor: "#FFFFFF", + pressedButtonColor: "#CCCCCC", }, }, From 2eb8bda5277854bd9790449e8be513778f27412a Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 27 May 2024 17:24:07 +0300 Subject: [PATCH 071/126] Shared:Selectors:Files: add create folder and back to parent buttons for empty screen --- .../shared/selectors/Files/FilesSelector.types.ts | 5 +++-- .../shared/selectors/Files/hooks/useFilesHelper.ts | 12 ++++++++++++ .../shared/selectors/Files/hooks/useSocketHelper.ts | 10 +++++----- packages/shared/selectors/Files/index.tsx | 1 + 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/shared/selectors/Files/FilesSelector.types.ts b/packages/shared/selectors/Files/FilesSelector.types.ts index 30ac26bfa8..5b18d9d531 100644 --- a/packages/shared/selectors/Files/FilesSelector.types.ts +++ b/packages/shared/selectors/Files/FilesSelector.types.ts @@ -98,7 +98,7 @@ export type UseFilesHelpersProps = { setIsRoot: (value: boolean) => void; setIsInit: (value: boolean) => void; searchValue?: string; - disabledItems: string[] | number[]; + disabledItems: (string | number)[]; setSelectedItemSecurity: (value: TFileSecurity | TFolderSecurity) => void; isThirdParty: boolean; setSelectedTreeNode: (treeNode: TFolder) => void; @@ -121,6 +121,7 @@ export type UseFilesHelpersProps = { isInit: boolean; setIsFirstLoad: (value: boolean) => void; withCreateFolder: boolean; + setSelectedItemId: (value: number | string) => void; }; export type TSelectedFileInfo = { @@ -140,7 +141,7 @@ export type FilesSelectorProps = ( ) & { socketHelper: SocketIOHelper; socketSubscribers: Set; - disabledItems: string[] | number[]; + disabledItems: (string | number)[]; filterParam?: string; withoutBackButton: boolean; withBreadCrumbs: boolean; diff --git a/packages/shared/selectors/Files/hooks/useFilesHelper.ts b/packages/shared/selectors/Files/hooks/useFilesHelper.ts index 6f6dc2e4bd..a4c4c4f3e9 100644 --- a/packages/shared/selectors/Files/hooks/useFilesHelper.ts +++ b/packages/shared/selectors/Files/hooks/useFilesHelper.ts @@ -84,6 +84,7 @@ const useFilesHelper = ({ setIsInit, setIsFirstLoad, withCreateFolder, + setSelectedItemId, }: UseFilesHelpersProps) => { const { t } = useTranslation(["Common"]); @@ -388,6 +389,16 @@ const useFilesHelper = ({ id: "create-folder-item", key: "create-folder-item", onCreateClick: addInputItem, + onBackClick: () => { + setSelectedItemId(current.parentId); + setBreadCrumbs((val) => { + const newVal = [...val]; + + newVal.pop(); + + return newVal; + }); + }, }); } else { setTotal(total); @@ -465,6 +476,7 @@ const useFilesHelper = ({ setItems, setTotal, addInputItem, + setSelectedItemId, rootThirdPartyId, ], ); diff --git a/packages/shared/selectors/Files/hooks/useSocketHelper.ts b/packages/shared/selectors/Files/hooks/useSocketHelper.ts index 46057c9bfa..93a6349336 100644 --- a/packages/shared/selectors/Files/hooks/useSocketHelper.ts +++ b/packages/shared/selectors/Files/hooks/useSocketHelper.ts @@ -128,8 +128,8 @@ const useSocketHelper = ({ let idx = 0; - if (value[0].isInputItem) idx = 1; - if (value[1].isInputItem) idx = 2; + if (value[0]?.isInputItem) idx = 1; + if (value[1]?.isInputItem) idx = 2; newValue.splice(idx, 0, item); @@ -144,9 +144,9 @@ const useSocketHelper = ({ for (let i = 0; i < value.length - 1; i += 1) { if ( - !value[i].isFolder && - !value[i].isCreateNewItem && - !value[i].isInputItem + !value[i]?.isFolder && + !value[i]?.isCreateNewItem && + !value[i]?.isInputItem ) break; diff --git a/packages/shared/selectors/Files/index.tsx b/packages/shared/selectors/Files/index.tsx index 0886dbe53a..c301cf5fd3 100644 --- a/packages/shared/selectors/Files/index.tsx +++ b/packages/shared/selectors/Files/index.tsx @@ -293,6 +293,7 @@ const FilesSelector = ({ isInit, setIsInit, withCreateFolder, + setSelectedItemId, }); const onSelectAction = React.useCallback( From 2200c6fa0ee1e7b54ed8bbadeda04607cc1b8e8d Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Mon, 27 May 2024 17:24:22 +0300 Subject: [PATCH 072/126] Client:FilesSelector: fix disabled items --- packages/client/src/components/FilesSelector/index.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 0ce43b4598..b7ba7cc87e 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -56,7 +56,7 @@ import InfoPanelStore from "SRC_DIR/store/InfoPanelStore"; import { FilesSelectorProps } from "./FilesSelector.types"; import { getAcceptButtonLabel, getHeaderLabel, getIsDisabled } from "./utils"; -const disabledItems: (string | number)[] = []; +let disabledItems: (string | number)[] = []; const FilesSelectorWrapper = ({ isPanelVisible = false, @@ -177,6 +177,12 @@ const FilesSelectorWrapper = ({ [t], ); + React.useEffect(() => { + return () => { + disabledItems = []; + }; + }, []); + const onAccept = async ( selectedItemId: string | number | undefined, folderTitle: string, From 1b0d9975ed668d60890454b87a2235e0a4b20f79 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 18:13:47 +0300 Subject: [PATCH 073/126] Client: Components: NavMenu: Hiding the language change for the wizard. --- .../NavMenu/sub-components/header-unauth.js | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 9623331733..7b69d7db28 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -33,11 +33,10 @@ import { Base } from "@docspace/shared/themes"; import { mobile, getLogoUrl } from "@docspace/shared/utils"; import { WhiteLabelLogoType } from "@docspace/shared/enums"; import { LanguageCombobox } from "@docspace/shared/components/language-combobox"; -import { setCookie } from "@docspace/shared/utils/cookie"; -import { COOKIE_EXPIRATION_YEAR, LANGUAGE } from "@docspace/shared/constants"; -import i18n from "../../../i18n"; import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; +import i18n from "../../../i18n"; + const Header = styled.header` align-items: left; background-color: ${(props) => props.theme.header.backgroundColor}; @@ -123,14 +122,16 @@ const HeaderUnAuth = ({ )} - + {!wizardToken && ( + + )} ); }; From 2559048563ca873c01fd0ab53754e50bf83773ba Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Mon, 27 May 2024 18:16:21 +0300 Subject: [PATCH 074/126] Shared: Utils: Refactoring. --- packages/shared/utils/common.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts index 942d2d8406..00b84cdb24 100644 --- a/packages/shared/utils/common.ts +++ b/packages/shared/utils/common.ts @@ -1088,6 +1088,8 @@ export function setLanguageForUnauthorized(culture: string) { "max-age": COOKIE_EXPIRATION_YEAR, }); + if (!window) return; + const url = new URL(window.location.href); const prevCulture = url.searchParams.get("culture"); From 6263c9456320f4924fa1a7e2e13bf4650a5cf925 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Tue, 28 May 2024 10:24:23 +0300 Subject: [PATCH 075/126] Shared:Selectors:Files: fix socket add item --- packages/shared/selectors/Files/hooks/useSocketHelper.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/shared/selectors/Files/hooks/useSocketHelper.ts b/packages/shared/selectors/Files/hooks/useSocketHelper.ts index 93a6349336..c214eba473 100644 --- a/packages/shared/selectors/Files/hooks/useSocketHelper.ts +++ b/packages/shared/selectors/Files/hooks/useSocketHelper.ts @@ -126,9 +126,8 @@ const useSocketHelper = ({ if (withCreateFolder) { const newValue = [...value]; - let idx = 0; + let idx = 1; - if (value[0]?.isInputItem) idx = 1; if (value[1]?.isInputItem) idx = 2; newValue.splice(idx, 0, item); From 61b00dd53cad49b4e13ca0a8ed491b72b9f1302c Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 28 May 2024 10:54:49 +0300 Subject: [PATCH 076/126] Web: Hotkeys: fixed scroll focus --- packages/client/src/store/AccountsHotkeysStore.ts | 6 +++++- packages/client/src/store/HotkeyStore.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/client/src/store/AccountsHotkeysStore.ts b/packages/client/src/store/AccountsHotkeysStore.ts index 3dd09f6551..33cf0b9299 100644 --- a/packages/client/src/store/AccountsHotkeysStore.ts +++ b/packages/client/src/store/AccountsHotkeysStore.ts @@ -255,7 +255,11 @@ class AccountsHotkeysStore { const scroll = document.getElementsByClassName( "section-scroll", ) as HTMLCollectionOf; - if (scroll && scroll[0]) scroll[0].focus(); + + if (scroll && scroll[0]) { + const scrollElem = scroll[0]?.firstChild as HTMLElement; + scrollElem?.focus(); + } } if (!this.hotkeyCaret && selection.length) { diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index 705746e7cd..083f66bc35 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -135,7 +135,7 @@ class HotkeyStore { if (!hotkeyCaret) { const scroll = document.getElementsByClassName("section-scroll"); - scroll && scroll[0] && scroll[0].focus(); + scroll && scroll[0] && scroll[0]?.firstChild.focus(); } if (!hotkeyCaret && selection.length) { From a9fbd7499356f69a6b30bb76f396c8633e93424d Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Tue, 28 May 2024 11:06:44 +0300 Subject: [PATCH 077/126] Shared:Components:Selector: add click by label for create item --- packages/shared/components/selector/Selector.styled.ts | 5 +++++ .../shared/components/selector/sub-components/NewItem.tsx | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/shared/components/selector/Selector.styled.ts b/packages/shared/components/selector/Selector.styled.ts index ae9043b775..3b324c17d8 100644 --- a/packages/shared/components/selector/Selector.styled.ts +++ b/packages/shared/components/selector/Selector.styled.ts @@ -222,6 +222,11 @@ const StyledItem = styled.div<{ `} } + .clicked-label { + width: fit-content; + cursor: pointer; + } + .input-component { margin-inline-start: 8px; } diff --git a/packages/shared/components/selector/sub-components/NewItem.tsx b/packages/shared/components/selector/sub-components/NewItem.tsx index e396cf56c2..f4ff2d8f85 100644 --- a/packages/shared/components/selector/sub-components/NewItem.tsx +++ b/packages/shared/components/selector/sub-components/NewItem.tsx @@ -50,12 +50,14 @@ const NewItem = ({ > {label} From dc3ca111b0df7f20382a40611fa2115d47fc087c Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Tue, 28 May 2024 12:09:20 +0300 Subject: [PATCH 078/126] Doceditor:Components:SelectFolderDialog: enable create folder --- packages/doceditor/src/components/SelectFileDialog.tsx | 1 + packages/doceditor/src/components/SelectFolderDialog.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/doceditor/src/components/SelectFileDialog.tsx b/packages/doceditor/src/components/SelectFileDialog.tsx index 51005e1893..62ae2d6295 100644 --- a/packages/doceditor/src/components/SelectFileDialog.tsx +++ b/packages/doceditor/src/components/SelectFileDialog.tsx @@ -110,6 +110,7 @@ const SelectFileDialog = ({ submitButtonId="select-file-modal-submit" cancelButtonId="select-file-modal-cancel" {...fileTypeDetection} + withCreateFolder={false} /> ); }; diff --git a/packages/doceditor/src/components/SelectFolderDialog.tsx b/packages/doceditor/src/components/SelectFolderDialog.tsx index 9153e19565..5eca552be6 100644 --- a/packages/doceditor/src/components/SelectFolderDialog.tsx +++ b/packages/doceditor/src/components/SelectFolderDialog.tsx @@ -92,6 +92,7 @@ const SelectFolderDialog = ({ getFilesArchiveError={() => ""} parentId={0} getIsDisabled={getIsDisabled} + withCreateFolder /> ); }; From 9253b3a120340fa7e091cb23992767e6ff08fe29 Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Tue, 28 May 2024 12:09:52 +0300 Subject: [PATCH 079/126] Fixed Bug 67431 - Mobile. Folder is not selected when selecting Folder Upload --- packages/client/src/store/ContextOptionsStore.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index 17c031f489..fd3bf6a73b 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -2051,6 +2051,7 @@ class ContextOptionsStore { ], }; + const showUploadFolder = !(isMobile || isTablet); const moreActions = { id: "personal_more-form", className: "main-button_drop-down", @@ -2072,7 +2073,7 @@ class ContextOptionsStore { key: "personal_more-form__separator-2", }, uploadFiles, - uploadFolder, + showUploadFolder ? uploadFolder : null, ], }; @@ -2321,6 +2322,7 @@ class ContextOptionsStore { ] : [createTemplateForm, createTemplateNewFormFile, templateOformsGallery]; + const showUploadFolder = !(isMobile || isTablet); const options = isRoomsFolder ? [ { @@ -2338,7 +2340,7 @@ class ContextOptionsStore { createNewFolder, { key: "separator", isSeparator: true }, uploadFiles, - uploadFolder, + showUploadFolder ? uploadFolder : null, ]; if (mainButtonItemsList && enablePlugins) { From 843b1c5541ea687dfe15d0d1cd04f27e9da73fa7 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Tue, 28 May 2024 14:23:41 +0500 Subject: [PATCH 080/126] Web: Client: Data Import: fixed breakpoint warning --- .../categories/data-import/GoogleWorkspace/index.js | 7 +++++-- .../categories/data-import/NextCloudWorkspace/index.js | 3 ++- .../categories/data-import/OnlyofficeWorkspace/index.js | 7 +++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js index 19bfe6831e..74713aa0c7 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/index.js @@ -28,7 +28,10 @@ import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import { Trans, withTranslation } from "react-i18next"; import { getStepTitle, getGoogleStepDescription } from "../../../utils"; -import { tablet } from "@docspace/shared/utils/device"; +import { + tablet, + isMobile as isMobileBreakpoint, +} from "@docspace/shared/utils/device"; import { isMobile } from "react-device-detect"; import useViewEffect from "SRC_DIR/Hooks/useViewEffect"; @@ -215,7 +218,7 @@ const GoogleWorkspace = ({ return clearCheckedAccounts; }, []); - if (isMobile) + if (isMobile || isMobileBreakpoint()) return ( { return clearCheckedAccounts; }, []); - if (isMobile) + if (isMobile || isMobileBreakpoint()) return ( Date: Fri, 24 May 2024 13:31:56 +0200 Subject: [PATCH 081/126] Shared: PeopleSelector: Fix infinite loading --- packages/shared/selectors/People/index.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/shared/selectors/People/index.tsx b/packages/shared/selectors/People/index.tsx index be6b82f925..aeccbf85ce 100644 --- a/packages/shared/selectors/People/index.tsx +++ b/packages/shared/selectors/People/index.tsx @@ -153,7 +153,7 @@ const PeopleSelector = ({ const [hasNextPage, setHasNextPage] = useState(true); const [isNextPageLoading, setIsNextPageLoading] = useState(false); const [selectedItem, setSelectedItem] = useState(null); - const isFirstLoad = useRef(true); + const isFirstLoadRef = useRef(true); const afterSearch = useRef(false); const totalRef = useRef(0); @@ -234,7 +234,7 @@ const PeopleSelector = ({ ? response.total - totalDifferent - 1 : response.total - totalDifferent; - if (isFirstLoad) { + if (isFirstLoadRef.current) { const newItems = withOutCurrentAuthorizedUser ? removeCurrentUserFromList(data) : moveCurrentUserToTopOfList(data); @@ -259,7 +259,7 @@ const PeopleSelector = ({ totalRef.current = newTotal; setIsNextPageLoading(false); - isFirstLoad.current = false; + isFirstLoadRef.current = false; }, [ disableDisabledUsers, @@ -275,7 +275,7 @@ const PeopleSelector = ({ ); const onSearch = useCallback((value: string, callback?: Function) => { - isFirstLoad.current = true; + isFirstLoadRef.current = true; afterSearch.current = true; setSearchValue(() => { return value; @@ -284,7 +284,7 @@ const PeopleSelector = ({ }, []); const onClearSearch = useCallback((callback?: Function) => { - isFirstLoad.current = true; + isFirstLoadRef.current = true; afterSearch.current = true; setSearchValue(() => { return ""; @@ -322,7 +322,7 @@ const PeopleSelector = ({ onClearSearch, searchLoader: , isSearchLoading: - isFirstLoad.current && !searchValue && !afterSearch.current, + isFirstLoadRef.current && !searchValue && !afterSearch.current, }; const infoProps: TSelectorInfo = withInfo @@ -406,9 +406,9 @@ const PeopleSelector = ({ loadNextPage={loadNextPage} isMultiSelect={isMultiSelect ?? false} totalItems={total} - isLoading={isFirstLoad.current} + isLoading={isFirstLoadRef.current} searchLoader={} - rowLoader={} + rowLoader={} onSelect={onSelect} {...infoProps} /> From 5b6d3910607da5efd283e46bf4fddebd6699ec42 Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Fri, 24 May 2024 15:47:58 +0200 Subject: [PATCH 082/126] Shared: Selector: Fix duplicate request --- .../components/selector/sub-components/Body.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index f79d4762b0..a6ebebe02c 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -129,6 +129,16 @@ const Body = ({ [hasNextPage, itemsCount], ); + const onLoadMoreItems = React.useCallback( + (startIndex: number) => { + // first page loads in selector's useEffect + if (startIndex === 1) return; + + loadMoreItems(startIndex); + }, + [loadMoreItems], + ); + React.useEffect(() => { window.addEventListener("resize", onBodyResize); @@ -250,7 +260,7 @@ const Body = ({ ref={listOptionsRef} isItemLoaded={isItemLoaded} itemCount={totalItems} - loadMoreItems={loadMoreItems} + loadMoreItems={onLoadMoreItems} > {({ onItemsRendered, ref }) => ( Date: Mon, 27 May 2024 18:45:43 +0200 Subject: [PATCH 083/126] Client: Members: Fix infinite loading and duplicate members after inviting users. Remove useless code --- .../components/panels/InvitePanel/index.js | 38 +++--------- .../InfoPanel/Body/views/Members/index.js | 39 ++++-------- packages/client/src/store/InfoPanelStore.js | 59 ++++++++----------- 3 files changed, 45 insertions(+), 91 deletions(-) diff --git a/packages/client/src/components/panels/InvitePanel/index.js b/packages/client/src/components/panels/InvitePanel/index.js index 0f5d0e125d..8799b4de81 100644 --- a/packages/client/src/components/panels/InvitePanel/index.js +++ b/packages/client/src/components/panels/InvitePanel/index.js @@ -80,8 +80,8 @@ const InvitePanel = ({ defaultAccess, inviteUsers, setInfoPanelIsMobileHidden, - updateInfoPanelSelection, - addInfoPanelMembers, + updateInfoPanelMembers, + isRoomMembersPanelOpen, setInviteLanguage, getUsersList, filter, @@ -291,28 +291,6 @@ const InvitePanel = ({ setIsLoading(false); - const invitedViaEmail = data.invitations - .filter((inv) => inv.email && !inv.id) - .map((invitation) => ({ - access: invitation.access, - sharedTo: { - name: invitation.email, - userName: invitation.email, - email: invitation.email, - displayName: invitation.email, - status: 1, - activationStatus: 2, - usedSpace: 0, - hasAvatar: false, - }, - canEditAccess: false, - })); - - if (isRooms) { - const newInfoPanelMembers = [...result.members, ...invitedViaEmail]; - addInfoPanelMembers(t, newInfoPanelMembers); - } - onClose(); toastr.success(t("Common:UsersInvited")); @@ -320,7 +298,9 @@ const InvitePanel = ({ toastr.warning(result?.warning); } - updateInfoPanelSelection(); + if (isRoomMembersPanelOpen) { + updateInfoPanelMembers(t); + } } catch (err) { toastr.error(err); setIsLoading(false); @@ -503,8 +483,8 @@ export default inject( const { filter } = peopleStore.filterStore; const { setIsMobileHidden: setInfoPanelIsMobileHidden, - updateInfoPanelSelection, - addInfoPanelMembers, + updateInfoPanelMembers, + isRoomMembersPanelOpen, } = infoPanelStore; const { @@ -547,8 +527,8 @@ export default inject( collaboratorLink, inviteUsers, setInfoPanelIsMobileHidden, - updateInfoPanelSelection, - addInfoPanelMembers, + updateInfoPanelMembers, + isRoomMembersPanelOpen, getUsersList, filter, currentDeviceType, diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js index 7c66ae2b6f..e1b397b483 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js @@ -65,7 +65,7 @@ const Members = ({ isPublicRoomType, membersFilter, infoPanelMembers, - setInfoPanelMembers, + updateInfoPanelMembers, primaryLink, isArchiveFolder, isPublicRoom, @@ -75,38 +75,24 @@ const Members = ({ getPrimaryLink, setExternalLink, withPublicRoomBlock, - fetchMembers, fetchMoreMembers, membersIsLoading, searchValue, - searchResultIsLoading, + isMembersPanelUpdating, }) => { const withoutTitlesAndLinks = !!searchValue; const membersHelper = new MembersHelper({ t }); const scrollContext = useContext(ScrollbarContext); - const updateInfoPanelMembers = async () => { - if ( - !infoPanelSelection || - !infoPanelSelection.isRoom || - !infoPanelSelection.id - ) { - return; - } - - const fetchedMembers = await fetchMembers(t, true, withoutTitlesAndLinks); - setInfoPanelMembers(fetchedMembers); - }; - useEffect(() => { - updateInfoPanelMembers(); + updateInfoPanelMembers(t); }, [infoPanelSelection, searchValue]); useEffect(() => { - if (searchResultIsLoading) return; + if (isMembersPanelUpdating) return; scrollContext?.parentScrollbar?.scrollToTop(); - }, [searchResultIsLoading]); + }, [isMembersPanelUpdating]); const loadNextPage = async () => { await fetchMoreMembers(t, withoutTitlesAndLinks); @@ -259,8 +245,8 @@ const Members = ({ @@ -303,13 +290,12 @@ export default inject( infoPanelSelection, setIsScrollLocked, infoPanelMembers, - setInfoPanelMembers, - fetchMembers, + updateInfoPanelMembers, fetchMoreMembers, membersIsLoading, withPublicRoomBlock, searchValue, - searchResultIsLoading, + isMembersPanelUpdating, } = infoPanelStore; const { membersFilter } = filesStore; const { id: selfId, isAdmin } = userStore.user; @@ -337,7 +323,7 @@ export default inject( isPublicRoomType, membersFilter, infoPanelMembers, - setInfoPanelMembers, + updateInfoPanelMembers, roomType, primaryLink, isArchiveFolder: isArchiveFolderRoot, @@ -348,11 +334,10 @@ export default inject( getPrimaryLink: filesStore.getPrimaryLink, setExternalLink, withPublicRoomBlock, - fetchMembers, fetchMoreMembers, membersIsLoading, searchValue, - searchResultIsLoading, + isMembersPanelUpdating, }; }, )( diff --git a/packages/client/src/store/InfoPanelStore.js b/packages/client/src/store/InfoPanelStore.js index 18e33461f0..44fc55c9c5 100644 --- a/packages/client/src/store/InfoPanelStore.js +++ b/packages/client/src/store/InfoPanelStore.js @@ -88,7 +88,7 @@ class InfoPanelStore { infoPanelSelection = null; infoPanelRoom = null; membersIsLoading = false; - searchResultIsLoading = false; + isMembersPanelUpdating = false; shareChanged = false; @@ -128,15 +128,8 @@ class InfoPanelStore { setShowSearchBlock = (bool) => (this.showSearchBlock = bool); - setSearchResultIsLoading = (isLoading) => { - this.searchResultIsLoading = isLoading; - }; - setSearchValue = (value) => { - if (value !== this.searchValue) { - this.setSearchResultIsLoading(true); - this.searchValue = value; - } + this.searchValue = value; }; resetSearch = () => { @@ -171,6 +164,10 @@ class InfoPanelStore { this.isScrollLocked = isScrollLocked; }; + setIsMembersPanelUpdating = (isMembersPanelUpdating) => { + this.isMembersPanelUpdating = isMembersPanelUpdating; + }; + // Selection helpers // get infoPanelSelectedItems() { @@ -231,6 +228,10 @@ class InfoPanelStore { : null; } + get isRoomMembersPanelOpen() { + return this.infoPanelSelection?.isRoom && this.roomsView === infoMembers; + } + get withPublicRoomBlock() { return ( this.infoPanelCurrentSelection?.access === @@ -643,7 +644,6 @@ class InfoPanelStore { const [data, links] = await Promise.all(requests); clearFilter && this.setMembersIsLoading(false); clearTimeout(timerId); - this.setSearchResultIsLoading(false); links && this.publicRoomStore.setExternalLinks(links); @@ -691,32 +691,21 @@ class InfoPanelStore { this.setInfoPanelMembers(mergedMembers); }; - addInfoPanelMembers = (t, members) => { - const convertedMembers = this.convertMembers(t, members); - - if (this.infoPanelMembers) { - const { roomId, administrators, users, expected, groups } = - this.infoPanelMembers; - - const mergedMembers = { - roomId: roomId, - administrators: [...administrators, ...convertedMembers.administrators], - users: [...users, ...convertedMembers.users], - expected: [...expected, ...convertedMembers.expectedMembers], - groups: [...groups, ...convertedMembers.groups], - }; - - this.addMembersTitle( - t, - mergedMembers.administrators, - mergedMembers.users, - mergedMembers.expected, - mergedMembers.groups, - ); - - this.filesStore.setInRoomFolder(roomId, true); - this.setInfoPanelMembers(mergedMembers); + updateInfoPanelMembers = async (t) => { + if ( + !this.infoPanelSelection || + !this.infoPanelSelection.isRoom || + !this.infoPanelSelection.id + ) { + return; } + + this.setIsMembersPanelUpdating(true); + + const fetchedMembers = await this.fetchMembers(t, true, !!this.searchValue); + this.setInfoPanelMembers(fetchedMembers); + + this.setIsMembersPanelUpdating(false); }; openShareTab = () => { From 5fa18224d2f76fefa8fa41b88f6c04e7b84ac2d8 Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Tue, 28 May 2024 11:14:04 +0200 Subject: [PATCH 084/126] Shared: Selector: Fix scrolled content after changing tab --- .../shared/components/scrollbar/Scrollbar.types.ts | 2 +- .../components/scrollbar/sub-components/index.tsx | 2 ++ .../shared/components/selector/sub-components/Body.tsx | 10 ++++++++++ .../selector/sub-components/VirtualScroll.tsx | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/shared/components/scrollbar/Scrollbar.types.ts b/packages/shared/components/scrollbar/Scrollbar.types.ts index 89a27f3d4a..a89f0254ee 100644 --- a/packages/shared/components/scrollbar/Scrollbar.types.ts +++ b/packages/shared/components/scrollbar/Scrollbar.types.ts @@ -54,7 +54,7 @@ export type ScrollbarProps = { export type CustomScrollbarsVirtualListProps = Pick< ScrollbarProps, - "style" | "onScroll" | "children" | "className" | "autoFocus" + "style" | "onScroll" | "children" | "className" | "autoFocus" | "scrollClass" > & { forwardedRef?: React.ForwardedRef; contentRef?: React.MutableRefObject; diff --git a/packages/shared/components/scrollbar/sub-components/index.tsx b/packages/shared/components/scrollbar/sub-components/index.tsx index 81dabe0f0a..871d122067 100644 --- a/packages/shared/components/scrollbar/sub-components/index.tsx +++ b/packages/shared/components/scrollbar/sub-components/index.tsx @@ -38,6 +38,7 @@ const CustomScrollbars = ({ className, contentRef, autoFocus, + scrollClass, }: CustomScrollbarsVirtualListProps) => { const refSetter = ( scrollbarsRef: React.RefObject, @@ -66,6 +67,7 @@ const CustomScrollbars = ({ onScroll={onScroll} className={className} autoFocus={autoFocus} + scrollClass={scrollClass} > {children}
diff --git a/packages/shared/components/selector/sub-components/Body.tsx b/packages/shared/components/selector/sub-components/Body.tsx index a6ebebe02c..e9123138f7 100644 --- a/packages/shared/components/selector/sub-components/Body.tsx +++ b/packages/shared/components/selector/sub-components/Body.tsx @@ -155,6 +155,16 @@ const Body = ({ resetCache(); }, [resetCache, hasNextPage]); + // scroll to top after changing tab + React.useEffect(() => { + if (!withTabs) return; + const scrollElement = document.querySelector(".selector-body-scroll"); + + if (scrollElement) { + scrollElement.scrollTo(0, 0); + } + }, [withTabs, activeTabId]); + let listHeight = bodyHeight - CONTAINER_PADDING; if (withSearch || isSearch || itemsCount > 0) listHeight -= SEARCH_HEIGHT; diff --git a/packages/shared/components/selector/sub-components/VirtualScroll.tsx b/packages/shared/components/selector/sub-components/VirtualScroll.tsx index a9f001cd05..9d096e0387 100644 --- a/packages/shared/components/selector/sub-components/VirtualScroll.tsx +++ b/packages/shared/components/selector/sub-components/VirtualScroll.tsx @@ -43,6 +43,7 @@ export const VirtualScroll = forwardRef((props, ref) => { return ( From 5513c48f4e9030a5a30000474623dd217314d976 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Tue, 28 May 2024 14:31:28 +0500 Subject: [PATCH 085/126] Web: Client: Settings: fixed arrow button shrink --- .../src/pages/PortalSettings/Layout/Section/Header/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js b/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js index ed46f7e9e9..a581e5ee13 100644 --- a/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js +++ b/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js @@ -94,6 +94,8 @@ const HeaderContainer = styled.div` } .arrow-button { + flex-shrink: 0; + ${(props) => props.theme.interfaceDirection === "rtl" ? css` From 4da2a3d95da0e26ba6d29b7c6eaaa766bbb7707f Mon Sep 17 00:00:00 2001 From: Elyor Djalilov Date: Tue, 28 May 2024 14:54:15 +0500 Subject: [PATCH 086/126] Web: Client: Profile: ActiveSessions. removed extra comma in row view --- .../SessionsTable/RowView/SessionsRowContent.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/Profile/Section/Body/sub-components/active-session/SessionsTable/RowView/SessionsRowContent.js b/packages/client/src/pages/Profile/Section/Body/sub-components/active-session/SessionsTable/RowView/SessionsRowContent.js index dc39f35d65..03652a24e1 100644 --- a/packages/client/src/pages/Profile/Section/Body/sub-components/active-session/SessionsTable/RowView/SessionsRowContent.js +++ b/packages/client/src/pages/Profile/Section/Body/sub-components/active-session/SessionsTable/RowView/SessionsRowContent.js @@ -70,10 +70,9 @@ const SessionsRowContent = ({ )} {convertTime(date)} {(country || city) && ( - + {country} - {country && city && ", "} - {city} + {country && city && ` ${city}`} )} From 27c15949817bbed8ff89ce3ece51af536e2a2dc1 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Tue, 28 May 2024 16:23:13 +0500 Subject: [PATCH 087/126] Web: Client: Data Import: throw error on multiple files select --- .../NextCloudWorkspace/Stepper/SelectFileStep/index.js | 1 + .../OnlyofficeWorkspace/Stepper/SelectFileStep/index.js | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js index a44433f408..d6847a46ee 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js @@ -191,6 +191,7 @@ const SelectFileStep = ({ setProgress(0); setIsVisible(true); try { + if (Array.isArray(file)) throw new Error(t("Common:SomethingWentWrong")); await singleFileUploading(file, setProgress, isAbort); await initMigrationName(searchParams.get("service")); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js index 9d7cf46a5d..46acf6e380 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js @@ -181,6 +181,7 @@ const SelectFileStep = ({ setProgress(0); setIsVisible(true); try { + if (Array.isArray(file)) throw new Error(t("Common:SomethingWentWrong")); await singleFileUploading(file, setProgress, isAbort); await initMigrationName(searchParams.get("service")); From 6b3a20efd4ff063f45ba6e583f5f74168ff276c2 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Tue, 28 May 2024 16:07:17 +0300 Subject: [PATCH 088/126] Shared: Components: DropDown: Fixed incorrect width calculation for dark theme. --- packages/shared/components/drop-down/DropDown.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/shared/components/drop-down/DropDown.tsx b/packages/shared/components/drop-down/DropDown.tsx index 1cbef7033a..d6d0095260 100644 --- a/packages/shared/components/drop-down/DropDown.tsx +++ b/packages/shared/components/drop-down/DropDown.tsx @@ -84,7 +84,6 @@ const DropDown = ({ directionY, manualY, width: 0, - borderOffset: theme?.isBase ? 0 : 2, // need to remove the difference in width with the parent in a dark theme isDropdownReady: false, // need to avoid scrollbar appearing during dropdown position calculation }); @@ -169,9 +168,7 @@ const DropDown = ({ ...s, directionX, directionY, - width: dropDownRef.current - ? dropDownRef.current.offsetWidth - state.borderOffset - : 240, + width: dropDownRef.current ? dropDownRef.current.offsetWidth : 240, isDropdownReady: true, })); }, [ @@ -181,7 +178,6 @@ const DropDown = ({ forwardedRef, offsetLeft, right, - state.borderOffset, theme?.interfaceDirection, top, ]); @@ -255,9 +251,7 @@ const DropDown = ({ directionX: x, directionY: y, manualY: mY, - width: dropDownRef.current - ? dropDownRef.current.offsetWidth - state.borderOffset - : 240, + width: dropDownRef.current ? dropDownRef.current.offsetWidth : 240, isDropdownReady: true, })); } @@ -269,7 +263,6 @@ const DropDown = ({ state.directionX, state.directionY, state.manualY, - state.borderOffset, ]); // const handleClickOutside = (e: any) => { From 10153170a13c4d5cca106a8068320c8ce8d17eae Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Tue, 28 May 2024 18:14:00 +0200 Subject: [PATCH 089/126] Client: Members: Fix infinite loading after removing member --- .../pages/Home/InfoPanel/Body/views/Members/User.js | 13 ++++++++++++- packages/client/src/store/InfoPanelStore.js | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js index 48a2038231..9b0be80cf4 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js @@ -144,11 +144,19 @@ const User = ({ newMembersFilter.total -= 1; if (hasNextPage) { + const oldStartIndex = newMembersFilter.startIndex; + const oldPageCount = newMembersFilter.pageCount; + newMembersFilter.startIndex = (newMembersFilter.page + 1) * newMembersFilter.pageCount - 1; newMembersFilter.pageCount = 1; - const fetchedMembers = await fetchMembers(t, false); + const fetchedMembers = await fetchMembers( + t, + false, + withoutTitles, + newMembersFilter, + ); const newMembers = { administrators: [ @@ -164,6 +172,9 @@ const User = ({ roomId: infoPanelSelection.id, ...newMembers, }); + + newMembersFilter.startIndex = oldStartIndex; + newMembersFilter.pageCount = oldPageCount; } setMembersFilter(newMembersFilter); diff --git a/packages/client/src/store/InfoPanelStore.js b/packages/client/src/store/InfoPanelStore.js index 44fc55c9c5..b47a773d33 100644 --- a/packages/client/src/store/InfoPanelStore.js +++ b/packages/client/src/store/InfoPanelStore.js @@ -619,6 +619,7 @@ class InfoPanelStore { t, clearFilter = true, withoutTitlesAndLinks = false, + membersFilter, ) => { if (this.membersIsLoading) return; const roomId = this.infoPanelSelection.id; @@ -626,7 +627,9 @@ class InfoPanelStore { const isPublic = this.infoPanelSelection?.roomType ?? this.infoPanelSelection?.roomType; - const requests = [this.filesStore.getRoomMembers(roomId, clearFilter)]; + const requests = [ + this.filesStore.getRoomMembers(roomId, clearFilter, membersFilter), + ]; if ( isPublic && From 355523f8dea7de80db1e9a1fd027a303b647475e Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Tue, 28 May 2024 19:41:20 +0200 Subject: [PATCH 090/126] Client: AddUsersPanel: Fix infinite loading after empty search --- .../client/src/components/panels/AddUsersPanel/index.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/panels/AddUsersPanel/index.tsx b/packages/client/src/components/panels/AddUsersPanel/index.tsx index 917c794905..d7afdfa0d6 100644 --- a/packages/client/src/components/panels/AddUsersPanel/index.tsx +++ b/packages/client/src/components/panels/AddUsersPanel/index.tsx @@ -321,8 +321,11 @@ const AddUsersPanel = ({ const onClearSearch = useCallback( (callback?: Function) => { isFirstLoad.current = true; - setIsLoading(true); - setSearchValue(() => { + setSearchValue((prevValue: string) => { + if (prevValue !== "") { + setIsLoading(true); + } + return ""; }); callback?.(); From 7bbccb4faf5c84bbe9abf4debe01895486ea30ab Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 29 May 2024 13:59:36 +0500 Subject: [PATCH 091/126] Web: Client: warning was hidden in DeleteProfileEverDialog if user type is visitor --- .../dialogs/DeleteProfileEverDialog/index.js | 3 +++ .../sub-components/BodyComponent.js | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js index 0fa5733baa..fd67d2568f 100644 --- a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js +++ b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js @@ -118,6 +118,8 @@ const DeleteProfileEverDialogComponent = (props) => { usersToDelete[0].isAdmin || usersToDelete[0].isCollaborator); + const areUsersOnly = usersToDelete.every((user) => user.isVisitor); + const onDeleteUser = (id) => { const filter = Filter.getDefault(); setIsRequestRunning(true); @@ -193,6 +195,7 @@ const DeleteProfileEverDialogComponent = (props) => { deleteWithoutReassign={deleteWithoutReassign} users={usersToDelete} onlyOneUser={onlyOneUser} + areUsersOnly={areUsersOnly} t={t} /> diff --git a/packages/client/src/components/dialogs/DeleteProfileEverDialog/sub-components/BodyComponent.js b/packages/client/src/components/dialogs/DeleteProfileEverDialog/sub-components/BodyComponent.js index 54a7c1da3e..0169f2b28c 100644 --- a/packages/client/src/components/dialogs/DeleteProfileEverDialog/sub-components/BodyComponent.js +++ b/packages/client/src/components/dialogs/DeleteProfileEverDialog/sub-components/BodyComponent.js @@ -40,6 +40,7 @@ const BodyComponent = (props) => { userPerformedDeletion, users, onlyOneUser, + areUsersOnly, } = props; const warningMessageMyDocuments = t("DeleteMyDocumentsUser"); @@ -87,8 +88,12 @@ const BodyComponent = (props) => { return ( <> {t("ActionCannotBeUndone")} - {t("Common:Warning")} - {warningMessage} + {!areUsersOnly && ( + <> + {t("Common:Warning")} + {warningMessage} + + )} ); } @@ -96,8 +101,12 @@ const BodyComponent = (props) => { return ( <> {deleteMessage} - {t("Common:Warning")} - {warningMessage} + {!areUsersOnly && ( + <> + {t("Common:Warning")} + {warningMessage} + + )} {needReassignData && ( Date: Wed, 29 May 2024 13:05:48 +0400 Subject: [PATCH 092/126] Translations: Fix WrongTranslationVariablesTest issue (CommonFilesDescription key) --- i18next/client.babel | 128 ++++++++++++++++++ .../client/public/locales/ar-SA/Settings.json | 2 +- .../client/public/locales/az/Settings.json | 2 +- .../client/public/locales/bg/Settings.json | 2 +- .../client/public/locales/cs/Settings.json | 2 +- .../client/public/locales/de/Settings.json | 2 +- .../client/public/locales/el-GR/Settings.json | 2 +- .../client/public/locales/es/Settings.json | 2 +- .../client/public/locales/fi/Settings.json | 2 +- .../client/public/locales/fr/Settings.json | 2 +- .../client/public/locales/hy-AM/Settings.json | 2 +- .../client/public/locales/it/Settings.json | 2 +- .../client/public/locales/ja-JP/Settings.json | 2 +- .../client/public/locales/ko-KR/Settings.json | 2 +- .../client/public/locales/lv/Settings.json | 2 +- .../client/public/locales/nl/Settings.json | 2 +- .../client/public/locales/pl/Settings.json | 2 +- .../client/public/locales/pt-BR/Settings.json | 2 +- .../client/public/locales/pt/Settings.json | 2 +- .../client/public/locales/ro/Settings.json | 2 +- .../client/public/locales/ru/Settings.json | 2 +- .../client/public/locales/si/Settings.json | 2 +- .../client/public/locales/sk/Settings.json | 2 +- .../client/public/locales/sl/Settings.json | 2 +- .../public/locales/sr-Latn-RS/Settings.json | 2 +- .../client/public/locales/tr/Settings.json | 2 +- .../client/public/locales/uk-UA/Settings.json | 2 +- .../client/public/locales/vi/Settings.json | 2 +- .../client/public/locales/zh-CN/Settings.json | 2 +- 29 files changed, 156 insertions(+), 28 deletions(-) diff --git a/i18next/client.babel b/i18next/client.babel index dab02cb038..c91cf41e6a 100644 --- a/i18next/client.babel +++ b/i18next/client.babel @@ -56364,6 +56364,134 @@ + + OpenSameTab + + + + + + ar-SA + false + + + az-Latn-AZ + false + + + bg-BG + false + + + cs-CZ + false + + + de-DE + false + + + el-GR + false + + + en-US + false + + + es-ES + false + + + fi-FI + false + + + fr-FR + false + + + hy-AM + false + + + it-IT + false + + + ja-JP + false + + + ko-KR + false + + + lo-LA + false + + + lv-LV + false + + + nl-NL + false + + + pl-PL + false + + + pt-BR + false + + + pt-PT + false + + + ro-RO + false + + + ru-RU + false + + + si-SI + false + + + sk-SK + false + + + sl-SI + false + + + sr-Latn-RS + false + + + tr-TR + false + + + uk-UA + false + + + vi-VN + false + + + zh-CN + false + + + OriginalCopy diff --git a/packages/client/public/locales/ar-SA/Settings.json b/packages/client/public/locales/ar-SA/Settings.json index d6763d0cac..3c5c25c641 100644 --- a/packages/client/public/locales/ar-SA/Settings.json +++ b/packages/client/public/locales/ar-SA/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "اختر ملفات النسخ الاحتياطي", "ClearBackupList": "احذف جميع النسخ الاحتياطية", "CloseMenu": "أغلاق القائمة", - "CommonFilesDescription": "بالنسبة للملفات الموجودة في القسم العام، سيتم إنشاء غرفة منفصلة (غرفة مشتركة). سيتمكن مسؤولو DocSpace فقط من الوصول إلى هذه الغرفة. بشكل افتراضي، سيكون مالك الغرفة هو المستخدم الذي يبدأ الاستيراد: John Smith (You).", + "CommonFilesDescription": "بالنسبة للملفات الموجودة في القسم العام، سيتم إنشاء غرفة منفصلة (غرفة مشتركة). سيتمكن مسؤولو DocSpace فقط من الوصول إلى هذه الغرفة. بشكل افتراضي، سيكون مالك الغرفة هو المستخدم الذي يبدأ الاستيراد: {{user}} (You).", "CompanyInfoSettings": "إعدادات معلومات الشركة", "CompanyInfoSettingsDescription": "سيتم عرض هذه المعلومات في النافذة <1> {{link}} .", "ConfirmEmailSended": "تم إرسال بريد التأكيد الإلكتروني إلى {{ownerName}}", diff --git a/packages/client/public/locales/az/Settings.json b/packages/client/public/locales/az/Settings.json index 1ac5a4bcca..6924efa69e 100644 --- a/packages/client/public/locales/az/Settings.json +++ b/packages/client/public/locales/az/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Ehtiyat faylları seçin", "ClearBackupList": "Bütün ehtiyat nüsxələri silin", "CloseMenu": "Menyunu bağlayın", - "CommonFilesDescription": "Ümumi bölmədəki fayllar üçün ayrıca otaq (Ümumi otaq) yaradılacaq. Bu otağa yalnız DocSpace administratorları daxil ola bilər. Defolt olaraq, otağın sahibi idxalı başladan istifadəçi olacaq: John Smith (Siz).", + "CommonFilesDescription": "Ümumi bölmədəki fayllar üçün ayrıca otaq (Ümumi otaq) yaradılacaq. Bu otağa yalnız DocSpace administratorları daxil ola bilər. Defolt olaraq, otağın sahibi idxalı başladan istifadəçi olacaq: {{user}} (Siz).", "CompanyInfoSettings": "Şirkət məlumatları parametrləri", "CompanyInfoSettingsDescription": "Bu məlumat <1>{{link}} pəncərəsində göstəriləcək.", "ConfirmEmailSended": "Təsdiqləmə e-məktubu {{ownerName}} göndərilmişdir", diff --git a/packages/client/public/locales/bg/Settings.json b/packages/client/public/locales/bg/Settings.json index 11a42dc2bd..8102cec3d4 100644 --- a/packages/client/public/locales/bg/Settings.json +++ b/packages/client/public/locales/bg/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Изберете архивните файлове", "ClearBackupList": "Изтриване на всички архиви", "CloseMenu": "Затвори меню", - "CommonFilesDescription": "За файловете в раздела Общи ще бъде създадена отделна стая (Обща стая). Само администраторите на DocSpace ще имат достъп до тази стая. По подразбиране собственикът на стаята ще бъде потребителят, иницииращ импортирането: Джон Смит (Вие).", + "CommonFilesDescription": "За файловете в раздела Общи ще бъде създадена отделна стая (Обща стая). Само администраторите на DocSpace ще имат достъп до тази стая. По подразбиране собственикът на стаята ще бъде потребителят, иницииращ импортирането: {{user}} (Вие).", "CompanyInfoSettings": "Настройки на фирмените данни", "CompanyInfoSettingsDescription": "Тази информация ще се покаже в прозореца <1>{{link}}.", "ConfirmEmailSended": "Имейлът за потвърждение бе изпратен на {{ownerName}}", diff --git a/packages/client/public/locales/cs/Settings.json b/packages/client/public/locales/cs/Settings.json index 506f790ec8..a835de270b 100644 --- a/packages/client/public/locales/cs/Settings.json +++ b/packages/client/public/locales/cs/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Výběr záložních souborů", "ClearBackupList": "Odstranit všechny zálohy", "CloseMenu": "Zavřít nabídku", - "CommonFilesDescription": "Pro soubory ve společné části bude vytvořena samostatná místnost (Společná místnost). Do této místnosti budou mít přístup pouze správci DocSpace. Ve výchozím nastavení bude vlastníkem místnosti uživatel, který iniciuje import: Jan Novák (Vy).", + "CommonFilesDescription": "Pro soubory ve společné části bude vytvořena samostatná místnost (Společná místnost). Do této místnosti budou mít přístup pouze správci DocSpace. Ve výchozím nastavení bude vlastníkem místnosti uživatel, který iniciuje import: {{user}} (Vy).", "CompanyInfoSettings": "Nastavení informací o společnosti", "CompanyInfoSettingsDescription": "Tyto informace se zobrazí v okně <1>{{link}}.", "ConfirmEmailSended": "Potvrzující e-mail byl odeslán{{ownerName}}", diff --git a/packages/client/public/locales/de/Settings.json b/packages/client/public/locales/de/Settings.json index f6680b15ad..a4ffea4593 100644 --- a/packages/client/public/locales/de/Settings.json +++ b/packages/client/public/locales/de/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Sicherungsdateien wählen", "ClearBackupList": "Alle Datensicherungen löschen", "CloseMenu": "Menü schließen", - "CommonFilesDescription": "Für die Dateien im Abschnitt „Gemeinsam“ wird ein separater Raum erstellt (Gemeinsamer Raum). Nur DocSpace-Administratoren haben Zugriff auf diesen Raum. Standardmäßig ist der Besitzer des Raums der Benutzer, der den Import initiiert: John Smith (Sie).", + "CommonFilesDescription": "Für die Dateien im Abschnitt „Gemeinsam“ wird ein separater Raum erstellt (Gemeinsamer Raum). Nur DocSpace-Administratoren haben Zugriff auf diesen Raum. Standardmäßig ist der Besitzer des Raums der Benutzer, der den Import initiiert: {{user}} (Sie).", "CompanyInfoSettings": "Einstellungen zum Unternehmen", "CompanyInfoSettingsDescription": "Diese Informationen werden im Fenster <1>{{link}} angezeigt.", "ConfirmEmailSended": "Bestätiguns-E-Mail wurde an {{ownerName}} gesendet.", diff --git a/packages/client/public/locales/el-GR/Settings.json b/packages/client/public/locales/el-GR/Settings.json index f63b74c932..98ae150789 100644 --- a/packages/client/public/locales/el-GR/Settings.json +++ b/packages/client/public/locales/el-GR/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Επιλογή αρχείων αντιγράφων ασφαλείας", "ClearBackupList": "Διαγραφή όλων των αντιγράφων ασφαλείας", "CloseMenu": "Κλείσιμο μενού", - "CommonFilesDescription": "Για τα αρχεία στην ενότητα Κοινά, θα δημιουργηθεί ένα ξεχωριστό δωμάτιο (Κοινό δωμάτιο). Μόνο οι διαχειριστές του DocSpace θα έχουν πρόσβαση σε αυτό το δωμάτιο. Από προεπιλογή, ο ιδιοκτήτης του δωματίου θα είναι ο χρήστης που ξεκινά την εισαγωγή: Γιώργος Παπαδόπουλος (Εσείς).", + "CommonFilesDescription": "Για τα αρχεία στην ενότητα Κοινά, θα δημιουργηθεί ένα ξεχωριστό δωμάτιο (Κοινό δωμάτιο). Μόνο οι διαχειριστές του DocSpace θα έχουν πρόσβαση σε αυτό το δωμάτιο. Από προεπιλογή, ο ιδιοκτήτης του δωματίου θα είναι ο χρήστης που ξεκινά την εισαγωγή: {{user}} (Εσείς).", "CompanyInfoSettings": "Ρυθμίσεις πληροφοριών εταιρείας", "CompanyInfoSettingsDescription": "Αυτές οι πληροφορίες θα εμφανιστούν στο παράθυρο <1>{{link}}.", "ConfirmEmailSended": "Το e-mail επιβεβαίωσης έχει σταλεί στον χρήστη {{ownerName}}", diff --git a/packages/client/public/locales/es/Settings.json b/packages/client/public/locales/es/Settings.json index 0b0b6596a3..4d85c7d567 100644 --- a/packages/client/public/locales/es/Settings.json +++ b/packages/client/public/locales/es/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Elija los archivos de copia de seguridad", "ClearBackupList": "Eliminar todas las copias de seguridad", "CloseMenu": "Cerrar menú", - "CommonFilesDescription": "Para los archivos de la sección Común, se creará una sala separada (Sala común). Solo los administradores de DocSpace tendrán acceso a esta sala. De forma predeterminada, el propietario de la sala será el usuario que inicie la importación: John Smith (usted).", + "CommonFilesDescription": "Para los archivos de la sección Común, se creará una sala separada (Sala común). Solo los administradores de DocSpace tendrán acceso a esta sala. De forma predeterminada, el propietario de la sala será el usuario que inicie la importación: {{user}} (usted).", "CompanyInfoSettings": "Configuración de la información de la empresa", "CompanyInfoSettingsDescription": "Esta información se mostrará en la ventana <1>{{link}}.", "ConfirmEmailSended": "El correo electrónico de confirmación ha sido enviado a {{ownerName}}", diff --git a/packages/client/public/locales/fi/Settings.json b/packages/client/public/locales/fi/Settings.json index d4aeb27b8d..e7accad776 100644 --- a/packages/client/public/locales/fi/Settings.json +++ b/packages/client/public/locales/fi/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Valitse varmuuskopiotiedostot", "ClearBackupList": "Poista kaikki varmuuskopiot", "CloseMenu": "Sulje menu ", - "CommonFilesDescription": "Erillinen huone luodaan Yleistä-osion tiedostoille (Yleistä-huone). Vain DocSpace-järjestelmänvalvojilla on oikeudet tähän huoneeseen. Huoneen omistaja on oletuksena käyttäjä, joka voi aloittaa tuonnin: John Smith (sinä).", + "CommonFilesDescription": "Erillinen huone luodaan Yleistä-osion tiedostoille (Yleistä-huone). Vain DocSpace-järjestelmänvalvojilla on oikeudet tähän huoneeseen. Huoneen omistaja on oletuksena käyttäjä, joka voi aloittaa tuonnin: {{user}} (sinä).", "CompanyInfoSettings": "Yrityksen info-asetukset", "CompanyInfoSettingsDescription": "Tämä informaatio näytetään <1>{{link}} ikkunassa.", "ConfirmEmailSended": "Vahvistusviesti on lähetetty osoitteen {{ownerName}}", diff --git a/packages/client/public/locales/fr/Settings.json b/packages/client/public/locales/fr/Settings.json index eca6d31e31..6e34a68b28 100644 --- a/packages/client/public/locales/fr/Settings.json +++ b/packages/client/public/locales/fr/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Choisissez les fichiers de sauvegarde", "ClearBackupList": "Supprimer toutes les sauvegardes", "CloseMenu": "Fermer le menu", - "CommonFilesDescription": "Quant aux fichiers depuis la section Commun, une salle séparée sera crée (Salle Commune). Ce sont uniquement les administrateurs DocSpace qui auront l'accès à cette salle. Par défaut, le propriétaire de la salle sera l'utilisateur qui a lancé l'importation: John Smith (Vous).", + "CommonFilesDescription": "Quant aux fichiers depuis la section Commun, une salle séparée sera crée (Salle Commune). Ce sont uniquement les administrateurs DocSpace qui auront l'accès à cette salle. Par défaut, le propriétaire de la salle sera l'utilisateur qui a lancé l'importation: {{user}} (Vous).", "CompanyInfoSettings": "Paramètres d’information de l’entreprise", "CompanyInfoSettingsDescription": "Ces informations seront affichées dans la fenêtre <1>{{link}}.", "ConfirmEmailSended": "Un e-mail de confirmation a été envoyé à {{ownerName}}", diff --git a/packages/client/public/locales/hy-AM/Settings.json b/packages/client/public/locales/hy-AM/Settings.json index 790bf55f2e..f610809e6e 100644 --- a/packages/client/public/locales/hy-AM/Settings.json +++ b/packages/client/public/locales/hy-AM/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Ընտրել պահուստային կրկնօրինակ ֆայլերը", "ClearBackupList": "Ջնջել բոլոր պահուստները", "CloseMenu": "Փակել մենյուն", - "CommonFilesDescription": "Ընդհանուր բաժնի ֆայլերի համար կստեղծվի առանձին սենյակ (Ընդհանուր սենյակ): Այս սենյակ մուտք կունենան միայն DocSpace-ի ադմինիստրատորները: Լռելյայնորեն, սենյակի սեփականատերը կլինի ներմուծումը նախաձեռնող օգտատերը՝ Ջոն Սմիթը (Դուք):", + "CommonFilesDescription": "Ընդհանուր բաժնի ֆայլերի համար կստեղծվի առանձին սենյակ (Ընդհանուր սենյակ): Այս սենյակ մուտք կունենան միայն DocSpace-ի ադմինիստրատորները: Լռելյայնորեն, սենյակի սեփականատերը կլինի ներմուծումը նախաձեռնող օգտատերը՝ {{user}} (Դուք):", "CompanyInfoSettings": "Ընկերության տեղեկատվության կարգավորումները", "CompanyInfoSettingsDescription": "Այս տեղեկատվությունը կցուցադրվի <1>{{link}} պատուհանում:", "ConfirmEmailSended": "Հաստատման էլ-նամակը ուղարկվել է {{ownerName}}", diff --git a/packages/client/public/locales/it/Settings.json b/packages/client/public/locales/it/Settings.json index 8f4203b6b4..02cbf20840 100644 --- a/packages/client/public/locales/it/Settings.json +++ b/packages/client/public/locales/it/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Scegli i file di backup", "ClearBackupList": "Elimina tutti i backup", "CloseMenu": "Chiudi menù", - "CommonFilesDescription": "Per i file presenti nella sezione Comune verrà creata una stanza separata (Stanza Comune). Solo gli amministratori di DocSpace avranno accesso a questa stanza. Per impostazione predefinita, il proprietario della stanza sarà l'utente che avvia l'importazione: John Smith (Tu).", + "CommonFilesDescription": "Per i file presenti nella sezione Comune verrà creata una stanza separata (Stanza Comune). Solo gli amministratori di DocSpace avranno accesso a questa stanza. Per impostazione predefinita, il proprietario della stanza sarà l'utente che avvia l'importazione: {{user}} (Tu).", "CompanyInfoSettings": "Impostazioni delle informazioni aziendali", "CompanyInfoSettingsDescription": "Queste informazioni verranno visualizzate nella finestra <1>{{link}}.", "ConfirmEmailSended": "Un messaggio e-mail di conferma è stato spedito a {{ownerName}}", diff --git a/packages/client/public/locales/ja-JP/Settings.json b/packages/client/public/locales/ja-JP/Settings.json index 3a157bf0df..98c84c9a96 100644 --- a/packages/client/public/locales/ja-JP/Settings.json +++ b/packages/client/public/locales/ja-JP/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "バックアップファイルの選択", "ClearBackupList": "すべてのバックアップを削除", "CloseMenu": "メニューを閉じる", - "CommonFilesDescription": "共通セクションのファイルについては、別のルーム(共通ルーム)が作成されます。このルームには、DocSpaceの管理者のみがアクセスできます。デフォルトでは、ルームの所有者はインポートを開始したユーザーです: John Smith(あなた)です。", + "CommonFilesDescription": "共通セクションのファイルについては、別のルーム(共通ルーム)が作成されます。このルームには、DocSpaceの管理者のみがアクセスできます。デフォルトでは、ルームの所有者はインポートを開始したユーザーです: {{user}}(あなた)です。", "CompanyInfoSettings": "会社情報設定", "CompanyInfoSettingsDescription": "この情報は、<1>{{link}}ウィンドウに表示されます。", "ConfirmEmailSended": "確認のメールが{{ownerName}}に送信されました。", diff --git a/packages/client/public/locales/ko-KR/Settings.json b/packages/client/public/locales/ko-KR/Settings.json index c7c3f5727f..2142959b02 100644 --- a/packages/client/public/locales/ko-KR/Settings.json +++ b/packages/client/public/locales/ko-KR/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "백업 파일을 선택하세요", "ClearBackupList": "모든 백업 삭제", "CloseMenu": "메뉴 닫기", - "CommonFilesDescription": "공용 섹션의 파일에 대해 별도의 공간(공용 방)이 생성됩니다. DocSpace 관리자만 이 방에 액세스할 수 있습니다. 기본적으로 방 소유자는 가져오기를 시작하는 사용자인 귀하(John Smith)입니다.", + "CommonFilesDescription": "공용 섹션의 파일에 대해 별도의 공간(공용 방)이 생성됩니다. DocSpace 관리자만 이 방에 액세스할 수 있습니다. 기본적으로 방 소유자는 가져오기를 시작하는 사용자인 귀하({{user}})입니다.", "CompanyInfoSettings": "회사 정보 설정", "CompanyInfoSettingsDescription": "이 정보가 <1>{{link}} 창에 표시됩니다.", "ConfirmEmailSended": "확인 이메일이 {{ownerName}} 님에게 전송되었습니다", diff --git a/packages/client/public/locales/lv/Settings.json b/packages/client/public/locales/lv/Settings.json index 1d358e4c04..ec7351d27e 100644 --- a/packages/client/public/locales/lv/Settings.json +++ b/packages/client/public/locales/lv/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Atlasīt dublējuma failus", "ClearBackupList": "Dzēst visus dublējumus", "CloseMenu": "Aizvērt izvēlni", - "CommonFilesDescription": "Kopējās sadaļas failiem tiks izveidota atsevišķa telpa (kopējā telpa). Tikai DocSpace administratoriem būs piekļuve šai telpai. Pēc noklusējuma telpas īpašnieks būs lietotājs, kas uzsāks importēšanu: Džons Smits (jūs).", + "CommonFilesDescription": "Kopējās sadaļas failiem tiks izveidota atsevišķa telpa (kopējā telpa). Tikai DocSpace administratoriem būs piekļuve šai telpai. Pēc noklusējuma telpas īpašnieks būs lietotājs, kas uzsāks importēšanu: {{user}} (jūs).", "CompanyInfoSettings": "Uzņēmuma informācijas iestatījumi", "CompanyInfoSettingsDescription": "Šī informācija tiks parādīta logā <1>{{link}}.", "ConfirmEmailSended": "Apstiprinājuma e-pasts ir nosūtīts uz {{ownerName}}", diff --git a/packages/client/public/locales/nl/Settings.json b/packages/client/public/locales/nl/Settings.json index 73b206e207..2e941c1192 100644 --- a/packages/client/public/locales/nl/Settings.json +++ b/packages/client/public/locales/nl/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Kies de back-up bestanden", "ClearBackupList": "Verwijder alle back-ups", "CloseMenu": "Sluit menu", - "CommonFilesDescription": "Voor de bestanden in de Algemene sectie wordt een aparte ruimte gemaakt (Algemene kamer). Alleen DocSpace beheerders hebben toegang tot deze ruimte. Standaard is de eigenaar van de kamer de gebruiker die de import start: John Smith (U).", + "CommonFilesDescription": "Voor de bestanden in de Algemene sectie wordt een aparte ruimte gemaakt (Algemene kamer). Alleen DocSpace beheerders hebben toegang tot deze ruimte. Standaard is de eigenaar van de kamer de gebruiker die de import start: {{user}} (U).", "CompanyInfoSettings": "Bedrijfsinformatie instellingen", "CompanyInfoSettingsDescription": "Deze informatie wordt weergegeven in het venster <1>{{link}}.", "ConfirmEmailSended": "Bevestiging e-mail is gestuurd naar {{ownerName}}", diff --git a/packages/client/public/locales/pl/Settings.json b/packages/client/public/locales/pl/Settings.json index 71d94e4479..6cdf3fb168 100644 --- a/packages/client/public/locales/pl/Settings.json +++ b/packages/client/public/locales/pl/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Wybierz pliki kopii zapasowej", "ClearBackupList": "Usuń wszystkie kopie zapasowe", "CloseMenu": "Zamknij menu", - "CommonFilesDescription": "Dla plików w sekcji Wspólne zostanie utworzony osobny pokój (pokój Wspólny). Tylko administratorzy DocSpace będą mieli dostęp do tego pokoju Domyślnie, właścicielem pokoju będzie użytkownik inicjujący import: Jan Kowalski (Ty).", + "CommonFilesDescription": "Dla plików w sekcji Wspólne zostanie utworzony osobny pokój (pokój Wspólny). Tylko administratorzy DocSpace będą mieli dostęp do tego pokoju Domyślnie, właścicielem pokoju będzie użytkownik inicjujący import: {{user}} (Ty).", "CompanyInfoSettings": "Ustawienia informacji o firmie", "CompanyInfoSettingsDescription": "Dana informacja wyświetli się w oknie <1>{{link}}.", "ConfirmEmailSended": "Wiadomość e-mail z potwierdzeniem została wysłana do {{ownerName}}", diff --git a/packages/client/public/locales/pt-BR/Settings.json b/packages/client/public/locales/pt-BR/Settings.json index b6fcfe9d96..89be7641cc 100644 --- a/packages/client/public/locales/pt-BR/Settings.json +++ b/packages/client/public/locales/pt-BR/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Escolha os arquivos de backup", "ClearBackupList": "Excluir todos os backups", "CloseMenu": "Fechar menu", - "CommonFilesDescription": "Para os arquivos da seção Comum será criada uma sala separada (Sala Comum). Somente administradores do DocSpace terão acesso a esta sala. Por padrão, o proprietário da sala será o usuário que inicia a importação: John Smith (Você).", + "CommonFilesDescription": "Para os arquivos da seção Comum será criada uma sala separada (Sala Comum). Somente administradores do DocSpace terão acesso a esta sala. Por padrão, o proprietário da sala será o usuário que inicia a importação: {{user}} (Você).", "CompanyInfoSettings": "Configurações de informações da empresa", "CompanyInfoSettingsDescription": "Essas informações serão exibidas na janela <1>{{link}}.", "ConfirmEmailSended": "O e-mail de confirmação foi enviado para {{ownerName}}.", diff --git a/packages/client/public/locales/pt/Settings.json b/packages/client/public/locales/pt/Settings.json index 49d84040f0..1cc8a18007 100644 --- a/packages/client/public/locales/pt/Settings.json +++ b/packages/client/public/locales/pt/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Escolha os arquivos de backup", "ClearBackupList": "Eliminar todas as cópias de segurança", "CloseMenu": "Fechar menu", - "CommonFilesDescription": "Para os arquivos da seção Comum será criada uma sala separada (Sala Comum). Somente administradores do DocSpace terão acesso a esta sala. Por padrão, o proprietário da sala será o usuário que inicia a importação: John Smith (Você).", + "CommonFilesDescription": "Para os arquivos da seção Comum será criada uma sala separada (Sala Comum). Somente administradores do DocSpace terão acesso a esta sala. Por padrão, o proprietário da sala será o usuário que inicia a importação: {{user}} (Você).", "CompanyInfoSettings": "Definições das informações sobre a empresa", "CompanyInfoSettingsDescription": "Esta informação será exibida na janela <1>{{link}}.", "ConfirmEmailSended": "Um email de confirmação foi enviado para {{ownerName}}", diff --git a/packages/client/public/locales/ro/Settings.json b/packages/client/public/locales/ro/Settings.json index ba6ea30ca4..78de97db3f 100644 --- a/packages/client/public/locales/ro/Settings.json +++ b/packages/client/public/locales/ro/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Alegeți fișiere de rezervă", "ClearBackupList": "Șterge toate copiile de rezervă", "CloseMenu": "Închidere meniu", - "CommonFilesDescription": "Pentru fișiere din secțiunea Comun, o sală separată va fi creată (Sală comună). Numai administratorii DocSpace vor avea acces la această sală. În mod implicit, proprietarul sălii va fi utilizatorul care poate iniția importul: John Smith (Dumneavoastră).", + "CommonFilesDescription": "Pentru fișiere din secțiunea Comun, o sală separată va fi creată (Sală comună). Numai administratorii DocSpace vor avea acces la această sală. În mod implicit, proprietarul sălii va fi utilizatorul care poate iniția importul: {{user}} (Dumneavoastră).", "CompanyInfoSettings": "Setări Informaţii companie", "CompanyInfoSettingsDescription": "Aceste informaţii vor fi afişate în fereastra <1>{{link}}.", "ConfirmEmailSended": "Un mesaj pentru confirmarea adresei de email a fost trimis către {{ownerName}}", diff --git a/packages/client/public/locales/ru/Settings.json b/packages/client/public/locales/ru/Settings.json index 2e16229b44..a3b1fa88e0 100644 --- a/packages/client/public/locales/ru/Settings.json +++ b/packages/client/public/locales/ru/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Выберите файлы резервных копий", "ClearBackupList": "Удалить все резервные копии", "CloseMenu": "Закрыть меню", - "CommonFilesDescription": "Для файлов в разделе \"Общие\" будет создана отдельная комната (Общая комната). Только администраторы DocSpace будут иметь доступ к этой комнате. По умолчанию владельцем комнаты будет пользователь, инициирующий импорт: Джон Смит (Вы).", + "CommonFilesDescription": "Для файлов в разделе \"Общие\" будет создана отдельная комната (Общая комната). Только администраторы DocSpace будут иметь доступ к этой комнате. По умолчанию владельцем комнаты будет пользователь, инициирующий импорт: {{user}} (Вы).", "CompanyInfoSettings": "Настройки информации о компании", "CompanyInfoSettingsDescription": "Эта информация будет отображаться в окне <1>{{link}} .", "ConfirmEmailSended": "Письмо с подтверждением отправлено {{ownerName}}", diff --git a/packages/client/public/locales/si/Settings.json b/packages/client/public/locales/si/Settings.json index a2ddbc5275..0ee97b4005 100644 --- a/packages/client/public/locales/si/Settings.json +++ b/packages/client/public/locales/si/Settings.json @@ -70,7 +70,7 @@ "ChooseBackupFiles": "උපස්ථ ගොනු තෝරන්න", "ClearBackupList": "සියළුම උපස්ථ මකන්න", "CloseMenu": "වට්ටෝරුව වසන්න", - "CommonFilesDescription": "පොදු කොටසේ ගොනු සඳහා වෙනම කාමරයක් (පොදු කාමරය) සාදනු ලැබේ. DocSpace පරිපාලකයින්ට පමණක් මෙම කාමරයට ප්‍රවේශය ඇත. පෙරනිමි පරිදි කාමරයේ හිමිකරු ආයාත කිරීම අරඹන පරිශ්‍රීලකයා වනු ඇත: හසිත ජයවර්ධන (ඔබ).", + "CommonFilesDescription": "පොදු කොටසේ ගොනු සඳහා වෙනම කාමරයක් (පොදු කාමරය) සාදනු ලැබේ. DocSpace පරිපාලකයින්ට පමණක් මෙම කාමරයට ප්‍රවේශය ඇත. පෙරනිමි පරිදි කාමරයේ හිමිකරු ආයාත කිරීම අරඹන පරිශ්‍රීලකයා වනු ඇත: {{user}} (ඔබ).", "CompanyInfoSettings": "සමාගමේ තොරතුරු සැකසුම්", "CompanyInfoSettingsDescription": "මෙම තොරතුරු <1>{{link}} කවුළුවෙහි දිස් වේ.", "ConfirmEmailSended": "තහවුරු කිරීමේ වි-තැපෑල {{ownerName}} වෙත යවා ඇත", diff --git a/packages/client/public/locales/sk/Settings.json b/packages/client/public/locales/sk/Settings.json index 319634bc38..f4a5ceca57 100644 --- a/packages/client/public/locales/sk/Settings.json +++ b/packages/client/public/locales/sk/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Vyberte záložné súbory", "ClearBackupList": "Odstrániť všetky zálohované údaje", "CloseMenu": "Zatvoriť menu", - "CommonFilesDescription": "Pre súbory v Spoločnej časti bude vytvorená samostatná miestnosť (Spoločná miestnosť). Prístup do tejto miestnosti budú mať len administrátori DocSpace. V predvolenom nastavení bude vlastníkom miestnosti používateľ, ktorý iniciuje import: John Smith (Vy).", + "CommonFilesDescription": "Pre súbory v Spoločnej časti bude vytvorená samostatná miestnosť (Spoločná miestnosť). Prístup do tejto miestnosti budú mať len administrátori DocSpace. V predvolenom nastavení bude vlastníkom miestnosti používateľ, ktorý iniciuje import: {{user}} (Vy).", "CompanyInfoSettings": "Nastavenia informácií o spoločnosti", "CompanyInfoSettingsDescription": "Tieto informácie sa zobrazia v okne <1>{{link}}.", "ConfirmEmailSended": "Potvrdzujúci mail bol odoslaný {{ownerName}}", diff --git a/packages/client/public/locales/sl/Settings.json b/packages/client/public/locales/sl/Settings.json index 305ace6c95..b4bc9537cd 100644 --- a/packages/client/public/locales/sl/Settings.json +++ b/packages/client/public/locales/sl/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Izberi datoteke varnostne kopije", "ClearBackupList": "Izbriši vse varnostne kopije", "CloseMenu": "Zapri menu", - "CommonFilesDescription": "Za datoteke v razdelku Skupno bo ustvarjena posebna soba (Skupna soba). Samo skrbniki DocSpace bodo imeli dostop do te sobe. Privzeto bo lastnik sobe uporabnik, ki začne uvoz: John Smith (Vi).", + "CommonFilesDescription": "Za datoteke v razdelku Skupno bo ustvarjena posebna soba (Skupna soba). Samo skrbniki DocSpace bodo imeli dostop do te sobe. Privzeto bo lastnik sobe uporabnik, ki začne uvoz: {{user}} (Vi).", "CompanyInfoSettings": "Nastavitve informacij o podjetju", "CompanyInfoSettingsDescription": "Te informacije bodo prikazane v <1>{{link}} oknu.", "ConfirmEmailSended": "Potrditveni e-mail je bil poslan na {{ownerName}}", diff --git a/packages/client/public/locales/sr-Latn-RS/Settings.json b/packages/client/public/locales/sr-Latn-RS/Settings.json index 2426ae8de9..9f69f89af3 100644 --- a/packages/client/public/locales/sr-Latn-RS/Settings.json +++ b/packages/client/public/locales/sr-Latn-RS/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Izaberi rezervne datoteke", "ClearBackupList": "Obriši sve rezervne kopije", "CloseMenu": "Zatvori meni", - "CommonFilesDescription": "Za datoteke u odeljku ‘Zajedničko’, biće kreirana posebna soba (Zajednička soba). Samo administratori DocSpace-a će imati pristup ovoj sobi. Po podrazumevanim podešavanjima, vlasnik sobe će biti korisnik koji je inicirao uvoz: John Smith (Vi).", + "CommonFilesDescription": "Za datoteke u odeljku ‘Zajedničko’, biće kreirana posebna soba (Zajednička soba). Samo administratori DocSpace-a će imati pristup ovoj sobi. Po podrazumevanim podešavanjima, vlasnik sobe će biti korisnik koji je inicirao uvoz: {{user}} (Vi).", "CompanyInfoSettings": "Informacije o Kompaniji podešavanja", "CompanyInfoSettingsDescription": "Ova informacija će biti prikazana u <1>{{link}} prozoru.", "ConfirmEmailSended": "Email konfirmacije je poslat {{ownerName}}", diff --git a/packages/client/public/locales/tr/Settings.json b/packages/client/public/locales/tr/Settings.json index 8c51b4fb5e..c48a1260d1 100644 --- a/packages/client/public/locales/tr/Settings.json +++ b/packages/client/public/locales/tr/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Yedekleme dosyalarını seç", "ClearBackupList": "Tüm yedekleri sil", "CloseMenu": "Menüyü kapat", - "CommonFilesDescription": "Ortak bölümdeki dosyalar için ayrı bir oda oluşturulacaktır (Ortak oda). Bu odaya yalnızca DocSpace yöneticilerinin erişimi olacaktır. Varsayılan olarak, odanın sahibi içe aktarmayı başlatan kullanıcı olacaktır: John Smith (Siz).", + "CommonFilesDescription": "Ortak bölümdeki dosyalar için ayrı bir oda oluşturulacaktır (Ortak oda). Bu odaya yalnızca DocSpace yöneticilerinin erişimi olacaktır. Varsayılan olarak, odanın sahibi içe aktarmayı başlatan kullanıcı olacaktır: {{user}} (Siz).", "CompanyInfoSettings": "Şirket bilgileri ayarları", "CompanyInfoSettingsDescription": "Bu bilgi <1>{{link}} penceresinde görüntülenecektir.", "ConfirmEmailSended": "Onay e-postası şu kişiye gönderildi {{ownerName}}", diff --git a/packages/client/public/locales/uk-UA/Settings.json b/packages/client/public/locales/uk-UA/Settings.json index 0314c96039..d13d3cd560 100644 --- a/packages/client/public/locales/uk-UA/Settings.json +++ b/packages/client/public/locales/uk-UA/Settings.json @@ -72,7 +72,7 @@ "ChooseBackupFiles": "Вибрати файли резервної копії", "ClearBackupList": "Видалити всі резервні копії", "CloseMenu": "Закрити меню", - "CommonFilesDescription": "Для файлів у розділі «Загальні» буде створено окрему кімнату (кімната «Загальні»). До цієї кімнати будуть мати доступ лише адміністратори DocSpace. За замовчуванням власником кімнати буде користувач, який ініціював імпорт: Джон Сміт (ви). ", + "CommonFilesDescription": "Для файлів у розділі «Загальні» буде створено окрему кімнату (кімната «Загальні»). До цієї кімнати будуть мати доступ лише адміністратори DocSpace. За замовчуванням власником кімнати буде користувач, який ініціював імпорт: {{user}} (ви). ", "CompanyInfoSettings": "Параметри інформації про компанію", "CompanyInfoSettingsDescription": "Цю інформацію буде показано у вікні <1>{{link}}.", "ConfirmEmailSended": "Електронний лист-підтвердження надіслано {{ownerName}}", diff --git a/packages/client/public/locales/vi/Settings.json b/packages/client/public/locales/vi/Settings.json index e09ad0c4bc..37963a60a5 100644 --- a/packages/client/public/locales/vi/Settings.json +++ b/packages/client/public/locales/vi/Settings.json @@ -71,7 +71,7 @@ "ChooseBackupFiles": "Chọn các tập tin sao lưu", "ClearBackupList": "Xóa tất cả bản sao lưu", "CloseMenu": "Đóng menu", - "CommonFilesDescription": "Đối với các tập tin trong phần Chung, một phòng riêng biệt sẽ được tạo (Phòng chung). Chỉ quản trị viên DocSpace mới có quyền truy cập vào phòng này. Theo mặc định, chủ phòng sẽ là người dùng bắt đầu nhập: John Smith (Bạn).", + "CommonFilesDescription": "Đối với các tập tin trong phần Chung, một phòng riêng biệt sẽ được tạo (Phòng chung). Chỉ quản trị viên DocSpace mới có quyền truy cập vào phòng này. Theo mặc định, chủ phòng sẽ là người dùng bắt đầu nhập: {{user}} (Bạn).", "CompanyInfoSettings": "Cài đặt thông tin công ty", "CompanyInfoSettingsDescription": "Thông tin này sẽ được hiển thị trong cửa sổ <1>{{link}}.", "ConfirmEmailSended": "Email xác nhận đã được gửi tới {{ownerName}}", diff --git a/packages/client/public/locales/zh-CN/Settings.json b/packages/client/public/locales/zh-CN/Settings.json index dcc2f1bd54..9eb345efc1 100644 --- a/packages/client/public/locales/zh-CN/Settings.json +++ b/packages/client/public/locales/zh-CN/Settings.json @@ -70,7 +70,7 @@ "ChooseBackupFiles": "选择备份文件", "ClearBackupList": "删除所有备份", "CloseMenu": "关闭菜单", - "CommonFilesDescription": "系统会为“公共”板块中的文件创建一个单独的房间(公共房间)。只有协作空间管理员可访问此房间。默认情况下,房间的所有者是发起导入的用户:John Smith(您)。", + "CommonFilesDescription": "系统会为“公共”板块中的文件创建一个单独的房间(公共房间)。只有协作空间管理员可访问此房间。默认情况下,房间的所有者是发起导入的用户:{{user}}(您)。", "CompanyInfoSettings": "公司信息设置", "CompanyInfoSettingsDescription": "此信息将展示在 <1>{{link}} 窗口中。", "ConfirmEmailSended": "确认邮件已发送至{{ownerName}}", From 2781498b8ae502284eb3c36171c60e22ce21c498 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 29 May 2024 12:07:15 +0300 Subject: [PATCH 093/126] Web: Accounts: Hotkeys: added Esc key support --- packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts | 5 +++++ packages/client/src/pages/Home/Section/AccountsBody/index.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts index 300465e35f..a8bbcd66e5 100644 --- a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts +++ b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts @@ -36,6 +36,7 @@ interface AccountsHotkeysProps { selectBottom: () => void; selectUpper: () => void; activateHotkeys: (e: KeyboardEvent) => void; + setSelected: (value: string) => void; } const useAccountsHotkeys = ({ @@ -44,6 +45,7 @@ const useAccountsHotkeys = ({ selectBottom, selectUpper, activateHotkeys, + setSelected, }: AccountsHotkeysProps) => { const [isEnabled, setIsEnabled] = useState(true); @@ -104,6 +106,9 @@ const useAccountsHotkeys = ({ }, hotkeysFilter, ); + + // Deselect all accounts + useHotkeys("shift+n, ESC", () => setSelected("none"), hotkeysFilter); }; export default useAccountsHotkeys; diff --git a/packages/client/src/pages/Home/Section/AccountsBody/index.js b/packages/client/src/pages/Home/Section/AccountsBody/index.js index 5867cb7174..49dd3d4de2 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/index.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/index.js @@ -55,6 +55,7 @@ const SectionBodyContent = (props) => { activateHotkeys, setHotkeyCaretStart, setHotkeyCaret, + setSelected, } = props; const location = useLocation(); @@ -66,6 +67,7 @@ const SectionBodyContent = (props) => { selectBottom, selectUpper, activateHotkeys, + setSelected, }); useEffect(() => { @@ -140,6 +142,7 @@ export default inject(({ peopleStore }) => { setSelection: setPeopleSelection, setBufferSelection: setPeopleBufferSelection, selectUser, + setSelected, } = peopleStore.selectionStore; const { @@ -176,6 +179,7 @@ export default inject(({ peopleStore }) => { setEnabledHotkeys, setHotkeyCaretStart, setHotkeyCaret, + setSelected, }; })( withTranslation(["People", "Common", "PeopleTranslations"])( From 3b06dd5a8c4efd62a9da0ad575079b98966264be Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 29 May 2024 12:21:21 +0300 Subject: [PATCH 094/126] Web: Files: fixed link for "Share room" button --- packages/client/src/pages/Home/Section/Header/index.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Header/index.js b/packages/client/src/pages/Home/Section/Header/index.js index c7384918a0..4636899dfb 100644 --- a/packages/client/src/pages/Home/Section/Header/index.js +++ b/packages/client/src/pages/Home/Section/Header/index.js @@ -827,7 +827,7 @@ const SectionHeaderContent = (props) => { }; const onNavigationButtonClick = () => { - onCreateAndCopySharedLink(props.roomItem, t); + onCreateAndCopySharedLink(selectedFolder, t); }; const headerMenu = isAccountsPage @@ -1236,11 +1236,6 @@ export default inject( shared) || (sharedItem && sharedItem.canCopyPublicLink); - const roomItem = - navigationPath.length > 1 - ? navigationPath[navigationPath.length - 2] - : selectedFolder; - return { isGracePeriod, setInviteUsersWarningDialogVisible, @@ -1366,8 +1361,6 @@ export default inject( onClickReconnectStorage, getFolderModel, onCreateRoom, - - roomItem, }; }, )( From 70a4b2e00be35e0ca1b7b0440e6377fe66b27bda Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Wed, 29 May 2024 12:53:10 +0300 Subject: [PATCH 095/126] Shared: TabsContainer: fix styles --- .../tabs-container/TabsContainer.styled.tsx | 27 ++++++++++++++++--- packages/shared/themes/base.ts | 10 ++++--- packages/shared/themes/dark.ts | 13 +++++---- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/shared/components/tabs-container/TabsContainer.styled.tsx b/packages/shared/components/tabs-container/TabsContainer.styled.tsx index 6e87867b0d..a1fdae9736 100644 --- a/packages/shared/components/tabs-container/TabsContainer.styled.tsx +++ b/packages/shared/components/tabs-container/TabsContainer.styled.tsx @@ -41,7 +41,9 @@ const NavItem = styled.div` position: relative; white-space: nowrap; display: flex; + gap: 8px; `; + NavItem.defaultProps = { theme: Base }; const Label = styled.div<{ isDisabled?: boolean; selected?: boolean }>` @@ -49,10 +51,12 @@ const Label = styled.div<{ isDisabled?: boolean; selected?: boolean }>` border-radius: ${(props) => props.theme.tabsContainer.label.borderRadius}; min-width: ${(props) => props.theme.tabsContainer.label.minWidth}; width: ${(props) => props.theme.tabsContainer.label.width}; + display: flex; + align-items: center; .title_style { text-align: center; - margin: ${(props) => props.theme.tabsContainer.label.title.margin}; + padding: ${(props) => props.theme.tabsContainer.label.title.padding}; overflow: ${(props) => props.theme.interfaceDirection === "rtl" ? "visible" : "hidden"}; ${NoUserSelect}; @@ -67,13 +71,25 @@ const Label = styled.div<{ isDisabled?: boolean; selected?: boolean }>` ${(props) => props.selected ? css` + border: 1px solid transparent; cursor: default; background-color: ${props.theme.tabsContainer.label.backgroundColor}; .title_style { color: ${props.theme.tabsContainer.label.title.color}; } + + &:hover { + cursor: pointer; + opacity: 0.85; + } + + &:active { + background: ${props.theme.tabsContainer.label + .activeSelectedBackgroundColor}; + } ` : css` + border: ${props.theme.tabsContainer.label.border}; &:hover { cursor: pointer; background-color: ${props.theme.tabsContainer.label @@ -82,14 +98,17 @@ const Label = styled.div<{ isDisabled?: boolean; selected?: boolean }>` color: ${props.theme.tabsContainer.label.title.hoverColor}; } } + + &:active { + background-color: ${props.theme.tabsContainer.label + .activeBackgroundColor}; + } `} ${(props) => props.isDisabled && - props.selected && css` - background-color: ${props.theme.tabsContainer.label - .disableBackgroundColor}; + ${props.selected && `opacity: 0.6;`} .title_style { color: ${props.theme.tabsContainer.label.title.disableColor}; } diff --git a/packages/shared/themes/base.ts b/packages/shared/themes/base.ts index b49e6a09f4..66cebc40a7 100644 --- a/packages/shared/themes/base.ts +++ b/packages/shared/themes/base.ts @@ -1030,18 +1030,22 @@ export const getBaseTheme = () => { }, label: { - height: " 32px", + height: " 30px", + border: "1px solid #ECEEF1", borderRadius: "16px", minWidth: "fit-content", marginRight: "8px", width: "fit-content", backgroundColor: blueLightMid, - hoverBackgroundColor: grayLight, + hoverBackgroundColor: "#F3F4F4", disableBackgroundColor: grayLightMid, + activeBackgroundColor: "#ECEEF1", + activeSelectedBackgroundColor: + "linear-gradient(0deg, #265a8f, #265a8f), linear-gradient(0deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))", title: { - margin: "7px 15px 7px 15px", + padding: "4px 16px", overflow: "hidden", color: white, hoverColor: black, diff --git a/packages/shared/themes/dark.ts b/packages/shared/themes/dark.ts index 516b78f09e..2a664a2f7f 100644 --- a/packages/shared/themes/dark.ts +++ b/packages/shared/themes/dark.ts @@ -1000,18 +1000,21 @@ const Dark: TTheme = { }, label: { - height: " 32px", + height: " 30px", + border: "1px solid #474747", borderRadius: "16px", minWidth: "fit-content", marginRight: "8px", width: "fit-content", - backgroundColor: "#d6d6d6", - hoverBackgroundColor: "#3D3D3D", - disableBackgroundColor: "#292929", + backgroundColor: "#FFFFFF", + hoverBackgroundColor: "#474747", + disableBackgroundColor: "#282828", + activeBackgroundColor: "#282828", + activeSelectedBackgroundColor: "linear-gradient(0deg, #FFFFFF, #FFFFFF), linear-gradient(0deg, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.18))", title: { - margin: "7px 15px 7px 15px", + padding: "4px 16px", overflow: "hidden", color: black, hoverColor: "#a4a4a4", From 295d5ce2f3dd4fec1054434c1d819dc13a4dd7f4 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 29 May 2024 15:03:02 +0500 Subject: [PATCH 096/126] Web: Client: adjusted spacing in DeleteProfileEverDialog --- .../components/dialogs/DeleteProfileEverDialog/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js index fd67d2568f..b749469e08 100644 --- a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js +++ b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js @@ -62,7 +62,11 @@ const StyledModalDialogContainer = styled(ModalDialogContainer)` .user-delete { line-height: 20px; - padding-bottom: 16px; + ${(props) => + (!props.areUsersOnly || props.deleteWithoutReassign) && + css` + padding-bottom: 16px; + `} } .text-warning { @@ -184,6 +188,8 @@ const DeleteProfileEverDialogComponent = (props) => { visible={visible} onClose={onClose} needReassignData={needReassignData} + deleteWithoutReassign={deleteWithoutReassign} + areUsersOnly={areUsersOnly} > {onlyOneUser ? t("DeleteUser") : t("DeletingUsers")} From 27a18d8b904c78c59a8333d183f3f2211c93e50b Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 29 May 2024 15:34:52 +0500 Subject: [PATCH 097/126] Web: Client: Data Import: error text was corrected --- .../OnlyofficeWorkspace/Stepper/SelectFileStep/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js index 46acf6e380..b94b4e37b9 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js @@ -181,7 +181,10 @@ const SelectFileStep = ({ setProgress(0); setIsVisible(true); try { - if (Array.isArray(file)) throw new Error(t("Common:SomethingWentWrong")); + if (Array.isArray(file)) { + setShowErrorText(true); + throw new Error(t("Common:SomethingWentWrong")); + } await singleFileUploading(file, setProgress, isAbort); await initMigrationName(searchParams.get("service")); From 2723efb02b99a4f0326413e70a18ba36f296eaa0 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 29 May 2024 15:05:06 +0300 Subject: [PATCH 098/126] Shared: Utils: Added checks. --- packages/shared/utils/cookie.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/shared/utils/cookie.ts b/packages/shared/utils/cookie.ts index d07e31937a..167ea8bc69 100644 --- a/packages/shared/utils/cookie.ts +++ b/packages/shared/utils/cookie.ts @@ -30,18 +30,17 @@ import { LANGUAGE } from "../constants"; export function getCookie(name: string) { - if (name === LANGUAGE) { + if (typeof window !== "undefined" && name === LANGUAGE) { const url = new URL(window.location.href); const culture = url.searchParams.get("culture"); if (url.pathname === "/confirm/LinkInvite" && culture) { return culture; } - if (url.pathname === "/login/" && culture) { - return culture; - } } + if (typeof document === "undefined") return undefined; + const matches = document.cookie.match( new RegExp( "(?:^|; )" + From 7cd2d0c19ac5274aeacfb6d4e947b0b315c648f8 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 29 May 2024 15:09:29 +0300 Subject: [PATCH 099/126] Login: Components: Refactoring. --- packages/login/src/components/LoginForm/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/login/src/components/LoginForm/index.tsx b/packages/login/src/components/LoginForm/index.tsx index 713c17b1b9..4f8f06b55d 100644 --- a/packages/login/src/components/LoginForm/index.tsx +++ b/packages/login/src/components/LoginForm/index.tsx @@ -73,7 +73,7 @@ const LoginForm = ({ const { t, ready, i18n } = useTranslation(["Login", "Common"]); const currentCulture = i18n.language; - + const message = searchParams.get("message"); const confirmedEmail = searchParams.get("confirmedEmail"); const authError = searchParams.get("authError"); @@ -163,7 +163,7 @@ const LoginForm = ({ useEffect(() => { window.authCallback = authCallback; - }, [currentCulture]); + }, [authCallback]); useEffect(() => { message && setErrorText(message); From 0552d3adfb00bf9e00b9bd7d26ecc99351c54723 Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Wed, 29 May 2024 15:42:51 +0200 Subject: [PATCH 100/126] Fix Bug 68250 - Accounts: Frozen client on the settings page after clicking Page Up / Page Down --- packages/client/src/HOCs/withHotkeys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/HOCs/withHotkeys.js b/packages/client/src/HOCs/withHotkeys.js index 9444fee28e..ab45e8962c 100644 --- a/packages/client/src/HOCs/withHotkeys.js +++ b/packages/client/src/HOCs/withHotkeys.js @@ -158,7 +158,7 @@ const withHotkeys = (Component) => { document.addEventListener("paste", onPaste); return () => { - window.removeEventListener("keypress", throttledKeyDownEvent); + window.removeEventListener("keydown", throttledKeyDownEvent); document.removeEventListener("paste", onPaste); }; }); From 681b101a5bb83734251bc678ab419cc00fcd773d Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Thu, 30 May 2024 11:49:08 +0300 Subject: [PATCH 101/126] Login: Language request added to client. --- packages/login/src/app/(root)/layout.tsx | 16 +++++++---- .../src/components/LanguageCombobox/index.tsx | 28 +++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/login/src/app/(root)/layout.tsx b/packages/login/src/app/(root)/layout.tsx index 4f9fb71f60..e9eca7cceb 100644 --- a/packages/login/src/app/(root)/layout.tsx +++ b/packages/login/src/app/(root)/layout.tsx @@ -25,6 +25,7 @@ // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode import { cookies } from "next/headers"; +import dynamic from "next/dynamic"; import { SYSTEM_THEME_KEY } from "@docspace/shared/constants"; import { ThemeKeys, WhiteLabelLogoType } from "@docspace/shared/enums"; @@ -36,18 +37,23 @@ import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import SimpleNav from "@/components/SimpleNav"; import { LoginContent, LoginFormWrapper } from "@/components/Login"; import GreetingContainer from "@/components/GreetingContainer"; -import { getColorTheme, getPortalCultures, getSettings } from "@/utils/actions"; -import LanguageComboboxWrapper from "@/components/LanguageCombobox"; +import { getColorTheme, getSettings } from "@/utils/actions"; + +const LanguageComboboxWrapper = dynamic( + () => import("@/components/LanguageCombobox"), + { + ssr: false, + }, +); export default async function Layout({ children, }: { children: React.ReactNode; }) { - const [settings, colorTheme, cultures] = await Promise.all([ + const [settings, colorTheme] = await Promise.all([ getSettings(), getColorTheme(), - getPortalCultures(), ]); const cookieStore = cookies(); @@ -71,7 +77,7 @@ export default async function Layout({
- + { - const { cultures } = props; +const LanguageComboboxWrapper = () => { const { i18n } = useTranslation(["Login", "Common"]); - const currentCulture = i18n.language; + const [cultures, setCultures] = useState>(null); + + const getData = useCallback(async () => { + const [cultures] = await Promise.all([getPortalCultures()]); + + if (cultures) setCultures(cultures); + }, []); + + useEffect(() => { + getData(); + }, [getData]); + const onLanguageSelect = (culture: { key: string }) => { const { key } = culture; @@ -53,6 +63,8 @@ const LanguageComboboxWrapper = (props: TLanguageCombobox) => { const { currentDeviceType } = useDeviceType(); const isMobileView = currentDeviceType === DeviceType.mobile; + if (!cultures) return <>; + return ( Date: Thu, 30 May 2024 16:10:38 +0300 Subject: [PATCH 102/126] Client: add translate --- packages/client/public/locales/en/Files.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/public/locales/en/Files.json b/packages/client/public/locales/en/Files.json index 751276474e..0339aef4bc 100644 --- a/packages/client/public/locales/en/Files.json +++ b/packages/client/public/locales/en/Files.json @@ -182,6 +182,7 @@ "WantLeaveRoom": "Do you really want to leave this room? You will be able to join it again via new invitation by a room admin.", "WantToRestoreTheRoom": "All shared links in this room will become active, and its contents will be available to everyone with the link. Do you want to restore the room?", "WantToRestoreTheRooms": "All shared links in restored rooms will become active, and their contents will be available to everyone with the room links. Do you want to restore the rooms?", + "WaitOperation": "Wait for the current operation to complete", "WithSubfolders": "With subfolders", "YouLeftTheRoom": "You have left the room" } From 56c31b549f6e0dad9aacdc6da79f2278ac848f2f Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 30 May 2024 16:11:20 +0300 Subject: [PATCH 103/126] Client: add warning toast for double operation --- packages/client/src/store/ContextOptionsStore.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index fd3bf6a73b..277fa703bc 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -880,6 +880,10 @@ class ContextOptionsStore { toastr.error(t("Files:DocumentEdited")); }; + onShowWaitOperationToast = (t) => { + toastr.warning(t("Files:WaitOperation")); + }; + onClickMute = (e, item, t) => { const data = (e.currentTarget && e.currentTarget.dataset) || e; const { action } = data; @@ -1062,6 +1066,8 @@ class ContextOptionsStore { const showSeparator0 = (hasInfoPanel || !isMedia) && !this.publicRoomStore.isPublicRoom; // || !emailSendIsDisabled; + const { isGroupMenuBlocked } = this.filesActionsStore; + const separator0 = showSeparator0 ? { key: "separator0", @@ -1594,7 +1600,11 @@ class ContextOptionsStore { : t("Common:Delete"), icon: TrashReactSvgUrl, onClick: () => - isEditing ? this.onShowEditingToast(t) : this.onClickDelete(item, t), + isEditing + ? this.onShowEditingToast(t) + : isGroupMenuBlocked + ? this.onShowWaitOperationToast(t) + : this.onClickDelete(item, t), disabled: false, }, { From fdf9149aeab5732559c49d9593e5062bffc5311c Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 31 May 2024 10:30:14 +0300 Subject: [PATCH 104/126] Login: Components: Refactoring. --- .../src/components/LanguageCombobox/index.tsx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/login/src/components/LanguageCombobox/index.tsx b/packages/login/src/components/LanguageCombobox/index.tsx index a784ca4934..aff0a09439 100644 --- a/packages/login/src/components/LanguageCombobox/index.tsx +++ b/packages/login/src/components/LanguageCombobox/index.tsx @@ -26,7 +26,7 @@ "use client"; -import { useCallback, useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { setLanguageForUnauthorized } from "@docspace/shared/utils/common"; @@ -44,15 +44,14 @@ const LanguageComboboxWrapper = () => { const [cultures, setCultures] = useState>(null); - const getData = useCallback(async () => { - const [cultures] = await Promise.all([getPortalCultures()]); - - if (cultures) setCultures(cultures); - }, []); - useEffect(() => { - getData(); - }, [getData]); + const fetchData = async () => { + const cultures = await getPortalCultures(); + if (cultures) setCultures(cultures); + }; + + fetchData(); + }, []); const onLanguageSelect = (culture: { key: string }) => { const { key } = culture; From dc4380ce5427a818d069cae6f970d8010c3f0a1d Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Fri, 31 May 2024 12:28:56 +0300 Subject: [PATCH 105/126] Doceditor:Hooks:UseEditorEvents: update user info for onRequestUser method --- packages/doceditor/src/hooks/useEditorEvents.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/doceditor/src/hooks/useEditorEvents.ts b/packages/doceditor/src/hooks/useEditorEvents.ts index 7dee21c01f..69f725ec2b 100644 --- a/packages/doceditor/src/hooks/useEditorEvents.ts +++ b/packages/doceditor/src/hooks/useEditorEvents.ts @@ -42,8 +42,8 @@ import { import { TEditHistory, TGetReferenceData, + TSharedUsers, } from "@docspace/shared/api/files/types"; -import { TUser } from "@docspace/shared/api/people/types"; import { EDITOR_ID } from "@docspace/shared/constants"; import { assign, @@ -67,7 +67,6 @@ import { THistoryData, UseEventsProps, } from "@/types"; -import { useTranslation } from "react-i18next"; type IConfigEvents = Pick; @@ -87,7 +86,7 @@ const useEditorEvents = ({ const [events, setEvents] = React.useState({}); const [documentReady, setDocumentReady] = React.useState(false); const [createUrl, setCreateUrl] = React.useState>(null); - const [usersInRoom, setUsersInRoom] = React.useState([]); + const [usersInRoom, setUsersInRoom] = React.useState([]); const [docTitle, setDocTitle] = React.useState(""); const [docSaved, setDocSaved] = React.useState(false); @@ -443,6 +442,7 @@ const useEditorEvents = ({ const onSDKRequestUsers = React.useCallback( async (event: object) => { + console.log("====", event); try { const currEvent = event as TEvent; const c = currEvent?.data?.c; @@ -452,16 +452,11 @@ const useEditorEvents = ({ : getSharedUsers(fileInfo.id)); if (c !== "protect") { - const usersArray = users.map( - (item) => - ({ - email: item.email, - name: item.name, - }) as unknown as TUser, - ); - setUsersInRoom(usersArray); + setUsersInRoom(users); } + console.log(users, c); + docEditor?.setUsers?.({ c: c ?? "", users, From ef4146588b1cf2785f8315dcf146bc2dc95ee1d9 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Fri, 31 May 2024 12:32:25 +0300 Subject: [PATCH 106/126] Doceditor: delete console log --- packages/doceditor/src/hooks/useEditorEvents.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/doceditor/src/hooks/useEditorEvents.ts b/packages/doceditor/src/hooks/useEditorEvents.ts index 69f725ec2b..58f1a7ae76 100644 --- a/packages/doceditor/src/hooks/useEditorEvents.ts +++ b/packages/doceditor/src/hooks/useEditorEvents.ts @@ -442,7 +442,6 @@ const useEditorEvents = ({ const onSDKRequestUsers = React.useCallback( async (event: object) => { - console.log("====", event); try { const currEvent = event as TEvent; const c = currEvent?.data?.c; @@ -455,8 +454,6 @@ const useEditorEvents = ({ setUsersInRoom(users); } - console.log(users, c); - docEditor?.setUsers?.({ c: c ?? "", users, From 4feb846b9a0923d9b6727fb48de290766d58dd53 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Fri, 31 May 2024 15:00:58 +0300 Subject: [PATCH 107/126] Fixed Bug 67108: Fixed user-agent autofill styles for TextInput component --- packages/shared/components/text-input/TextInput.styled.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/shared/components/text-input/TextInput.styled.ts b/packages/shared/components/text-input/TextInput.styled.ts index 4ee47d40e4..68d4e18af5 100644 --- a/packages/shared/components/text-input/TextInput.styled.ts +++ b/packages/shared/components/text-input/TextInput.styled.ts @@ -57,6 +57,9 @@ const StyledTextInput = styled(Input).attrs((props) => ({ props.isDisabled ? props.theme.input.disableBackgroundColor : props.theme.input.backgroundColor}; + + -webkit-background-clip: text !important; + -webkit-text-fill-color: ${(props) => props.isDisabled ? props.theme.input.disableColor @@ -65,8 +68,8 @@ const StyledTextInput = styled(Input).attrs((props) => ({ : props.theme.textInput.placeholderColor} !important; caret-color: ${(props) => props.isDisabled ? props.theme.input.disableColor : props.theme.text.color}; - -webkit-background-clip: text !important; - box-shadow: inset 0 0 20px 20px + + box-shadow: inset 0 0 0 30px ${(props) => props.isDisabled ? props.theme.input.disableBackgroundColor From e6a0aeaf7fbac2dc088cabb49e7b6bdb87810549 Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Sat, 1 Jun 2024 15:45:24 +0300 Subject: [PATCH 108/126] Client: FilesActionsStore: fix --- packages/client/src/store/FilesActionsStore.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 0025e1bb7f..aaf5b3fd2f 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -1690,7 +1690,12 @@ class FilesActionStore { case "delete": const canDelete = selection.every((s) => s.security?.Delete); - return !allFilesIsEditing && canDelete && hasSelection; + return ( + !allFilesIsEditing && + !this.isGroupMenuBlocked && + canDelete && + hasSelection + ); case "create-room": const canCreateRoom = selection.some((s) => s.security?.CreateRoomFrom); return canCreateRoom; From dcb5e534a8ad67618d9c640122175079117d4c60 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 3 Jun 2024 10:41:39 +0300 Subject: [PATCH 109/126] fixed SortButton icon ltr --- .../FormGallery/Filter/SortFilter/index.styled.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js index c4a58858b8..35c3ce0d13 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -31,7 +31,15 @@ import { ComboBox } from "@docspace/shared/components/combobox"; export const SortButton = styled.div` .combo-button { - padding-right: 4px; + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + padding-left: 4px; + ` + : css` + padding-right: 4px; + `} + background: ${(props) => props.theme.filterInput.sort.background} !important; From b085df80a840cbb83106ec0c0ad49d9e623d93ce Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 3 Jun 2024 12:39:57 +0300 Subject: [PATCH 110/126] Web: Fixed closing the creation context menu --- .../section/sub-components/SectionBody.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/shared/components/section/sub-components/SectionBody.tsx b/packages/shared/components/section/sub-components/SectionBody.tsx index 4b9a7a7f51..914a2e92c6 100644 --- a/packages/shared/components/section/sub-components/SectionBody.tsx +++ b/packages/shared/components/section/sub-components/SectionBody.tsx @@ -61,6 +61,8 @@ const SectionBody = React.memo( }>(null); const location = useLocation(); + const [isOpen, setIsOpen] = React.useState(false); + const onContextMenu = React.useCallback( (e: MouseEvent | React.MouseEvent) => { const bodyElem = document.getElementsByClassName( @@ -80,11 +82,20 @@ const SectionBody = React.memo( e.stopPropagation(); e.preventDefault(); - if (cmRef.current) cmRef.current.toggle(e); + // if (cmRef.current) cmRef.current.toggle(e); + if (cmRef.current) { + if (!isOpen) cmRef?.current?.show(e); + else cmRef?.current?.hide(e); + setIsOpen(!isOpen); + } }, - [getContextModel], + [getContextModel, isOpen], ); + const onHide = () => { + setIsOpen(false); + }; + const focusSectionBody = React.useCallback(() => { if (focusRef.current) focusRef.current.focus({ preventScroll: true }); }, []); @@ -137,6 +148,7 @@ const SectionBody = React.memo( const contextBlock = ( Date: Mon, 3 Jun 2024 13:20:20 +0300 Subject: [PATCH 111/126] Web: Accounts: Hotkeys: added selectAll support --- packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts | 5 +++++ packages/client/src/pages/Home/Section/AccountsBody/index.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts index a8bbcd66e5..165ff1c495 100644 --- a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts +++ b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts @@ -37,6 +37,7 @@ interface AccountsHotkeysProps { selectUpper: () => void; activateHotkeys: (e: KeyboardEvent) => void; setSelected: (value: string) => void; + selectAll: () => void; } const useAccountsHotkeys = ({ @@ -46,6 +47,7 @@ const useAccountsHotkeys = ({ selectUpper, activateHotkeys, setSelected, + selectAll, }: AccountsHotkeysProps) => { const [isEnabled, setIsEnabled] = useState(true); @@ -107,6 +109,9 @@ const useAccountsHotkeys = ({ hotkeysFilter, ); + // Select all accounts + useHotkeys("shift+a, ctrl+a", selectAll, hotkeysFilter); + // Deselect all accounts useHotkeys("shift+n, ESC", () => setSelected("none"), hotkeysFilter); }; diff --git a/packages/client/src/pages/Home/Section/AccountsBody/index.js b/packages/client/src/pages/Home/Section/AccountsBody/index.js index 49dd3d4de2..2ed921cc98 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/index.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/index.js @@ -56,6 +56,7 @@ const SectionBodyContent = (props) => { setHotkeyCaretStart, setHotkeyCaret, setSelected, + selectAll, } = props; const location = useLocation(); @@ -68,6 +69,7 @@ const SectionBodyContent = (props) => { selectUpper, activateHotkeys, setSelected, + selectAll, }); useEffect(() => { @@ -143,6 +145,7 @@ export default inject(({ peopleStore }) => { setBufferSelection: setPeopleBufferSelection, selectUser, setSelected, + selectAll, } = peopleStore.selectionStore; const { @@ -180,6 +183,7 @@ export default inject(({ peopleStore }) => { setHotkeyCaretStart, setHotkeyCaret, setSelected, + selectAll, }; })( withTranslation(["People", "Common", "PeopleTranslations"])( From f7dc44810425f22abc2f8aa96b1310549ac68f3e Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Mon, 3 Jun 2024 14:46:50 +0300 Subject: [PATCH 112/126] Client: fix --- packages/client/src/HOCs/withHotkeys.js | 7 ++++++- packages/client/src/store/FilesActionsStore.js | 7 +------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/client/src/HOCs/withHotkeys.js b/packages/client/src/HOCs/withHotkeys.js index ab45e8962c..d44590fa4f 100644 --- a/packages/client/src/HOCs/withHotkeys.js +++ b/packages/client/src/HOCs/withHotkeys.js @@ -89,6 +89,8 @@ const withHotkeys = (Component) => { security, copyToClipboard, uploadClipboardFiles, + + isGroupMenuBlocked, } = props; const navigate = useNavigate(); @@ -317,7 +319,7 @@ const withHotkeys = (Component) => { return; } - if (isAvailableOption("delete")) { + if (isAvailableOption("delete") && !isGroupMenuBlocked) { if (isRecentFolder) return; if (isFavoritesFolder) { @@ -460,6 +462,7 @@ const withHotkeys = (Component) => { setFavoriteAction, deleteRooms, archiveRooms, + isGroupMenuBlocked, } = filesActionsStore; const { visible: mediaViewerIsVisible } = mediaViewerDataStore; @@ -533,6 +536,8 @@ const withHotkeys = (Component) => { copyToClipboard, uploadClipboardFiles, + + isGroupMenuBlocked, }; }, )(observer(WithHotkeys)); diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index aaf5b3fd2f..0025e1bb7f 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -1690,12 +1690,7 @@ class FilesActionStore { case "delete": const canDelete = selection.every((s) => s.security?.Delete); - return ( - !allFilesIsEditing && - !this.isGroupMenuBlocked && - canDelete && - hasSelection - ); + return !allFilesIsEditing && canDelete && hasSelection; case "create-room": const canCreateRoom = selection.some((s) => s.security?.CreateRoomFrom); return canCreateRoom; From 838324696c6e3848952cec0260c02ceb33e0f0b9 Mon Sep 17 00:00:00 2001 From: namushka Date: Mon, 3 Jun 2024 15:32:17 +0300 Subject: [PATCH 113/126] fixed SortButton center positioning --- .../FormGallery/Filter/SortFilter/index.styled.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js index 35c3ce0d13..0527e1379a 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -31,15 +31,7 @@ import { ComboBox } from "@docspace/shared/components/combobox"; export const SortButton = styled.div` .combo-button { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - padding-left: 4px; - ` - : css` - padding-right: 4px; - `} - + padding-inline-end: 3px; background: ${(props) => props.theme.filterInput.sort.background} !important; From f50fdbfce152feb58959f4c182f75fb935b69a11 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 3 Jun 2024 17:49:44 +0300 Subject: [PATCH 114/126] Web: Accounts: fixed keydown event unmount --- packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts index 165ff1c495..865fae1e7f 100644 --- a/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts +++ b/packages/client/src/pages/Home/Hooks/useAccountsHotkeys.ts @@ -77,10 +77,10 @@ const useAccountsHotkeys = ({ useEffect(() => { const throttledKeyDownEvent = throttle(onKeyDown, 300); - window.addEventListener("keydown", onKeyDown); + window.addEventListener("keydown", throttledKeyDownEvent); return () => { - window.removeEventListener("keypress", throttledKeyDownEvent); + window.removeEventListener("keydown", throttledKeyDownEvent); }; }, [onKeyDown]); From c2dc1a0578db0069725091ebc32575275e5e3dac Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 5 Jun 2024 12:39:18 +0500 Subject: [PATCH 115/126] Web: Client: Data Import: translations were corrected --- .../AddEmailsStep/AccountsTable/TableView/UsersTableRow.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/AccountsTable/TableView/UsersTableRow.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/AccountsTable/TableView/UsersTableRow.js index 39e3f51ed5..2a7d00e93c 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/AccountsTable/TableView/UsersTableRow.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/AccountsTable/TableView/UsersTableRow.js @@ -178,7 +178,7 @@ const UsersTableRow = ({ {isEmailOpen ? ( - {prevEmail !== "" ? prevEmail : t("EnterEmail")} + {prevEmail !== "" ? prevEmail : t("Settings:NoEmail")} )} From 5a0f1dd8d0d65fd32bb746912948ad6a2f5168f8 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 5 Jun 2024 12:39:33 +0500 Subject: [PATCH 116/126] Web: Client: Data Import: rerenders were fixed --- .../NextCloudWorkspace/Stepper/AddEmailsStep/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js index 049b073ea5..759fe1bc9e 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/AddEmailsStep/index.js @@ -89,7 +89,7 @@ const AddEmailsStep = (props) => { useEffect(() => { setQuota(parseQuota(quotaCharacteristics[1])); - }); + }, []); const totalUsedUsers = quota.used + From 1b8ba6be4f37f906acfa54b5d705fbe8d562cc29 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 5 Jun 2024 13:42:43 +0500 Subject: [PATCH 117/126] Web: Client: Data Import: table group menu spacings --- .../AccountsTable/TableView/index.js | 4 ++-- .../Stepper/SelectUsersTypeStep/index.js | 18 ++++++++--------- .../AccountsTable/TableView/index.js | 4 ++-- .../Stepper/SelectUsersTypeStep/index.js | 20 +++++++++---------- .../AccountsTable/TableView/index.js | 4 ++-- .../Stepper/SelectUsersTypeStep/index.js | 20 +++++++++---------- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js index 91b842c1d0..6c08a8b719 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js @@ -51,11 +51,11 @@ const StyledTableContainer = styled(TableContainer)` position: sticky; z-index: 201; width: calc(100% + 40px); - margin-top: 20px; + margin-top: -33px; margin-left: -20px; top: 0; - margin-bottom: -37.5px; + margin-bottom: -36px; .table-container_group-menu { border-image-slice: 0; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/index.js index 3b6f1eac4e..a3a18b92d5 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersTypeStep/index.js @@ -92,16 +92,14 @@ const SelectUsersTypeStep = ({ {filteredUsers.length > 0 && ( <> - {!checkedUsers.result.length > 0 && ( - - )} + diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js index 2c3452ea26..71688eebd0 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js @@ -49,11 +49,11 @@ const UserSelectTableContainer = styled(StyledTableContainer)` position: sticky; z-index: 201; width: calc(100% + 40px); - margin-top: 20px; + margin-top: -33px; margin-left: -20px; top: 0; - margin-bottom: -37.5px; + margin-bottom: -36px; .table-container_group-menu { border-image-slice: 0; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/index.js index 1a02c48a0d..8dd3cff965 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersTypeStep/index.js @@ -89,17 +89,15 @@ const SelectUsersTypeStep = (props) => { {filteredUsers.length > 0 && ( <> - {!checkedUsers.result.length > 0 && ( - - )} + diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js index 7e8adb5dc6..dbf83d184e 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/AccountsTable/TableView/index.js @@ -51,11 +51,11 @@ const StyledTableContainer = styled(TableContainer)` position: sticky; z-index: 201; width: calc(100% + 40px); - margin-top: 20px; + margin-top: -33px; margin-left: -20px; top: 0; - margin-bottom: -37.5px; + margin-bottom: -36px; .table-container_group-menu { border-image-slice: 0; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/index.js index 39b2d9adc2..fb341bf2e5 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersTypeStep/index.js @@ -86,17 +86,15 @@ const SelectUsersTypeStep = ({ {filteredUsers.length > 0 && ( <> - {!checkedUsers.result.length > 0 && ( - - )} + From f12abb952ca5122820d5aa0b481440f4b72912a8 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 5 Jun 2024 13:20:49 +0300 Subject: [PATCH 118/126] Fix Bug 68367 - Links. The clickable area for the icon has been increased --- .../Home/Section/Body/TableView/StyledTable.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js index 99d35d913c..df994c84e6 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js @@ -438,24 +438,17 @@ const StyledQuickButtonsContainer = styled.div` } .badge { - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 14px; - ` - : css` - margin-right: 14px; - `} + padding: 12px 7px; } .badge:last-child { ${(props) => props.theme.interfaceDirection === "rtl" ? css` - margin-left: 10px; + margin-left: 3px; ` : css` - margin-right: 10px; + margin-right: 3px; `} } From 43a2d375962e109bfc8f0933e77e85c8c326f5a2 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 5 Jun 2024 13:22:21 +0300 Subject: [PATCH 119/126] Web: Files: fixed palm cursor --- .../pages/Home/Section/Body/RowsView/SimpleFilesRow.js | 2 +- .../src/pages/Home/Section/Body/TableView/StyledTable.js | 2 +- public/images/cursor.palm.react.svg | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js b/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js index 4108bfd419..4bdb7634e7 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js @@ -126,7 +126,7 @@ const StyledSimpleFilesRow = styled(Row)` !props.isThirdPartyFolder && (props.checked || props.isActive) && props.canDrag && - `url(${CursorPalmReactSvgUrl}), auto`}; + `url(${CursorPalmReactSvgUrl}) 8 0, auto`}; ${(props) => props.inProgress && css` diff --git a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js index df994c84e6..1c70c17312 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js @@ -148,7 +148,7 @@ const StyledTableRow = styled(TableRow)` !props.isThirdPartyFolder && (props.checked || props.isActive) && props.canDrag && - `url(${CursorPalmSvgUrl}), auto !important`}; + `url(${CursorPalmSvgUrl}) 8 0, auto !important`}; ${(props) => props.inProgress && diff --git a/public/images/cursor.palm.react.svg b/public/images/cursor.palm.react.svg index c08077c4fc..aaa54d67ae 100644 --- a/public/images/cursor.palm.react.svg +++ b/public/images/cursor.palm.react.svg @@ -1,9 +1,9 @@ - + - - + + - + From 8e5a6f654a251a6ea4013a9e4a0cbda97971b947 Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Wed, 5 Jun 2024 16:41:57 +0500 Subject: [PATCH 120/126] Web: Client: Data Import: status pooling was corrected --- .../Stepper/SelectFileStep/index.js | 46 +++++++++------- .../Stepper/SelectUsersStep/index.js | 9 +++- .../Stepper/ImportCompleteStep/index.js | 2 +- .../Stepper/SelectFileStep/index.js | 53 +++++++++++------- .../Stepper/SelectUsersStep/index.js | 9 +++- .../Stepper/ImportCompleteStep/index.js | 2 +- .../Stepper/SelectFileStep/index.js | 54 ++++++++++++------- .../Stepper/SelectUsersStep/index.js | 9 +++- .../client/src/store/ImportAccountsStore.js | 8 ++- 9 files changed, 126 insertions(+), 66 deletions(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js index db908547f7..02322bded8 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectFileStep/index.js @@ -89,6 +89,8 @@ const ErrorBlock = styled.div` } `; +const FAILS_TRIES = 1; + const SelectFileStep = ({ t, onNextStep, @@ -117,9 +119,10 @@ const SelectFileStep = ({ const uploadInterval = useRef(null); const navigate = useNavigate(); + const [failTries, setFailsTries] = useState(FAILS_TRIES); + const goBack = () => { - cancelMigration(); - setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); + navigate("/portal-settings/data-import/migration"); }; const checkMigrationStatusAndUpdate = async () => { @@ -187,7 +190,6 @@ const SelectFileStep = ({ }; const onUploadFile = async (file) => { - setProgress(0); setIsVisible(true); try { if (file.length) { @@ -195,23 +197,18 @@ const SelectFileStep = ({ } else { await singleFileUploading(file, setProgress, isAbort); } + + if (isAbort.current) return; + await initMigrationName(searchParams.get("service")); uploadInterval.current = setInterval(async () => { try { const res = await getMigrationStatus(); - setProgress(res?.progress); - if (res.progress > 10) { - setIsVisible(false); - } else { - setIsVisible(true); - } - - if (res.error || res.parseResult.failedArchives.length > 0) { - setShowErrorText(true); - } else { - setShowErrorText(false); + if (!res && failTries) { + setFailsTries((tries) => tries - 1); + return; } if (!res || res.parseResult.failedArchives.length > 0 || res.error) { @@ -219,12 +216,14 @@ const SelectFileStep = ({ setIsFileError(true); setIsFileLoading(false); clearInterval(uploadInterval.current); - } else if (res.isCompleted || res.parseResult.progress === 100) { + setShowErrorText(true); + return; + } + + if (res.isCompleted || res.parseResult.progress === 100) { clearInterval(uploadInterval.current); setIsFileLoading(false); setIsVisible(false); - setProgress(100); - if ( res.parseResult.users.length + res.parseResult.existUsers.length + @@ -239,12 +238,23 @@ const SelectFileStep = ({ cancelMigration(); } } + + setProgress(res?.progress); + + if (res.progress > 10) { + setIsVisible(false); + } else { + setIsVisible(true); + } + setShowErrorText(false); } catch (error) { toastr.error(error || t("Common:SomethingWentWrong")); setIsFileError(true); setIsFileLoading(false); setIsError(true); clearInterval(uploadInterval.current); + } finally { + isAbort.current = false; } }, 1000); } catch (error) { @@ -259,6 +269,7 @@ const SelectFileStep = ({ setIsFileError(false); setShowReminder(false); setIsFileLoading(true); + setFailsTries(FAILS_TRIES); try { onUploadFile(file); } catch (error) { @@ -286,7 +297,6 @@ const SelectFileStep = ({ }); } catch (error) { toastr.error(error); - console.log(error); } }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js index b1eeb487b6..92c4b333e8 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/GoogleWorkspace/Stepper/SelectUsersStep/index.js @@ -51,6 +51,7 @@ const SelectUsersStep = ({ }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); const [quota, setQuota] = useState({ used: 0, max: 0 }); + const [isSaving, setIsSaving] = useState(false); useEffect(() => { setSearchValue(""); @@ -83,7 +84,11 @@ const SelectUsersStep = ({ const goBack = () => { cancelMigration(); - setTimeout(onPrevStep, 100); + setIsSaving(true); + setTimeout(() => { + setIsSaving(false); + onPrevStep(); + }, 1000); }; const totalUsedUsers = @@ -103,6 +108,7 @@ const SelectUsersStep = ({ saveButtonDisabled={ areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } + isSaving={isSaving} /> {quota.max && ( @@ -147,6 +153,7 @@ const SelectUsersStep = ({ saveButtonDisabled={ areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } + isSaving={isSaving} /> )} diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js index 846a1a85fa..b4bc7e293f 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/ImportCompleteStep/index.js @@ -96,7 +96,7 @@ const ImportCompleteStep = ({ setIsSaving(true); setTimeout(() => { setIsSaving(false); - setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); + navigate("/portal-settings/data-import/migration"); }, 1000); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js index d6847a46ee..2d07fa1c74 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectFileStep/index.js @@ -39,7 +39,6 @@ import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-butto import { Box } from "@docspace/shared/components/box"; import { Link } from "@docspace/shared/components/link"; import { toastr } from "@docspace/shared/components/toast"; -// import { mockRes } from "./tempMock"; const Wrapper = styled.div` max-width: 700px; @@ -101,6 +100,8 @@ const ErrorBlock = styled.div` } `; +const FAILS_TRIES = 1; + const SelectFileStep = ({ t, incrementStep, @@ -125,9 +126,10 @@ const SelectFileStep = ({ const uploadInterval = useRef(null); const navigate = useNavigate(); + const [failTries, setFailsTries] = useState(FAILS_TRIES); + const goBack = () => { - cancelMigration(); - setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); + navigate("/portal-settings/data-import/migration"); }; const checkMigrationStatusAndUpdate = async () => { @@ -188,16 +190,41 @@ const SelectFileStep = ({ }; const onUploadFile = async (file) => { - setProgress(0); setIsVisible(true); try { if (Array.isArray(file)) throw new Error(t("Common:SomethingWentWrong")); + await singleFileUploading(file, setProgress, isAbort); + + if (isAbort.current) return; + await initMigrationName(searchParams.get("service")); uploadInterval.current = setInterval(async () => { try { const res = await getMigrationStatus(); + + if (!res && failTries) { + setFailsTries((tries) => tries - 1); + return; + } + + if (!res || res.parseResult.failedArchives.length > 0 || res.error) { + clearInterval(uploadInterval.current); + setIsFileError(true); + setIsFileLoading(false); + toastr.error(res.error); + return; + } + + if (res.isCompleted || res.parseResult.progress === 100) { + clearInterval(uploadInterval.current); + setIsFileLoading(false); + setIsVisible(false); + setUsers(res.parseResult); + setIsSaveDisabled(true); + } + setProgress(res.progress); if (res.progress > 10) { @@ -205,26 +232,14 @@ const SelectFileStep = ({ } else { setIsVisible(true); } - - if (!res || res.parseResult.failedArchives.length > 0 || res.error) { - toastr.error(res.error); - setIsFileError(true); - setIsFileLoading(false); - clearInterval(uploadInterval.current); - } else if (res.isCompleted || res.parseResult.progress === 100) { - clearInterval(uploadInterval.current); - setIsFileLoading(false); - setIsVisible(false); - setProgress(100); - setUsers(res.parseResult); - setIsSaveDisabled(true); - } } catch (error) { toastr.error(error || error.message); setIsFileError(true); setIsFileLoading(false); setIsError(true); clearInterval(uploadInterval.current); + } finally { + isAbort.current = false; } }, 1000); } catch (error) { @@ -239,6 +254,7 @@ const SelectFileStep = ({ setIsFileError(false); setIsSaveDisabled(false); setIsFileLoading(true); + setFailsTries(FAILS_TRIES); try { onUploadFile(file); } catch (error) { @@ -265,7 +281,6 @@ const SelectFileStep = ({ window.URL.revokeObjectURL(url); }); } catch (error) { - console.log(error); toastr.error(error); } }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js index b8d2aea6a8..92ac4d6dc3 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/NextCloudWorkspace/Stepper/SelectUsersStep/index.js @@ -55,6 +55,7 @@ const SelectUsersStep = (props) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); const [quota, setQuota] = useState({ used: 0, max: 0 }); + const [isSaving, setIsSaving] = useState(false); useEffect(() => { setSearchValue(""); @@ -82,7 +83,11 @@ const SelectUsersStep = (props) => { const goBack = () => { cancelMigration(); - setTimeout(decrementStep, 100); + setIsSaving(true); + setTimeout(() => { + setIsSaving(false); + decrementStep(); + }, 1000); }; const numberOfSelectedUsers = @@ -105,6 +110,7 @@ const SelectUsersStep = (props) => { cancelButtonLabel={t("Common:Back")} showReminder displaySettings + isSaving={isSaving} /> {quota.max && ( @@ -151,6 +157,7 @@ const SelectUsersStep = (props) => { cancelButtonLabel={t("Common:Back")} showReminder displaySettings + isSaving={isSaving} /> )} diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js index 8a928ddf57..7bc6a9f6d8 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/ImportCompleteStep/index.js @@ -107,7 +107,7 @@ const ImportCompleteStep = ({ setIsSaving(true); setTimeout(() => { setIsSaving(false); - setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); + navigate("/portal-settings/data-import/migration") }, 1000); }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js index b94b4e37b9..90cfff10e6 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectFileStep/index.js @@ -89,6 +89,8 @@ const ErrorBlock = styled.div` } `; +const FAILS_TRIES = 1; + const SelectFileStep = ({ t, onNextStep, @@ -115,9 +117,10 @@ const SelectFileStep = ({ const uploadInterval = useRef(null); const navigate = useNavigate(); + const [failTries, setFailsTries] = useState(FAILS_TRIES); + const goBack = () => { - cancelMigration(); - setTimeout(() => navigate("/portal-settings/data-import/migration"), 100); + navigate("/portal-settings/data-import/migration"); }; const checkMigrationStatusAndUpdate = async () => { @@ -178,20 +181,45 @@ const SelectFileStep = ({ }; const onUploadFile = async (file) => { - setProgress(0); setIsVisible(true); try { if (Array.isArray(file)) { setShowErrorText(true); throw new Error(t("Common:SomethingWentWrong")); } + await singleFileUploading(file, setProgress, isAbort); + + if (isAbort.current) return; + await initMigrationName(searchParams.get("service")); uploadInterval.current = setInterval(async () => { try { const res = await getMigrationStatus(); - setProgress(res?.progress); + + if (!res && failTries) { + setFailsTries((tries) => tries - 1); + return; + } + + if (!res || res.parseResult.failedArchives.length > 0 || res.error) { + toastr.error(res.error || t("Common:SomethingWentWrong")); + setIsFileError(true); + setIsFileLoading(false); + clearInterval(uploadInterval.current); + return; + } + + if (res.isCompleted || res.parseResult.progress === 100) { + clearInterval(uploadInterval.current); + setIsFileLoading(false); + setIsVisible(false); + setUsers(res.parseResult); + setShowReminder(true); + } + + setProgress(res.progress); if (res.progress > 10) { setIsVisible(false); @@ -204,26 +232,14 @@ const SelectFileStep = ({ } else { setShowErrorText(false); } - - if (!res || res.parseResult.failedArchives.length > 0 || res.error) { - toastr.error(res.error || t("Common:SomethingWentWrong")); - setIsFileError(true); - setIsFileLoading(false); - clearInterval(uploadInterval.current); - } else if (res.isCompleted || res.parseResult.progress === 100) { - clearInterval(uploadInterval.current); - setIsFileLoading(false); - setIsVisible(false); - setProgress(100); - setUsers(res.parseResult); - setShowReminder(true); - } } catch (error) { toastr.error(error || t("Common:SomethingWentWrong")); setIsFileError(true); setIsFileLoading(false); setIsError(true); clearInterval(uploadInterval.current); + } finally { + isAbort.current = false; } }, 1000); } catch (error) { @@ -238,6 +254,7 @@ const SelectFileStep = ({ setIsFileError(false); setShowReminder(false); setIsFileLoading(true); + setFailsTries(FAILS_TRIES); try { onUploadFile(file); } catch (error) { @@ -265,7 +282,6 @@ const SelectFileStep = ({ }); } catch (error) { toastr.error(error); - console.log(error); } }; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js index b36085c306..d9edfe9301 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js +++ b/packages/client/src/pages/PortalSettings/categories/data-import/OnlyofficeWorkspace/Stepper/SelectUsersStep/index.js @@ -51,6 +51,7 @@ const SelectUsersStep = ({ }) => { const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25)); const [quota, setQuota] = useState({ used: 0, max: 0 }); + const [isSaving, setIsSaving] = useState(false); useEffect(() => { setSearchValue(""); @@ -83,7 +84,11 @@ const SelectUsersStep = ({ const goBack = () => { cancelMigration(); - setTimeout(onPrevStep, 100); + setIsSaving(true); + setTimeout(() => { + setIsSaving(false); + onPrevStep(); + }, 1000); }; const totalUsedUsers = @@ -103,6 +108,7 @@ const SelectUsersStep = ({ saveButtonDisabled={ areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } + isSaving={isSaving} /> {quota.max && ( @@ -147,6 +153,7 @@ const SelectUsersStep = ({ saveButtonDisabled={ areCheckedUsersEmpty || (quota.max && totalUsedUsers > quota.max) } + isSaving={isSaving} /> )} diff --git a/packages/client/src/store/ImportAccountsStore.js b/packages/client/src/store/ImportAccountsStore.js index c3cf34ee2f..724e0bbf32 100644 --- a/packages/client/src/store/ImportAccountsStore.js +++ b/packages/client/src/store/ImportAccountsStore.js @@ -102,7 +102,9 @@ class ImportAccountsStore { get filteredUsers() { return this.users.result.filter( (user) => - !this.users.existing.some((existingUser) => existingUser.key === user.key), + !this.users.existing.some( + (existingUser) => existingUser.key === user.key, + ), ); } @@ -290,8 +292,6 @@ class ImportAccountsStore { } } catch (e) { console.error(e); - } finally { - isAbort.current = false; } }; @@ -331,8 +331,6 @@ class ImportAccountsStore { } } catch (e) { console.error(e); - } finally { - isAbort.current = false; } }; From e175300d72ebc8a23aede42889136b9a45881b8c Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Wed, 5 Jun 2024 15:04:15 +0300 Subject: [PATCH 121/126] Fixed Bug 68325: SDK: Infinite loader when opening a document with a password. Call setIsLoaded after onAppReady editor event --- packages/doceditor/src/hooks/useEditorEvents.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/doceditor/src/hooks/useEditorEvents.ts b/packages/doceditor/src/hooks/useEditorEvents.ts index 58f1a7ae76..a41c05e779 100644 --- a/packages/doceditor/src/hooks/useEditorEvents.ts +++ b/packages/doceditor/src/hooks/useEditorEvents.ts @@ -141,6 +141,8 @@ const useEditorEvents = ({ const onSDKAppReady = React.useCallback(() => { docEditor = window.DocEditor.instances[EDITOR_ID]; + frameCallCommand("setIsLoaded"); + if (errorMessage || isSkipError) return docEditor?.showMessage?.(errorMessage || t("Common:InvalidLink")); @@ -167,8 +169,6 @@ const useEditorEvents = ({ // console.log("onDocumentReady", { docEditor }); setDocumentReady(true); - frameCallCommand("setIsLoaded"); - if (config?.errorMessage) docEditor?.showMessage?.(config.errorMessage); // if (config?.file?.canShare) { From 4330881958e411cbfcbd8462920d85c03b9f6261 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Wed, 5 Jun 2024 15:05:54 +0300 Subject: [PATCH 122/126] Client: CreateEvent: Added hash to document creation method --- packages/client/src/components/GlobalEvents/CreateEvent.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/client/src/components/GlobalEvents/CreateEvent.js b/packages/client/src/components/GlobalEvents/CreateEvent.js index adb924fffe..c41ad944a2 100644 --- a/packages/client/src/components/GlobalEvents/CreateEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateEvent.js @@ -184,6 +184,8 @@ const CreateEvent = ({ searchParams.append("formId", gallerySelected.id); } + searchParams.append("hash", new Date().getTime()); + const url = combineUrl( window.location.origin, window.DocSpaceConfig?.proxy?.url, @@ -191,6 +193,8 @@ const CreateEvent = ({ `/doceditor/create?${searchParams.toString()}`, ); + console.log(url); + window.open(url, openOnNewPage ? "_blank" : "_self"); setIsLoading(false); From c28e661d7a74fa5e68351352fc8bc481acc7fe3d Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Wed, 5 Jun 2024 15:06:23 +0300 Subject: [PATCH 123/126] Client: ConvertPasswordDialog: Added hash to document creation method --- .../src/components/dialogs/ConvertPasswordDialog/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js b/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js index 3b9340f5fc..72ddb716b8 100644 --- a/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js +++ b/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js @@ -103,6 +103,8 @@ const ConvertPasswordDialogComponent = (props) => { searchParams.append("password", password); searchParams.append("fromFile", true); + searchParams.append("hash", new Date().getTime()); + const url = combineUrl( window.location.origin, window.DocSpaceConfig?.proxy?.url, From 5f69578ee897c425ecd0c2ddb0bd3ecf043336b5 Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Wed, 5 Jun 2024 15:06:57 +0300 Subject: [PATCH 124/126] Client: CreateEvent: Removed log --- packages/client/src/components/GlobalEvents/CreateEvent.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/client/src/components/GlobalEvents/CreateEvent.js b/packages/client/src/components/GlobalEvents/CreateEvent.js index c41ad944a2..d03698837d 100644 --- a/packages/client/src/components/GlobalEvents/CreateEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateEvent.js @@ -193,8 +193,6 @@ const CreateEvent = ({ `/doceditor/create?${searchParams.toString()}`, ); - console.log(url); - window.open(url, openOnNewPage ? "_blank" : "_self"); setIsLoading(false); From dbede6ca0130bd9a97b794655bb362ddaae5ffc2 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 5 Jun 2024 15:52:38 +0300 Subject: [PATCH 125/126] Web: Hotkeys: fixed translations --- packages/client/public/locales/ar-SA/HotkeysPanel.json | 2 -- packages/client/public/locales/az/HotkeysPanel.json | 2 -- packages/client/public/locales/bg/HotkeysPanel.json | 2 -- packages/client/public/locales/cs/HotkeysPanel.json | 2 -- packages/client/public/locales/de/HotkeysPanel.json | 2 -- packages/client/public/locales/el-GR/HotkeysPanel.json | 2 -- packages/client/public/locales/en/HotkeysPanel.json | 2 -- packages/client/public/locales/es/HotkeysPanel.json | 2 -- packages/client/public/locales/fi/HotkeysPanel.json | 2 -- packages/client/public/locales/fr/HotkeysPanel.json | 2 -- packages/client/public/locales/hy-AM/HotkeysPanel.json | 2 -- packages/client/public/locales/it/HotkeysPanel.json | 2 -- packages/client/public/locales/ja-JP/HotkeysPanel.json | 2 -- packages/client/public/locales/ko-KR/HotkeysPanel.json | 2 -- packages/client/public/locales/lo-LA/HotkeysPanel.json | 2 -- packages/client/public/locales/lv/HotkeysPanel.json | 2 -- packages/client/public/locales/nl/HotkeysPanel.json | 2 -- packages/client/public/locales/pl/HotkeysPanel.json | 2 -- packages/client/public/locales/pt-BR/HotkeysPanel.json | 2 -- packages/client/public/locales/pt/HotkeysPanel.json | 2 -- packages/client/public/locales/ro/HotkeysPanel.json | 2 -- packages/client/public/locales/ru/HotkeysPanel.json | 2 -- packages/client/public/locales/si/HotkeysPanel.json | 2 -- packages/client/public/locales/sk/HotkeysPanel.json | 2 -- packages/client/public/locales/sl/HotkeysPanel.json | 2 -- packages/client/public/locales/sr-Latn-RS/HotkeysPanel.json | 2 -- packages/client/public/locales/tr/HotkeysPanel.json | 2 -- packages/client/public/locales/uk-UA/HotkeysPanel.json | 2 -- packages/client/public/locales/vi/HotkeysPanel.json | 2 -- packages/client/public/locales/zh-CN/HotkeysPanel.json | 2 -- .../client/src/components/panels/HotkeysPanel/ActionsBlock.js | 2 +- .../src/components/panels/HotkeysPanel/PreviewActionsBlock.js | 2 +- 32 files changed, 2 insertions(+), 62 deletions(-) diff --git a/packages/client/public/locales/ar-SA/HotkeysPanel.json b/packages/client/public/locales/ar-SA/HotkeysPanel.json index 69328f3688..349f26523c 100644 --- a/packages/client/public/locales/ar-SA/HotkeysPanel.json +++ b/packages/client/public/locales/ar-SA/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "أنشئ جدول بيانات", "HotkeysCreatingObjects": "إنشاء العناصر", "HotkeysCutSelected": "قص العناصر المحددة إلى الحافظة.", - "HotkeysEnterKey": "ادخل", "HotkeysExtendSelectionDown": "تمديد التحديد لأسفل", "HotkeysExtendSelectionLeft": "تمديد التحديد لليسار", "HotkeysExtendSelectionRight": "تمديد التحديد لليمين", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "حدد العنصر التالي على اليمين", "HotkeysSelectUp": "حدد العنصر التالي لأعلى", "HotkeysShortcuts": "عرض قائمة مفاتيح الاخصار للوحة المفاتيح", - "HotkeysSpaceKey": "إستضافة", "HotkeysUndoLastAction": "التراجع عن الإجراء الأخير", "HotkeysUploadFile": "ارفع الملف", "HotkeysUploadingObjects": "رفع العناصر", diff --git a/packages/client/public/locales/az/HotkeysPanel.json b/packages/client/public/locales/az/HotkeysPanel.json index 990302c476..cc74a59768 100644 --- a/packages/client/public/locales/az/HotkeysPanel.json +++ b/packages/client/public/locales/az/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Cədvəl yarat", "HotkeysCreatingObjects": "Elementlərin yaradılması", "HotkeysCutSelected": "Seçilmiş elementləri mübadilə buferinə kopyalayın", - "HotkeysEnterKey": "Daxil olun", "HotkeysExtendSelectionDown": "Seçimi sağa doğru uzadın", "HotkeysExtendSelectionLeft": "Seçimi sola doğru uzadın", "HotkeysExtendSelectionRight": "Seçimi sağa doğru uzadın", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Sağdakı növbəti elementi seçin", "HotkeysSelectUp": "Yuxarıdakı növbəti elementi seçin", "HotkeysShortcuts": "Klaviaturadakı qısayollar siyahısını göstərin", - "HotkeysSpaceKey": "Boşluq", "HotkeysUndoLastAction": "Son hərəkəti ləğv edin", "HotkeysUploadFile": "Fayl yüklə", "HotkeysUploadingObjects": "Elementlərin yüklənilməsi", diff --git a/packages/client/public/locales/bg/HotkeysPanel.json b/packages/client/public/locales/bg/HotkeysPanel.json index 11340a1ba8..99df0fb4b8 100644 --- a/packages/client/public/locales/bg/HotkeysPanel.json +++ b/packages/client/public/locales/bg/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Създайте таблица", "HotkeysCreatingObjects": "Създаване на елементи", "HotkeysCutSelected": "Изрежи избраните елементи в клипборда", - "HotkeysEnterKey": "Влез", "HotkeysExtendSelectionDown": "Разширяване на избора надолу", "HotkeysExtendSelectionLeft": "Разширяване на избора вляво", "HotkeysExtendSelectionRight": "Разширете избора надясно", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Изберете следващия елемент вдясно", "HotkeysSelectUp": "Изберете следващия елемент нагоре", "HotkeysShortcuts": "Показване на списък с клавишни комбинации на клавиатурата", - "HotkeysSpaceKey": "Пространство", "HotkeysUndoLastAction": "Отмяна на последното действие", "HotkeysUploadFile": "Качи файл", "HotkeysUploadingObjects": "Качване на елементи", diff --git a/packages/client/public/locales/cs/HotkeysPanel.json b/packages/client/public/locales/cs/HotkeysPanel.json index 8d81148e85..e29529f85e 100644 --- a/packages/client/public/locales/cs/HotkeysPanel.json +++ b/packages/client/public/locales/cs/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Vytvořit tabulku", "HotkeysCreatingObjects": "Vytváření položek", "HotkeysCutSelected": "Vyjmutí vybraných položek do schránky", - "HotkeysEnterKey": "Zadat", "HotkeysExtendSelectionDown": "Rozšířit výběr dolů", "HotkeysExtendSelectionLeft": "Rozšířit výběr vlevo", "HotkeysExtendSelectionRight": "Rozšířit výběr doprava", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Vybrat další položku vpravo", "HotkeysSelectUp": "Vybrat další položku nahoru", "HotkeysShortcuts": "Zobrazit seznam klávesových zkratek", - "HotkeysSpaceKey": "Mezera", "HotkeysUndoLastAction": "Vrátit poslední akci", "HotkeysUploadFile": "Nahrát soubor", "HotkeysUploadingObjects": "Nahrávání položek", diff --git a/packages/client/public/locales/de/HotkeysPanel.json b/packages/client/public/locales/de/HotkeysPanel.json index 5bb33811aa..2a49913184 100644 --- a/packages/client/public/locales/de/HotkeysPanel.json +++ b/packages/client/public/locales/de/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Eine Tabelle erstellen", "HotkeysCreatingObjects": "Erstellen von Elementen", "HotkeysCutSelected": "Ausgewählte Elemente in der Zwischenablage ausschneiden", - "HotkeysEnterKey": "Eingeben", "HotkeysExtendSelectionDown": "Auswahl nach unten erweitern", "HotkeysExtendSelectionLeft": "Auswahl nach links erweitern", "HotkeysExtendSelectionRight": "Auswahl nach rechts erweitern", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Nächstes Element nach rechts auswählen", "HotkeysSelectUp": "Nächstes Element nach oben auswählen", "HotkeysShortcuts": "Liste der Tastenkombinationen anzeigen", - "HotkeysSpaceKey": "Leerzeichen", "HotkeysUndoLastAction": "Rückgängig machen", "HotkeysUploadFile": "Datei hochladen", "HotkeysUploadingObjects": "Hochladen von Elementen", diff --git a/packages/client/public/locales/el-GR/HotkeysPanel.json b/packages/client/public/locales/el-GR/HotkeysPanel.json index a3e68e78bb..dd418c3973 100644 --- a/packages/client/public/locales/el-GR/HotkeysPanel.json +++ b/packages/client/public/locales/el-GR/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Δημιουργία υπολογιστικού φύλλου", "HotkeysCreatingObjects": "Δημιουργία στοιχείων", "HotkeysCutSelected": "Αποκοπή επιλεγμένων στοιχείων στο πρόχειρο", - "HotkeysEnterKey": "Εισαγωγή", "HotkeysExtendSelectionDown": "Επέκταση της επιλογής προς τα κάτω", "HotkeysExtendSelectionLeft": "Επέκταση της επιλογής αριστερά", "HotkeysExtendSelectionRight": "Επέκταση της επιλογής δεξιά", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Επιλέξτε το επόμενο στοιχείο στα δεξιά", "HotkeysSelectUp": "Επιλέξτε το επόμενο στοιχείο επάνω", "HotkeysShortcuts": "Εμφάνιση λίστας πλήκτρων συντομεύσεων πληκτρολογίου", - "HotkeysSpaceKey": "Κενό διάστημα", "HotkeysUndoLastAction": "Αναίρεση της τελευταίας ενέργειας", "HotkeysUploadFile": "Μεταφόρτωση αρχείου", "HotkeysUploadingObjects": "Μεταφόρτωση στοιχείων", diff --git a/packages/client/public/locales/en/HotkeysPanel.json b/packages/client/public/locales/en/HotkeysPanel.json index 8efcbd803c..314d23ad1e 100644 --- a/packages/client/public/locales/en/HotkeysPanel.json +++ b/packages/client/public/locales/en/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Create spreadsheet", "HotkeysCreatingObjects": "Creating items", "HotkeysCutSelected": "Cut selected items to the clipboard", - "HotkeysEnterKey": "Enter", "HotkeysExtendSelectionDown": "Extend selection down", "HotkeysExtendSelectionLeft": "Extend selection left", "HotkeysExtendSelectionRight": "Extend selection right", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Select next item to the right", "HotkeysSelectUp": "Select next item up", "HotkeysShortcuts": "Display keyboard hotkeys list", - "HotkeysSpaceKey": "Space", "HotkeysUndoLastAction": "Undo the last action", "HotkeysUploadFile": "Upload file", "HotkeysUploadingObjects": "Uploading items", diff --git a/packages/client/public/locales/es/HotkeysPanel.json b/packages/client/public/locales/es/HotkeysPanel.json index 19d9c2f56b..5dbdcb6826 100644 --- a/packages/client/public/locales/es/HotkeysPanel.json +++ b/packages/client/public/locales/es/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Crear hoja de cálculo", "HotkeysCreatingObjects": "Creando elementos", "HotkeysCutSelected": "Cortar los elementos seleccionados en el portapapeles", - "HotkeysEnterKey": "Introducir", "HotkeysExtendSelectionDown": "Ampliar la selección hacia abajo", "HotkeysExtendSelectionLeft": "Ampliar la selección hacia la izquierda", "HotkeysExtendSelectionRight": "Ampliar la selección hacia la derecha", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Seleccionar el siguiente elemento hacia la derecha", "HotkeysSelectUp": "Seleccionar el siguiente elemento hacia arriba", "HotkeysShortcuts": "Mostrar la lista de atajos de teclado", - "HotkeysSpaceKey": "Espacio", "HotkeysUndoLastAction": "Deshacer la última acción", "HotkeysUploadFile": "Cargar archivo", "HotkeysUploadingObjects": "Cargando elementos", diff --git a/packages/client/public/locales/fi/HotkeysPanel.json b/packages/client/public/locales/fi/HotkeysPanel.json index c772c35463..7f9218108a 100644 --- a/packages/client/public/locales/fi/HotkeysPanel.json +++ b/packages/client/public/locales/fi/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Luo laskentataulukko", "HotkeysCreatingObjects": "Kohteiden luominen", "HotkeysCutSelected": "Leikkaa valitut kohteet leikepöydälle", - "HotkeysEnterKey": "Syötä", "HotkeysExtendSelectionDown": "Laajenna valintaa alaspäin", "HotkeysExtendSelectionLeft": "Laajenna valintaa vasemmalle", "HotkeysExtendSelectionRight": "Laajenna valintaa oikealle", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Valitse seuraava kohde oikealta", "HotkeysSelectUp": "Valitse seuraava kohde yltä", "HotkeysShortcuts": "Näytä näppäimistön pikanäppäinten luettelo", - "HotkeysSpaceKey": "Väli", "HotkeysUndoLastAction": "Kumoa viimeinen toiminto", "HotkeysUploadFile": "Lataa tiedosto", "HotkeysUploadingObjects": "Kohteiden lataaminen", diff --git a/packages/client/public/locales/fr/HotkeysPanel.json b/packages/client/public/locales/fr/HotkeysPanel.json index ce10eb0eea..33f4f5d30c 100644 --- a/packages/client/public/locales/fr/HotkeysPanel.json +++ b/packages/client/public/locales/fr/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Créer une feuille de calcul", "HotkeysCreatingObjects": "Création d'éléments", "HotkeysCutSelected": "Couper les éléments sélectionnés dans le presse-papiers", - "HotkeysEnterKey": "Entrer", "HotkeysExtendSelectionDown": "Étendre la sélection vers le bas", "HotkeysExtendSelectionLeft": "Étendre la sélection vers la gauche", "HotkeysExtendSelectionRight": "Étendre la sélection vers la droite", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Sélectionner l'élément suivant à droite", "HotkeysSelectUp": "Sélectionner l'élément suivant vers le haut", "HotkeysShortcuts": "Afficher la liste des raccourcis clavier", - "HotkeysSpaceKey": "Espace", "HotkeysUndoLastAction": "Annuler la dernière action", "HotkeysUploadFile": "Télécharger le fichier", "HotkeysUploadingObjects": "Chargement d'éléments", diff --git a/packages/client/public/locales/hy-AM/HotkeysPanel.json b/packages/client/public/locales/hy-AM/HotkeysPanel.json index 65b18b4f89..de59c1d04f 100644 --- a/packages/client/public/locales/hy-AM/HotkeysPanel.json +++ b/packages/client/public/locales/hy-AM/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Ստեղծել աղյուսակաթերթ", "HotkeysCreatingObjects": "Միավորների ստեղծում", "HotkeysCutSelected": "Կտրեք ընտրված տարրերը սեղմատախտակի վրա", - "HotkeysEnterKey": "Մուտքագրել", "HotkeysExtendSelectionDown": "Ընդարձակում է ընտրարկումը վար", "HotkeysExtendSelectionLeft": "Ընդարձակում է ընտրարկումը ձախ", "HotkeysExtendSelectionRight": "Ընդարձակում է ընտրարկումը աջ", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Ընտրեք հաջորդ միավորը ձախ կողմում", "HotkeysSelectUp": "Ընտրեք հաջորդ միավորը աջ կողմում", "HotkeysShortcuts": "Ցուցադրել ստեղնաշարի թեժ ստեղների ցանկը", - "HotkeysSpaceKey": "Բացատ", "HotkeysUndoLastAction": "Հետարկել վերջին գործողությունը", "HotkeysUploadFile": "Վերբեռնել ֆայլը", "HotkeysUploadingObjects": "Միավորների վերբեռնում", diff --git a/packages/client/public/locales/it/HotkeysPanel.json b/packages/client/public/locales/it/HotkeysPanel.json index 68a7c848c9..982935e04d 100644 --- a/packages/client/public/locales/it/HotkeysPanel.json +++ b/packages/client/public/locales/it/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Creare foglio di calcolo", "HotkeysCreatingObjects": "Creazione elementi", "HotkeysCutSelected": "Tagliare gli elementi selezionati negli appunti", - "HotkeysEnterKey": "Invio", "HotkeysExtendSelectionDown": "Estendere la selezione verso il basso", "HotkeysExtendSelectionLeft": "Estendere la selezione a sinistra", "HotkeysExtendSelectionRight": "Estendere la selezione a destra", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Selezionare l'elemento successivo a destra", "HotkeysSelectUp": "Selezionare l'elemento successivo in alto", "HotkeysShortcuts": "Visualizzare l'elenco dei tasti di scelta rapida della tastiera", - "HotkeysSpaceKey": "Spazio", "HotkeysUndoLastAction": "Annullare l'ultima azione", "HotkeysUploadFile": "Caricare file", "HotkeysUploadingObjects": "Caricamento elementi", diff --git a/packages/client/public/locales/ja-JP/HotkeysPanel.json b/packages/client/public/locales/ja-JP/HotkeysPanel.json index 9a697940cd..944605c03e 100644 --- a/packages/client/public/locales/ja-JP/HotkeysPanel.json +++ b/packages/client/public/locales/ja-JP/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "スプレッドシートを作成する", "HotkeysCreatingObjects": "アイテムの作成", "HotkeysCutSelected": "選択した項目をクリップボードにカット", - "HotkeysEnterKey": "入力", "HotkeysExtendSelectionDown": "選択範囲の拡大(下)", "HotkeysExtendSelectionLeft": "選択範囲の拡大(左)", "HotkeysExtendSelectionRight": "選択範囲の拡大(右)", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "次のアイテムを選択(右)", "HotkeysSelectUp": "次のアイテムを選択(上)", "HotkeysShortcuts": "キーボードのホットキーリストを表示", - "HotkeysSpaceKey": "スペース", "HotkeysUndoLastAction": "直前のアクションを元に戻す", "HotkeysUploadFile": "ファイルをアップロード", "HotkeysUploadingObjects": "アイテムのアップロード", diff --git a/packages/client/public/locales/ko-KR/HotkeysPanel.json b/packages/client/public/locales/ko-KR/HotkeysPanel.json index 88c489d637..98f17f5154 100644 --- a/packages/client/public/locales/ko-KR/HotkeysPanel.json +++ b/packages/client/public/locales/ko-KR/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "스프레드 시트를 만듭니다", "HotkeysCreatingObjects": "항목 생성", "HotkeysCutSelected": "선택한 항목을 클립보드로 잘라내기", - "HotkeysEnterKey": "입력", "HotkeysExtendSelectionDown": "아래쪽으로 선택 확장", "HotkeysExtendSelectionLeft": "왼쪽으로 선택 확장", "HotkeysExtendSelectionRight": "오른쪽으로 선택 확장", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "오른쪽으로 다음 항목 선택", "HotkeysSelectUp": "위로 다음 항목 선택", "HotkeysShortcuts": "키보드 단축키 목록 표시", - "HotkeysSpaceKey": "공간", "HotkeysUndoLastAction": "마지막 작업 실행 취소", "HotkeysUploadFile": "파일 업로드", "HotkeysUploadingObjects": "항목 업로드", diff --git a/packages/client/public/locales/lo-LA/HotkeysPanel.json b/packages/client/public/locales/lo-LA/HotkeysPanel.json index bef37d9f7b..508bb560e8 100644 --- a/packages/client/public/locales/lo-LA/HotkeysPanel.json +++ b/packages/client/public/locales/lo-LA/HotkeysPanel.json @@ -12,7 +12,6 @@ "HotkeysCreatePresentation": "ສ້າງການນໍາສະເຫນີ", "HotkeysCreateSpreadsheet": "ສ້າງຕາຕະລາງ", "HotkeysCreatingObjects": "ການສ້າງລາຍການ", - "HotkeysEnterKey": "ເຂົ້າ", "HotkeysExtendSelectionDown": "ຂະຫຍາຍການເລືອກລົງ", "HotkeysExtendSelectionLeft": "ຂະຫຍາຍການເລືອກຊ້າຍ", "HotkeysExtendSelectionRight": "ຂະຫຍາຍການເລືອກທີ່ຖືກຕ້ອງ", @@ -36,7 +35,6 @@ "HotkeysSelectRight": "ເລືອກລາຍການຕໍ່ໄປໄປທາງຂວາ", "HotkeysSelectUp": "ເລືອກລາຍການຕໍ່ໄປ", "HotkeysShortcuts": "ສະແດງລາຍການຄີບອດແປ້ນພິມ", - "HotkeysSpaceKey": "ຍະຫວ່າງ", "HotkeysUndoLastAction": "ຍົກເລີກການກະ ທຳ ສຸດທ້າຍ", "HotkeysUploadFile": "ອັບໂຫລດໄຟລ໌", "HotkeysUploadingObjects": "ການອັບໂຫລດລາຍການ" diff --git a/packages/client/public/locales/lv/HotkeysPanel.json b/packages/client/public/locales/lv/HotkeysPanel.json index c6879b5fc6..19a698dea7 100644 --- a/packages/client/public/locales/lv/HotkeysPanel.json +++ b/packages/client/public/locales/lv/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Izveidot tabulu", "HotkeysCreatingObjects": "Izveidot vienumus", "HotkeysCutSelected": "Izgrieziet atlasītos vienumus starpliktuvē", - "HotkeysEnterKey": "Ievadīt", "HotkeysExtendSelectionDown": "Paplašināt atlasi uz leju", "HotkeysExtendSelectionLeft": "Paplašināt atlasi pa kreisi", "HotkeysExtendSelectionRight": "Paplašināt atlasi pa labi", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Atlasīt nākamo vienumu pa labi", "HotkeysSelectUp": "Izvēlēties nākamo vienumu uz augšu", "HotkeysShortcuts": "Parādīt tastatūras karsto taustiņu sarakstu", - "HotkeysSpaceKey": "Atstarpe", "HotkeysUndoLastAction": "Atsaukt pēdējo darbību", "HotkeysUploadFile": "Augšupielādēt failu", "HotkeysUploadingObjects": "Notiek vienumu augšupielāde", diff --git a/packages/client/public/locales/nl/HotkeysPanel.json b/packages/client/public/locales/nl/HotkeysPanel.json index c5baa5160d..835ef83b40 100644 --- a/packages/client/public/locales/nl/HotkeysPanel.json +++ b/packages/client/public/locales/nl/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Spreadsheet maken", "HotkeysCreatingObjects": "Items aanmaken", "HotkeysCutSelected": "Knip geselecteerde items naar het klembord", - "HotkeysEnterKey": "Invoeren", "HotkeysExtendSelectionDown": "Selectie uitbreiden naar beneden", "HotkeysExtendSelectionLeft": "Selectie naar links uitbreiden", "HotkeysExtendSelectionRight": "Selectie naar rechts uitbreiden", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Kies het volgende item aan de rechterkant", "HotkeysSelectUp": "Kies het volgende item omhoog", "HotkeysShortcuts": "Lijst met sneltoetsen weergeven", - "HotkeysSpaceKey": "Spatie", "HotkeysUndoLastAction": "Laatste actie ongedaan maken", "HotkeysUploadFile": "Bestand uploaden", "HotkeysUploadingObjects": "Items uploaden", diff --git a/packages/client/public/locales/pl/HotkeysPanel.json b/packages/client/public/locales/pl/HotkeysPanel.json index e9965ff27d..e6b0d77dd8 100644 --- a/packages/client/public/locales/pl/HotkeysPanel.json +++ b/packages/client/public/locales/pl/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Utwórz arkusz kalkulacyjny", "HotkeysCreatingObjects": "Tworzenie elementów", "HotkeysCutSelected": "Wytnij zaznaczone pliki do schowka", - "HotkeysEnterKey": "Wpisz", "HotkeysExtendSelectionDown": "Rozszerz zaznaczenie w dół", "HotkeysExtendSelectionLeft": "Rozszerz zaznaczenie w lewo", "HotkeysExtendSelectionRight": "Rozszerz zaznaczenie w prawo", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Zaznacz kolejny element po prawej", "HotkeysSelectUp": "Zaznacz kolejny element powyżej", "HotkeysShortcuts": "Wyświetl listę skrótów klawiaturowych", - "HotkeysSpaceKey": "Odstęp", "HotkeysUndoLastAction": "Cofnij ostatnią akcję", "HotkeysUploadFile": "Przesyłanie pliku", "HotkeysUploadingObjects": "Wgrywanie elementów", diff --git a/packages/client/public/locales/pt-BR/HotkeysPanel.json b/packages/client/public/locales/pt-BR/HotkeysPanel.json index 8454d35869..5e8c72c9e4 100644 --- a/packages/client/public/locales/pt-BR/HotkeysPanel.json +++ b/packages/client/public/locales/pt-BR/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Criar Planilha", "HotkeysCreatingObjects": "Criar itens", "HotkeysCutSelected": "Cortar itens selecionados para a área de transferência", - "HotkeysEnterKey": "Inserir", "HotkeysExtendSelectionDown": "Estender seleção para baixo", "HotkeysExtendSelectionLeft": "Estender seleção para a esquerda", "HotkeysExtendSelectionRight": "Estender seleção para a direita", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Selecionar o próximo item à direita", "HotkeysSelectUp": "Selecionar o próximo item acima", "HotkeysShortcuts": "Exibir lista de teclas de acesso do teclado", - "HotkeysSpaceKey": "Espaço", "HotkeysUndoLastAction": "Desfazer a última ação", "HotkeysUploadFile": "Carregar arquivo", "HotkeysUploadingObjects": "Fazer upload de itens", diff --git a/packages/client/public/locales/pt/HotkeysPanel.json b/packages/client/public/locales/pt/HotkeysPanel.json index 755180778a..2bd974411f 100644 --- a/packages/client/public/locales/pt/HotkeysPanel.json +++ b/packages/client/public/locales/pt/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Criar folha de cálculo", "HotkeysCreatingObjects": "A criar itens", "HotkeysCutSelected": "Cortar itens selecionados para a área de transferência", - "HotkeysEnterKey": "Introduzir", "HotkeysExtendSelectionDown": "Expandir a seleção para baixo", "HotkeysExtendSelectionLeft": "Expandir a seleção para a esquerda", "HotkeysExtendSelectionRight": "Expandir a seleção para a direita", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Selecionar o próximo item à direita", "HotkeysSelectUp": "Selecionar o próximo item acima", "HotkeysShortcuts": "Mostrar lista de teclas de atalho", - "HotkeysSpaceKey": "Espaço", "HotkeysUndoLastAction": "Anular a última ação", "HotkeysUploadFile": "Carregar ficheiro", "HotkeysUploadingObjects": "A carregar itens", diff --git a/packages/client/public/locales/ro/HotkeysPanel.json b/packages/client/public/locales/ro/HotkeysPanel.json index cc99dbca30..8161c8cbb5 100644 --- a/packages/client/public/locales/ro/HotkeysPanel.json +++ b/packages/client/public/locales/ro/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Creează o foaie de calcul", "HotkeysCreatingObjects": "Creează elemente", "HotkeysCutSelected": "Decupare elemente selectate în clipboard", - "HotkeysEnterKey": "Enter", "HotkeysExtendSelectionDown": "Extinde selecția în jos", "HotkeysExtendSelectionLeft": "Extinde selecția la stânga", "HotkeysExtendSelectionRight": "Extinde selecția la dreapta", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Selectează următorul element din dreapta", "HotkeysSelectUp": "Selectează următorul element de deasupra", "HotkeysShortcuts": "Afișează lista de comenzi rapide de la tastatură", - "HotkeysSpaceKey": "Spațiu", "HotkeysUndoLastAction": "Anulează ultima acțiune", "HotkeysUploadFile": "Încarcă fișier", "HotkeysUploadingObjects": "Încărcare elemente", diff --git a/packages/client/public/locales/ru/HotkeysPanel.json b/packages/client/public/locales/ru/HotkeysPanel.json index e2f8a917be..dedd2bb8f2 100644 --- a/packages/client/public/locales/ru/HotkeysPanel.json +++ b/packages/client/public/locales/ru/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Создать таблицу", "HotkeysCreatingObjects": "Создание объектов", "HotkeysCutSelected": "Вырезать выбранные элементы в буфер обмена", - "HotkeysEnterKey": "Ввод", "HotkeysExtendSelectionDown": "Расширить выделение вниз", "HotkeysExtendSelectionLeft": "Расширить выделение влево", "HotkeysExtendSelectionRight": "Расширить выделение вправо", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Выделить следующий объект справа", "HotkeysSelectUp": "Выделить следующий объект сверху", "HotkeysShortcuts": "Показать список быстрых клавиш", - "HotkeysSpaceKey": "Пробел", "HotkeysUndoLastAction": "Отменить последнее действие", "HotkeysUploadFile": "Загрузить файл", "HotkeysUploadingObjects": "Загрузка объектов", diff --git a/packages/client/public/locales/si/HotkeysPanel.json b/packages/client/public/locales/si/HotkeysPanel.json index cd885de039..0502412c89 100644 --- a/packages/client/public/locales/si/HotkeysPanel.json +++ b/packages/client/public/locales/si/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "පැතුරුම්පතක් සාදන්න", "HotkeysCreatingObjects": "අථක සෑදීම", "HotkeysCutSelected": "තෝරාගත් අථක කපන්න", - "HotkeysEnterKey": "ඇතුල් කරන්න", "HotkeysExtendSelectionDown": "තේරීම පහළට පතුරුවන්න", "HotkeysExtendSelectionLeft": "තේරීම වමට පතුරුවන්න", "HotkeysExtendSelectionRight": "තේරීම දකුණට පතුරුවන්න", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "දකුණු පස ඊළඟ අථකය තෝරන්න", "HotkeysSelectUp": "ඉහළ ඊළඟ අථකය තෝරන්න", "HotkeysShortcuts": "කෙටිමං ලැයිස්තුව පෙන්වන්න", - "HotkeysSpaceKey": "හිස්තැන", "HotkeysUndoLastAction": "අවසාන ක්‍රියාව පෙරසේ තබන්න", "HotkeysUploadFile": "ගොනුවක් උඩුගත කරන්න", "HotkeysUploadingObjects": "අථක උඩුගත වෙමින්", diff --git a/packages/client/public/locales/sk/HotkeysPanel.json b/packages/client/public/locales/sk/HotkeysPanel.json index dff786c072..19cbd3e0ae 100644 --- a/packages/client/public/locales/sk/HotkeysPanel.json +++ b/packages/client/public/locales/sk/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Vytvoriť tabuľku", "HotkeysCreatingObjects": "Vytváranie položiek", "HotkeysCutSelected": "Vyrezať vybrané položky do schránky", - "HotkeysEnterKey": "Zadať", "HotkeysExtendSelectionDown": "Rozšíriť výber nadol", "HotkeysExtendSelectionLeft": "Rozšíriť výber doľava", "HotkeysExtendSelectionRight": "Rozšíriť výber doprava", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Vybrať ďalšiu položku vpravo", "HotkeysSelectUp": "Vybrať ďalšiu položku hore", "HotkeysShortcuts": "Zobraziť zoznam klávesových skratiek na klávesnici", - "HotkeysSpaceKey": "Priestor", "HotkeysUndoLastAction": "Vrátiť späť poslednú akciu", "HotkeysUploadFile": "Nahrať súbor", "HotkeysUploadingObjects": "Nahrávanie položiek", diff --git a/packages/client/public/locales/sl/HotkeysPanel.json b/packages/client/public/locales/sl/HotkeysPanel.json index f4e572dca5..05cb8e9579 100644 --- a/packages/client/public/locales/sl/HotkeysPanel.json +++ b/packages/client/public/locales/sl/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Ustvari preglednico", "HotkeysCreatingObjects": "Ustvarjanje predmetov", "HotkeysCutSelected": "Izreži izbrane elemente v odložišče", - "HotkeysEnterKey": "Vstopi", "HotkeysExtendSelectionDown": "Premakni izbiro navzdol", "HotkeysExtendSelectionLeft": "Premakni izbiro na levo", "HotkeysExtendSelectionRight": "Premakni izbiro na desno", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Izberi naslednji predmet desno", "HotkeysSelectUp": "Izberi naslednji predmet zgoraj", "HotkeysShortcuts": "Prikaži seznam bližnjic na tipkovnici", - "HotkeysSpaceKey": "Razmik", "HotkeysUndoLastAction": "Razveljavi zadnjo akcijo", "HotkeysUploadFile": "Naloži datoteko", "HotkeysUploadingObjects": "Nalaganje predmetov", diff --git a/packages/client/public/locales/sr-Latn-RS/HotkeysPanel.json b/packages/client/public/locales/sr-Latn-RS/HotkeysPanel.json index 3bc90efb69..56a8e908ad 100644 --- a/packages/client/public/locales/sr-Latn-RS/HotkeysPanel.json +++ b/packages/client/public/locales/sr-Latn-RS/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Kreiraj proračunsku tabelu", "HotkeysCreatingObjects": "Kreiranje stavki", "HotkeysCutSelected": "Iseci odabrane stavke na privremenu memoriju", - "HotkeysEnterKey": "Uđi", "HotkeysExtendSelectionDown": "Proširi selekciju dole", "HotkeysExtendSelectionLeft": "Proširi selekciju levo", "HotkeysExtendSelectionRight": "Proširi selekciju desno", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Odaberi sledeću stavku sa desne strane", "HotkeysSelectUp": "Odaberi sledeću stavku gore", "HotkeysShortcuts": "Prikaži listu prečica tastature", - "HotkeysSpaceKey": "Prostor", "HotkeysUndoLastAction": "Poništi poslednju radnju", "HotkeysUploadFile": "Otpremi datoteku", "HotkeysUploadingObjects": "Otpremljivanje stavki", diff --git a/packages/client/public/locales/tr/HotkeysPanel.json b/packages/client/public/locales/tr/HotkeysPanel.json index 7a20bd660d..146f440a26 100644 --- a/packages/client/public/locales/tr/HotkeysPanel.json +++ b/packages/client/public/locales/tr/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Elektronik Tablo Oluştur", "HotkeysCreatingObjects": "Öğeler oluşturuluyor", "HotkeysCutSelected": "Seçilen öğeleri panoya kes", - "HotkeysEnterKey": "Giriş", "HotkeysExtendSelectionDown": "Seçimi aşağı genişlet", "HotkeysExtendSelectionLeft": "Seçimi sola genişlet", "HotkeysExtendSelectionRight": "Seçimi sağa genişlet", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Sıradaki öğeyi sağa doğru seç", "HotkeysSelectUp": "Sıradaki öğeyi yukarı doğru seç", "HotkeysShortcuts": "Klavye kısayol tuşları listesini görüntüle", - "HotkeysSpaceKey": "Boşluk", "HotkeysUndoLastAction": "Son işlemi geri al", "HotkeysUploadFile": "Dosya yükle", "HotkeysUploadingObjects": "Öğeler yükleniyor", diff --git a/packages/client/public/locales/uk-UA/HotkeysPanel.json b/packages/client/public/locales/uk-UA/HotkeysPanel.json index a5145a9412..ab2bd5d437 100644 --- a/packages/client/public/locales/uk-UA/HotkeysPanel.json +++ b/packages/client/public/locales/uk-UA/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Створити таблицю", "HotkeysCreatingObjects": "Створення елементів", "HotkeysCutSelected": "Вирізати вибрані елементи до буфера обміну", - "HotkeysEnterKey": "Ввести", "HotkeysExtendSelectionDown": "Розширити виділення вниз", "HotkeysExtendSelectionLeft": "Розширити виділення ліворуч", "HotkeysExtendSelectionRight": "Розширити виділення праворуч", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Вибрати наступний елемент праворуч", "HotkeysSelectUp": "Вибрати наступний елемент угорі", "HotkeysShortcuts": "Показати список сполучень клавіш", - "HotkeysSpaceKey": "Пробіл", "HotkeysUndoLastAction": "Скасувати останню дію", "HotkeysUploadFile": "Завантажити файл", "HotkeysUploadingObjects": "Передавання елементів", diff --git a/packages/client/public/locales/vi/HotkeysPanel.json b/packages/client/public/locales/vi/HotkeysPanel.json index 7abee764ee..80df5204e4 100644 --- a/packages/client/public/locales/vi/HotkeysPanel.json +++ b/packages/client/public/locales/vi/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "Tạo bảng tính", "HotkeysCreatingObjects": "Tạo mục", "HotkeysCutSelected": "Cắt các mục đã chọn vào bộ nhớ tạm", - "HotkeysEnterKey": "Nhập", "HotkeysExtendSelectionDown": "Mở rộng lựa chọn xuống", "HotkeysExtendSelectionLeft": "Mở rộng lựa chọn bên trái", "HotkeysExtendSelectionRight": "Mở rộng lựa chọn bên phải", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "Chọn mục tiếp theo bên phải", "HotkeysSelectUp": "Chọn mục tiếp theo bên trên", "HotkeysShortcuts": "Hiển thị danh sách phím tắt", - "HotkeysSpaceKey": "Khoảng cách", "HotkeysUndoLastAction": "Hoàn tác hành động cuối cùng", "HotkeysUploadFile": "Tải file lên", "HotkeysUploadingObjects": "Đang tải lên các mục", diff --git a/packages/client/public/locales/zh-CN/HotkeysPanel.json b/packages/client/public/locales/zh-CN/HotkeysPanel.json index 715c805aef..0b5fa2dd0c 100644 --- a/packages/client/public/locales/zh-CN/HotkeysPanel.json +++ b/packages/client/public/locales/zh-CN/HotkeysPanel.json @@ -14,7 +14,6 @@ "HotkeysCreateSpreadsheet": "新建电子表格", "HotkeysCreatingObjects": "创建项目", "HotkeysCutSelected": "将选定的项目剪切到剪贴板", - "HotkeysEnterKey": "输入", "HotkeysExtendSelectionDown": "向下扩展选定", "HotkeysExtendSelectionLeft": "向左扩展选定", "HotkeysExtendSelectionRight": "向右扩展选定", @@ -39,7 +38,6 @@ "HotkeysSelectRight": "向右选择下一个项目", "HotkeysSelectUp": "向上选择下一个项目", "HotkeysShortcuts": "显示快捷键列表", - "HotkeysSpaceKey": "空格", "HotkeysUndoLastAction": "撤销上次的行动", "HotkeysUploadFile": "上传文件", "HotkeysUploadingObjects": "上传项目", diff --git a/packages/client/src/components/panels/HotkeysPanel/ActionsBlock.js b/packages/client/src/components/panels/HotkeysPanel/ActionsBlock.js index f7ad3796cf..a5549278c2 100644 --- a/packages/client/src/components/panels/HotkeysPanel/ActionsBlock.js +++ b/packages/client/src/components/panels/HotkeysPanel/ActionsBlock.js @@ -34,7 +34,7 @@ const ActionsBlock = ({ t, textStyles, keyTextStyles, CtrlKey }) => { <> {t("HotkeysOpen")} - {t("HotkeysEnterKey")} + Enter diff --git a/packages/client/src/components/panels/HotkeysPanel/PreviewActionsBlock.js b/packages/client/src/components/panels/HotkeysPanel/PreviewActionsBlock.js index c081035856..512dd8f648 100644 --- a/packages/client/src/components/panels/HotkeysPanel/PreviewActionsBlock.js +++ b/packages/client/src/components/panels/HotkeysPanel/PreviewActionsBlock.js @@ -40,7 +40,7 @@ const PreviewActionsBlock = ({ t, textStyles, keyTextStyles }) => { <> {t("HotkeysPlayPause")} - {t("HotkeysSpaceKey")} + Space From 89febc906aa556fcced24540f08dc7d679e71b62 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Wed, 5 Jun 2024 18:08:59 +0300 Subject: [PATCH 126/126] Returning a backdrop solution without using portals. --- .../NavMenu/sub-components/profile-menu.js | 11 +++++++- .../src/components/Login/Login.styled.ts | 4 +-- packages/login/src/components/SimpleNav.tsx | 8 ++++++ .../shared/components/drop-down/DropDown.tsx | 16 +++--------- .../shared/components/drop-down/index.tsx | 25 +++++++++++++------ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/packages/client/src/components/NavMenu/sub-components/profile-menu.js b/packages/client/src/components/NavMenu/sub-components/profile-menu.js index 2312c08722..480b142692 100644 --- a/packages/client/src/components/NavMenu/sub-components/profile-menu.js +++ b/packages/client/src/components/NavMenu/sub-components/profile-menu.js @@ -208,6 +208,7 @@ class ProfileMenu extends React.Component { open={open} clickOutsideAction={clickOutsideAction} forwardedRef={forwardedRef} + isDefaultMode={false} withBlur={true} isBannerVisible={isBannerVisible} withPortal={true} @@ -236,7 +237,15 @@ class ProfileMenu extends React.Component { }; render() { - return {this.renderDropDown()}; + const { open } = this.props; + + const element = this.renderDropDown(); + + const root = document.getElementById("root"); + + const wrapper = {element}; + + return <>{}; } } diff --git a/packages/login/src/components/Login/Login.styled.ts b/packages/login/src/components/Login/Login.styled.ts index 5bdecc6def..45256b64ef 100644 --- a/packages/login/src/components/Login/Login.styled.ts +++ b/packages/login/src/components/Login/Login.styled.ts @@ -54,6 +54,7 @@ export const LoginFormWrapper = styled.div<{ bgPattern: string }>` @media ${mobile} { background-image: none; + height: 0; } } @@ -82,8 +83,7 @@ export const LoginFormWrapper = styled.div<{ bgPattern: string }>` top: 28px; @media ${mobile} { - top: 7px; - right: 8px; + display: none; } } .invitation-info-container { diff --git a/packages/login/src/components/SimpleNav.tsx b/packages/login/src/components/SimpleNav.tsx index f343b6bdef..8b743893dc 100644 --- a/packages/login/src/components/SimpleNav.tsx +++ b/packages/login/src/components/SimpleNav.tsx @@ -34,6 +34,7 @@ import { mobile } from "@docspace/shared/utils/device"; import { getLogoUrl } from "@docspace/shared/utils/common"; import { Base, Dark } from "@docspace/shared/themes"; import { ThemeKeys, WhiteLabelLogoType } from "@docspace/shared/enums"; +import LanguageComboboxWrapper from "./LanguageCombobox"; const StyledSimpleNav = styled.div` display: none; @@ -50,6 +51,12 @@ const StyledSimpleNav = styled.div` @media ${mobile} { display: flex; + + .language-combo-box { + position: absolute; + top: 7px; + right: 8px; + } } `; @@ -66,6 +73,7 @@ const SimpleNav = ({ systemTheme }: SimpleNavProps) => { return ( logo-url + ); }; diff --git a/packages/shared/components/drop-down/DropDown.tsx b/packages/shared/components/drop-down/DropDown.tsx index d6d0095260..767d243c0d 100644 --- a/packages/shared/components/drop-down/DropDown.tsx +++ b/packages/shared/components/drop-down/DropDown.tsx @@ -37,7 +37,6 @@ import { Row } from "./sub-components/Row"; import { DropDownProps } from "./DropDown.types"; import { DEFAULT_PARENT_HEIGHT } from "./DropDown.constants"; -import { Backdrop } from "../backdrop"; const DropDown = ({ directionY = "bottom", @@ -68,11 +67,6 @@ const DropDown = ({ manualY, className, style, - withoutBackground, - withBackground, - withBackdrop, - isAside, - withBlur, }: DropDownProps) => { const theme = useTheme(); @@ -381,23 +375,19 @@ const DropDown = ({ ? { height: `${calculatedHeight}px` } : {}; - const toggleDropDown = () => { - clickOutsideAction?.({} as Event, !open); - }; - return ( <> - {withBackdrop ? ( + {/* {withBackdrop ? ( //TODO: consider a solution when there will be a structure of correct z index for components - ) : null} + ) : null} */} { - const { eventTypes, forceCloseClickOutside } = props; + const { + clickOutsideAction, + open, + withBackdrop = true, - // const toggleDropDown = () => { - // clickOutsideAction?.({} as Event, !open); - // }; + withBlur = false, + + isAside, + withBackground, + eventTypes, + forceCloseClickOutside, + withoutBackground, + } = props; + + const toggleDropDown = () => { + clickOutsideAction?.({} as Event, !open); + }; const eventTypesProp = forceCloseClickOutside ? {} @@ -49,7 +61,7 @@ const DropDown = (props: DropDownProps) => { return ( <> - {/* {withBackdrop ? ( + {withBackdrop ? ( { withBackground={withBackground} withoutBackground={withoutBackground} /> - ) : null} */} + ) : null} ); }; - DropDown.defaultProps = { withBackdrop: true, showDisabledItems: false,