Merge branch 'hotfix/v2.6.1' into bugfix/huge-group-issues
This commit is contained in:
commit
c9661b2745
@ -350,7 +350,9 @@ export const getOptions = (
|
||||
t("EmptyView:UploadFromPortalTitle", {
|
||||
productName: t("Common:ProductName"),
|
||||
}),
|
||||
t("EmptyView:UploadPDFFormOptionDescription"),
|
||||
t("EmptyView:UploadPDFFormOptionDescription", {
|
||||
productName: t("Common:ProductName"),
|
||||
}),
|
||||
FilterType.PDFForm,
|
||||
);
|
||||
|
||||
|
@ -145,7 +145,9 @@ const SimulatePassword = memo(
|
||||
}, [isDisabled]);
|
||||
|
||||
useEffect(() => {
|
||||
setPassword(inputValue);
|
||||
if (inputValue !== undefined) {
|
||||
setPassword(inputValue);
|
||||
}
|
||||
}, [inputValue]);
|
||||
|
||||
return (
|
||||
|
@ -588,6 +588,7 @@ const AddUsersPanel = ({
|
||||
isSearchLoading={isInit}
|
||||
rowLoader={
|
||||
<RowLoader
|
||||
style={{ paddingInlineEnd: 0 }}
|
||||
isUser
|
||||
count={15}
|
||||
isContainer={isLoading}
|
||||
|
@ -52,6 +52,7 @@ import { StyledNewFilesBody, StyledLink } from "../StyledPanels";
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
|
||||
import config from "PACKAGE_FILE";
|
||||
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
|
||||
|
||||
const NewFilesPanel = (props) => {
|
||||
const {
|
||||
@ -60,8 +61,6 @@ const NewFilesPanel = (props) => {
|
||||
getFolderIcon,
|
||||
newFiles,
|
||||
markAsRead,
|
||||
setMediaViewerData,
|
||||
currentFolderId,
|
||||
setIsLoading,
|
||||
t,
|
||||
visible,
|
||||
@ -203,40 +202,10 @@ const NewFilesPanel = (props) => {
|
||||
}
|
||||
|
||||
if (isMedia) {
|
||||
if (currentFolderId !== item.folderId) {
|
||||
const categoryType = getCategoryTypeByFolderType(
|
||||
rootFolderType,
|
||||
item.folderId,
|
||||
);
|
||||
|
||||
const state = {
|
||||
title: "",
|
||||
rootFolderType,
|
||||
|
||||
isRoot: false,
|
||||
};
|
||||
setIsLoading(true);
|
||||
|
||||
const url = getCategoryUrl(categoryType, item.folderId);
|
||||
|
||||
const filter = FilesFilter.getDefault();
|
||||
filter.folder = item.folderId;
|
||||
|
||||
window.DocSpace.navigate(`${url}?${filter.toUrlParams()}`, { state });
|
||||
|
||||
const mediaItem = { visible: true, id };
|
||||
setMediaViewerData(mediaItem);
|
||||
|
||||
setInProgress(false);
|
||||
onClose();
|
||||
} else {
|
||||
const mediaItem = { visible: true, id };
|
||||
setMediaViewerData(mediaItem);
|
||||
|
||||
return onClose();
|
||||
}
|
||||
|
||||
return;
|
||||
return window.open(
|
||||
combineUrl(MEDIA_VIEW_URL, id),
|
||||
openOnNewPage ? "_blank" : "_self",
|
||||
);
|
||||
}
|
||||
|
||||
if (fileItemsList && enablePlugins) {
|
||||
@ -335,7 +304,6 @@ export default inject(
|
||||
filesStore,
|
||||
mediaViewerDataStore,
|
||||
filesActionsStore,
|
||||
selectedFolderStore,
|
||||
dialogsStore,
|
||||
filesSettingsStore,
|
||||
clientLoadingStore,
|
||||
@ -349,10 +317,9 @@ export default inject(
|
||||
setIsSectionFilterLoading(param);
|
||||
};
|
||||
|
||||
const { setMediaViewerData, setCurrentItem } = mediaViewerDataStore;
|
||||
const { setCurrentItem } = mediaViewerDataStore;
|
||||
const { getIcon, getFolderIcon, openOnNewPage } = filesSettingsStore;
|
||||
const { markAsRead } = filesActionsStore;
|
||||
const { id: currentFolderId } = selectedFolderStore;
|
||||
|
||||
const {
|
||||
setNewFilesPanelVisible,
|
||||
@ -371,8 +338,6 @@ export default inject(
|
||||
newFilesIds,
|
||||
isLoading,
|
||||
setCurrentItem,
|
||||
currentFolderId,
|
||||
setMediaViewerData,
|
||||
getIcon,
|
||||
getFolderIcon,
|
||||
markAsRead,
|
||||
|
@ -52,6 +52,7 @@ import {
|
||||
} from "./StyledCreateUser";
|
||||
import PortalLogo from "@docspace/shared/components/portal-logo/PortalLogo";
|
||||
import GreetingUserContainer from "./GreetingUserContainer";
|
||||
import { ALLOWED_PASSWORD_CHARACTERS } from "@docspace/shared/constants";
|
||||
|
||||
const ActivateUserForm = (props) => {
|
||||
const { t, settings, linkData, hashSettings, defaultPage, login } = props;
|
||||
|
@ -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 SsoReactSvgUrl from "PUBLIC_DIR/images/sso.react.svg?url";
|
||||
import SsoReactSvg from "PUBLIC_DIR/images/sso.react.svg";
|
||||
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import { withTranslation, Trans } from "react-i18next";
|
||||
@ -469,7 +469,7 @@ const CreateUserForm = (props) => {
|
||||
? {
|
||||
ssoUrl: capabilities?.ssoUrl,
|
||||
ssoLabel: capabilities?.ssoLabel,
|
||||
ssoSVG: SsoReactSvgUrl,
|
||||
ssoSVG: SsoReactSvg,
|
||||
}
|
||||
: {};
|
||||
|
||||
|
@ -52,7 +52,7 @@ const RoomsItemHeader = ({
|
||||
setSelection,
|
||||
setBufferSelection,
|
||||
isArchive,
|
||||
hasLinks,
|
||||
isShared,
|
||||
showSearchBlock,
|
||||
setShowSearchBlock,
|
||||
roomType,
|
||||
@ -70,7 +70,7 @@ const RoomsItemHeader = ({
|
||||
(selection.roomType === RoomsType.PublicRoom ||
|
||||
selection.roomType === RoomsType.FormRoom ||
|
||||
selection.roomType === RoomsType.CustomRoom) &&
|
||||
hasLinks;
|
||||
isShared;
|
||||
|
||||
const badgeUrl = showPlanetIcon ? Planet12ReactSvgUrl : null;
|
||||
const isRoomMembersPanel = selection?.isRoom && roomsView === "info_members";
|
||||
@ -161,7 +161,6 @@ export default inject(
|
||||
selectedFolderStore,
|
||||
filesStore,
|
||||
infoPanelStore,
|
||||
publicRoomStore,
|
||||
}) => {
|
||||
const {
|
||||
infoPanelSelection,
|
||||
@ -170,7 +169,6 @@ export default inject(
|
||||
showSearchBlock,
|
||||
setShowSearchBlock,
|
||||
} = infoPanelStore;
|
||||
const { externalLinks } = publicRoomStore;
|
||||
|
||||
const selection = infoPanelSelection.length > 1 ? null : infoPanelSelection;
|
||||
const isArchive = selection?.rootFolderType === FolderType.Archive;
|
||||
@ -196,7 +194,7 @@ export default inject(
|
||||
setSelection: filesStore.setSelection,
|
||||
setBufferSelection: filesStore.setBufferSelection,
|
||||
isArchive,
|
||||
hasLinks: externalLinks.length,
|
||||
isShared: selection?.shared,
|
||||
roomType,
|
||||
};
|
||||
},
|
||||
|
@ -187,12 +187,14 @@ const AdditionalResources = (props) => {
|
||||
const onSave = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
const settings = JSON.parse(JSON.stringify(additionalResourcesData));
|
||||
|
||||
settings.feedbackAndSupportEnabled = feedbackAndSupportEnabled;
|
||||
settings.videoGuidesEnabled = videoGuidesEnabled;
|
||||
settings.helpCenterEnabled = helpCenterEnabled;
|
||||
|
||||
await api.settings
|
||||
.setAdditionalResources(
|
||||
feedbackAndSupportEnabled,
|
||||
videoGuidesEnabled,
|
||||
helpCenterEnabled,
|
||||
)
|
||||
.setAdditionalResources(settings)
|
||||
.then(() => {
|
||||
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
|
||||
})
|
||||
|
@ -142,7 +142,7 @@ const SocialNetworks = (props) => {
|
||||
return (
|
||||
<div key={`${item.provider}ProviderItem`}>
|
||||
<SocialButton
|
||||
iconName={icon}
|
||||
IconComponent={icon}
|
||||
label={getProviderTranslation(label, t, item.linked)}
|
||||
$iconOptions={iconOptions}
|
||||
onClick={onClick}
|
||||
|
@ -246,6 +246,11 @@ const Sdk = ({
|
||||
|
||||
if (!frameConfig) return;
|
||||
|
||||
const selectorOpenRoot =
|
||||
selectorType !== "userFolderOnly" &&
|
||||
selectorType !== "roomsOnly" &&
|
||||
!frameConfig?.id;
|
||||
|
||||
switch (mode) {
|
||||
case "room-selector":
|
||||
const cancelButtonProps = frameConfig?.showSelectorCancel
|
||||
@ -294,7 +299,7 @@ const Sdk = ({
|
||||
acceptButtonLabel={frameConfig?.acceptButtonLabel}
|
||||
cancelButtonLabel={frameConfig?.cancelButtonLabel}
|
||||
currentFolderId={frameConfig?.id}
|
||||
openRoot={!frameConfig?.id}
|
||||
openRoot={selectorOpenRoot}
|
||||
descriptionText={formatsDescription[frameConfig?.filterParam] || ""}
|
||||
/>
|
||||
);
|
||||
|
@ -155,13 +155,6 @@ class FilesActionStore {
|
||||
this.isBulkDownload = isBulkDownload;
|
||||
};
|
||||
|
||||
isMediaOpen = () => {
|
||||
const { visible, setMediaViewerData, playlist } = this.mediaViewerDataStore;
|
||||
if (visible && playlist.length === 1) {
|
||||
setMediaViewerData({ visible: false, id: null });
|
||||
}
|
||||
};
|
||||
|
||||
updateCurrentFolder = (fileIds, folderIds, clearSelection, operationId) => {
|
||||
const { clearSecondaryProgressData } =
|
||||
this.uploadDataStore.secondaryProgressDataStore;
|
||||
@ -390,8 +383,6 @@ class FilesActionStore {
|
||||
addActiveItems(null, folderIds, destFolderId);
|
||||
|
||||
if (folderIds.length || fileIds.length) {
|
||||
this.isMediaOpen();
|
||||
|
||||
try {
|
||||
this.filesStore.setOperationAction(true);
|
||||
this.setGroupMenuBlocked(true);
|
||||
@ -852,7 +843,6 @@ class FilesActionStore {
|
||||
|
||||
if (isFile) {
|
||||
addActiveItems([itemId], null, destFolderId);
|
||||
this.isMediaOpen();
|
||||
return deleteFile(itemId)
|
||||
.then(async (res) => {
|
||||
if (res[0]?.error) return Promise.reject(res[0].error);
|
||||
|
@ -24,11 +24,8 @@
|
||||
// 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 { cookies } from "next/headers";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
import { SYSTEM_THEME_KEY } from "@docspace/shared/constants";
|
||||
import { ThemeKeys, WhiteLabelLogoType } from "@docspace/shared/enums";
|
||||
import { getBgPattern, getLogoUrl } from "@docspace/shared/utils/common";
|
||||
import { Scrollbar } from "@docspace/shared/components/scrollbar";
|
||||
import { ColorTheme, ThemeId } from "@docspace/shared/components/color-theme";
|
||||
@ -56,10 +53,6 @@ export default async function Layout({
|
||||
getColorTheme(),
|
||||
]);
|
||||
|
||||
const cookieStore = cookies();
|
||||
|
||||
const systemTheme = cookieStore.get(SYSTEM_THEME_KEY)?.value as ThemeKeys;
|
||||
|
||||
const bgPattern = getBgPattern(colorTheme?.selected);
|
||||
|
||||
const objectSettings = typeof settings === "string" ? undefined : settings;
|
||||
@ -68,8 +61,7 @@ export default async function Layout({
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%", height: "100%" }}>
|
||||
<SimpleNav systemTheme={systemTheme} />
|
||||
|
||||
<SimpleNav />
|
||||
<LoginFormWrapper id="login-page" bgPattern={bgPattern}>
|
||||
<div className="bg-cover" />
|
||||
<Scrollbar id="customScrollBar">
|
||||
|
@ -24,7 +24,14 @@
|
||||
// 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 { getSettings } from "@/utils/actions";
|
||||
import { PROVIDERS_DATA } from "@docspace/shared/constants";
|
||||
|
||||
import {
|
||||
getCapabilities,
|
||||
getSettings,
|
||||
getSSO,
|
||||
getThirdPartyProviders,
|
||||
} from "@/utils/actions";
|
||||
import Login from "@/components/Login";
|
||||
import LoginForm from "@/components/LoginForm";
|
||||
import ThirdParty from "@/components/ThirdParty";
|
||||
@ -32,7 +39,26 @@ import RecoverAccess from "@/components/RecoverAccess";
|
||||
import Register from "@/components/Register";
|
||||
|
||||
async function Page() {
|
||||
const settings = await getSettings();
|
||||
const [settings, thirdParty, capabilities, ssoSettings] = await Promise.all([
|
||||
getSettings(),
|
||||
getThirdPartyProviders(),
|
||||
getCapabilities(),
|
||||
getSSO(),
|
||||
]);
|
||||
|
||||
const ssoUrl = capabilities ? capabilities.ssoUrl : "";
|
||||
const hideAuthPage = ssoSettings ? ssoSettings.hideAuthPage : false;
|
||||
const ssoExists = !!ssoUrl;
|
||||
const oauthDataExists =
|
||||
!capabilities?.oauthEnabled || !thirdParty || thirdParty.length === 0
|
||||
? false
|
||||
: thirdParty
|
||||
.map((item) => {
|
||||
if (!(item.provider in PROVIDERS_DATA)) return undefined;
|
||||
|
||||
return item;
|
||||
})
|
||||
.some((item) => !!item);
|
||||
|
||||
return (
|
||||
<Login>
|
||||
@ -43,8 +69,17 @@ async function Page() {
|
||||
cookieSettingsEnabled={settings?.cookieSettingsEnabled}
|
||||
reCaptchaPublicKey={settings?.recaptchaPublicKey}
|
||||
reCaptchaType={settings?.recaptchaType}
|
||||
ldapDomain={capabilities?.ldapDomain}
|
||||
ldapEnabled={capabilities?.ldapEnabled}
|
||||
/>
|
||||
<ThirdParty
|
||||
thirdParty={thirdParty}
|
||||
capabilities={capabilities}
|
||||
ssoExists={ssoExists}
|
||||
ssoUrl={ssoUrl}
|
||||
hideAuthPage={hideAuthPage}
|
||||
oauthDataExists={oauthDataExists}
|
||||
/>
|
||||
<ThirdParty />
|
||||
{settings.enableAdmMess && <RecoverAccess />}
|
||||
{settings.enabledJoin && (
|
||||
<Register
|
||||
|
@ -36,11 +36,11 @@ import type {
|
||||
TFirebaseSettings,
|
||||
TSettings,
|
||||
} from "@docspace/shared/api/settings/types";
|
||||
import FirebaseHelper from "@docspace/shared/utils/firebase";
|
||||
|
||||
import useTheme from "@/hooks/useTheme";
|
||||
import useDeviceType from "@/hooks/useDeviceType";
|
||||
import useI18N from "@/hooks/useI18N";
|
||||
import FirebaseHelper from "@docspace/shared/utils/firebase";
|
||||
|
||||
import pkg from "../../package.json";
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
import { cookies, headers } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { Toast } from "@docspace/shared/components/toast";
|
||||
import { getBaseUrl } from "@docspace/shared/utils/next-ssr-helper";
|
||||
import { TenantStatus, ThemeKeys } from "@docspace/shared/enums";
|
||||
@ -58,18 +59,11 @@ export default async function RootLayout({
|
||||
|
||||
let redirectUrl = "";
|
||||
|
||||
const timers = { otherOperations: 0 };
|
||||
|
||||
const startOtherOperationsDate = new Date();
|
||||
|
||||
const [settings, colorTheme] = await Promise.all([
|
||||
getSettings(),
|
||||
getColorTheme(),
|
||||
]);
|
||||
|
||||
timers.otherOperations =
|
||||
new Date().getTime() - startOtherOperationsDate.getTime();
|
||||
|
||||
if (settings === "access-restricted") redirectUrl = `/${settings}`;
|
||||
|
||||
if (settings === "portal-not-found") {
|
||||
@ -132,7 +126,6 @@ export default async function RootLayout({
|
||||
systemTheme: systemTheme?.value as ThemeKeys,
|
||||
}}
|
||||
redirectURL={redirectUrl}
|
||||
timers={timers}
|
||||
>
|
||||
<Toast isSSR />
|
||||
{children}
|
||||
|
@ -33,7 +33,6 @@ import { useSearchParams } from "next/navigation";
|
||||
import { useTheme } from "styled-components";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import { WhiteLabelLogoType } from "@docspace/shared/enums";
|
||||
import { getLogoUrl } from "@docspace/shared/utils/common";
|
||||
|
||||
|
@ -33,10 +33,10 @@ import { setLanguageForUnauthorized } from "@docspace/shared/utils/common";
|
||||
import { LanguageCombobox } from "@docspace/shared/components/language-combobox";
|
||||
import { DeviceType } from "@docspace/shared/enums";
|
||||
import { Nullable } from "@docspace/shared/types";
|
||||
import { getPortalCultures } from "@docspace/shared/api/settings";
|
||||
import { TPortalCultures } from "@docspace/shared/api/settings/types";
|
||||
|
||||
import useDeviceType from "@/hooks/useDeviceType";
|
||||
import { getPortalCultures } from "@/utils/actions";
|
||||
|
||||
const LanguageComboboxWrapper = () => {
|
||||
const { i18n } = useTranslation(["Login", "Common"]);
|
||||
|
@ -31,27 +31,20 @@ import React, { createContext, useState } from "react";
|
||||
export const LoginValueContext = createContext({
|
||||
isLoading: false,
|
||||
isModalOpen: false,
|
||||
ldapDomain: "",
|
||||
});
|
||||
|
||||
export const LoginDispatchContext = createContext({
|
||||
setIsLoading: (value: boolean) => {},
|
||||
setIsModalOpen: (value: boolean) => {},
|
||||
setLdapDomain: (value: string) => {},
|
||||
});
|
||||
|
||||
export const LoginContext = ({ children }: { children: React.ReactNode }) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [ldapDomain, setLdapDomain] = useState("");
|
||||
|
||||
return (
|
||||
<LoginDispatchContext.Provider
|
||||
value={{ setIsLoading, setIsModalOpen, setLdapDomain }}
|
||||
>
|
||||
<LoginValueContext.Provider
|
||||
value={{ isLoading, isModalOpen, ldapDomain }}
|
||||
>
|
||||
<LoginDispatchContext.Provider value={{ setIsLoading, setIsModalOpen }}>
|
||||
<LoginValueContext.Provider value={{ isLoading, isModalOpen }}>
|
||||
{children}
|
||||
</LoginValueContext.Provider>
|
||||
</LoginDispatchContext.Provider>
|
||||
|
@ -38,6 +38,7 @@ import { useTranslation } from "react-i18next";
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
import HCaptcha from "@hcaptcha/react-hcaptcha";
|
||||
import { useTheme } from "styled-components";
|
||||
import { Id } from "react-toastify";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
@ -52,6 +53,7 @@ import { toastr } from "@docspace/shared/components/toast";
|
||||
import { thirdPartyLogin, checkConfirmLink } from "@docspace/shared/api/user";
|
||||
import { setWithCredentialsStatus } from "@docspace/shared/api/client";
|
||||
import { TValidate } from "@docspace/shared/components/email-input/EmailInput.types";
|
||||
import { RecaptchaType } from "@docspace/shared/enums";
|
||||
|
||||
import { LoginFormProps } from "@/types";
|
||||
import { getEmailFromInvitation, getConfirmDataFromInvitation } from "@/utils";
|
||||
@ -59,11 +61,11 @@ import { getEmailFromInvitation, getConfirmDataFromInvitation } from "@/utils";
|
||||
import EmailContainer from "./sub-components/EmailContainer";
|
||||
import PasswordContainer from "./sub-components/PasswordContainer";
|
||||
import ForgotContainer from "./sub-components/ForgotContainer";
|
||||
import LDAPContainer from "./sub-components/LDAPContainer";
|
||||
|
||||
import { LoginDispatchContext, LoginValueContext } from "../Login";
|
||||
|
||||
import { StyledCaptcha } from "./LoginForm.styled";
|
||||
import { LoginDispatchContext, LoginValueContext } from "../Login";
|
||||
import LDAPContainer from "./sub-components/LDAPContainer";
|
||||
import { RecaptchaType } from "@docspace/shared/enums";
|
||||
|
||||
let showToastr = true;
|
||||
|
||||
@ -72,10 +74,12 @@ const LoginForm = ({
|
||||
cookieSettingsEnabled,
|
||||
reCaptchaPublicKey,
|
||||
reCaptchaType,
|
||||
ldapDomain,
|
||||
ldapEnabled,
|
||||
}: LoginFormProps) => {
|
||||
const { isLoading, isModalOpen, ldapDomain } = useContext(LoginValueContext);
|
||||
const { isLoading, isModalOpen } = useContext(LoginValueContext);
|
||||
const { setIsLoading } = useContext(LoginDispatchContext);
|
||||
const toastId = useRef(null);
|
||||
const toastId = useRef<Id>();
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
@ -417,7 +421,7 @@ const LoginForm = ({
|
||||
onChangeCheckbox={onChangeCheckbox}
|
||||
/>
|
||||
|
||||
{ldapDomain && (
|
||||
{ldapDomain && ldapEnabled && (
|
||||
<LDAPContainer
|
||||
ldapDomain={ldapDomain}
|
||||
isLdapLoginChecked={isLdapLoginChecked}
|
||||
|
@ -54,7 +54,7 @@ interface IEmailContainer {
|
||||
onBlurEmail: () => void;
|
||||
onValidateEmail: (res: TValidate) => undefined;
|
||||
isLdapLogin: boolean;
|
||||
ldapDomain: string;
|
||||
ldapDomain?: string;
|
||||
}
|
||||
|
||||
const EmailContainer = ({
|
||||
|
@ -49,7 +49,7 @@ const ForgotPasswordModalDialog = ({
|
||||
userEmail,
|
||||
onDialogClose,
|
||||
}: ForgotPasswordModalDialogProps) => {
|
||||
const [email, setEmail] = useState(userEmail);
|
||||
const [email, setEmail] = useState(userEmail ?? "");
|
||||
const [emailError, setEmailError] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [errorText, setErrorText] = useState("");
|
||||
|
@ -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`
|
||||
@ -60,13 +61,13 @@ const StyledSimpleNav = styled.div`
|
||||
|
||||
StyledSimpleNav.defaultProps = { theme: Base };
|
||||
|
||||
interface SimpleNavProps {
|
||||
systemTheme: ThemeKeys;
|
||||
}
|
||||
interface SimpleNavProps {}
|
||||
|
||||
const SimpleNav = ({ systemTheme }: SimpleNavProps) => {
|
||||
const SimpleNav = ({}: SimpleNavProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const isDark = !theme.isBase;
|
||||
|
||||
const logoUrl = getLogoUrl(WhiteLabelLogoType.LightSmall, isDark);
|
||||
|
||||
return (
|
||||
|
@ -33,22 +33,13 @@ import styled from "styled-components";
|
||||
|
||||
import { SocialButtonsGroup } from "@docspace/shared/components/social-buttons-group";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { PROVIDERS_DATA } from "@docspace/shared/constants";
|
||||
import { getOAuthToken, getLoginLink } from "@docspace/shared/utils/common";
|
||||
import {
|
||||
TCapabilities,
|
||||
TGetSsoSettings,
|
||||
TThirdPartyProvider,
|
||||
} from "@docspace/shared/api/settings/types";
|
||||
import { Nullable } from "@docspace/shared/types";
|
||||
|
||||
import SSOIcon from "PUBLIC_DIR/images/sso.react.svg?url";
|
||||
|
||||
import {
|
||||
getCapabilities,
|
||||
getSSO,
|
||||
getThirdPartyProviders,
|
||||
} from "@/utils/actions";
|
||||
import SSOIcon from "PUBLIC_DIR/images/sso.react.svg";
|
||||
|
||||
import { LoginDispatchContext, LoginValueContext } from "./Login";
|
||||
|
||||
@ -57,44 +48,31 @@ const StyledThirdParty = styled.div<{ isVisible: boolean }>`
|
||||
height: auto;
|
||||
`;
|
||||
|
||||
const ThirdParty = () => {
|
||||
type ThirdPartyProps = {
|
||||
thirdParty?: TThirdPartyProvider[];
|
||||
capabilities?: TCapabilities;
|
||||
ssoUrl?: string;
|
||||
ssoExists?: boolean;
|
||||
oauthDataExists?: boolean;
|
||||
hideAuthPage?: boolean;
|
||||
};
|
||||
|
||||
const ThirdParty = ({
|
||||
thirdParty,
|
||||
capabilities,
|
||||
ssoUrl,
|
||||
ssoExists,
|
||||
oauthDataExists,
|
||||
hideAuthPage,
|
||||
}: ThirdPartyProps) => {
|
||||
const { isLoading } = useContext(LoginValueContext);
|
||||
const { setIsModalOpen, setLdapDomain } = useContext(LoginDispatchContext);
|
||||
const { setIsModalOpen } = useContext(LoginDispatchContext);
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const { t } = useTranslation(["Login", "Common"]);
|
||||
|
||||
const [capabilities, setCapabilities] =
|
||||
React.useState<Nullable<TCapabilities>>(null);
|
||||
const [thirdPartyProvider, setThirdPartyProvider] =
|
||||
React.useState<Nullable<TThirdPartyProvider[]>>(null);
|
||||
const [ssoSettings, setSsoSettings] =
|
||||
React.useState<Nullable<TGetSsoSettings>>(null);
|
||||
|
||||
const getData = useCallback(async () => {
|
||||
const [thirdParty, capabilities, ssoSettings] = await Promise.all([
|
||||
getThirdPartyProviders(),
|
||||
getCapabilities(),
|
||||
getSSO(),
|
||||
]);
|
||||
|
||||
if (thirdParty) setThirdPartyProvider(thirdParty);
|
||||
if (capabilities) setCapabilities(capabilities);
|
||||
if (ssoSettings) setSsoSettings(ssoSettings);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, [getData]);
|
||||
|
||||
useEffect(() => {
|
||||
const ssoUrl = capabilities ? capabilities.ssoUrl : "";
|
||||
const hideAuthPage = ssoSettings ? ssoSettings.hideAuthPage : false;
|
||||
|
||||
if (capabilities?.ldapEnabled && capabilities.ldapDomain)
|
||||
setLdapDomain(capabilities.ldapDomain);
|
||||
|
||||
if (
|
||||
ssoUrl &&
|
||||
hideAuthPage &&
|
||||
@ -102,25 +80,7 @@ const ThirdParty = () => {
|
||||
) {
|
||||
window.location.replace(ssoUrl);
|
||||
}
|
||||
}, [capabilities, searchParams, ssoSettings, setLdapDomain]);
|
||||
|
||||
const ssoExists = () => {
|
||||
if (capabilities?.ssoUrl) return true;
|
||||
else return false;
|
||||
};
|
||||
|
||||
const oauthDataExists = () => {
|
||||
if (!capabilities?.oauthEnabled) return false;
|
||||
|
||||
let existProviders = 0;
|
||||
if (thirdPartyProvider && thirdPartyProvider.length > 0)
|
||||
thirdPartyProvider?.map((item) => {
|
||||
if (!(item.provider in PROVIDERS_DATA)) return;
|
||||
existProviders++;
|
||||
});
|
||||
|
||||
return !!existProviders;
|
||||
};
|
||||
}, [capabilities, searchParams, ssoUrl, hideAuthPage]);
|
||||
|
||||
const onSocialButtonClick = useCallback(
|
||||
(e: React.MouseEvent<Element, MouseEvent>) => {
|
||||
@ -171,7 +131,7 @@ const ThirdParty = () => {
|
||||
[],
|
||||
);
|
||||
|
||||
const ssoProps = ssoExists()
|
||||
const ssoProps = ssoExists
|
||||
? {
|
||||
ssoUrl: capabilities?.ssoUrl,
|
||||
ssoLabel: capabilities?.ssoLabel,
|
||||
@ -179,7 +139,7 @@ const ThirdParty = () => {
|
||||
}
|
||||
: {};
|
||||
|
||||
const isVisible = oauthDataExists() || ssoExists();
|
||||
const isVisible = oauthDataExists || ssoExists;
|
||||
|
||||
return (
|
||||
isVisible && (
|
||||
@ -188,7 +148,7 @@ const ThirdParty = () => {
|
||||
<Text className="or-label">{t("Common:orContinueWith")}</Text>
|
||||
</div>
|
||||
<SocialButtonsGroup
|
||||
providers={thirdPartyProvider ?? undefined}
|
||||
providers={thirdParty ?? undefined}
|
||||
onClick={onSocialButtonClick}
|
||||
onMoreAuthToggle={setIsModalOpen}
|
||||
t={t}
|
||||
|
@ -25,14 +25,12 @@
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import React from "react";
|
||||
import { i18n } from "i18next";
|
||||
|
||||
import { getCookie, getLanguage } from "@docspace/shared/utils";
|
||||
import { getCookie } from "@docspace/shared/utils";
|
||||
import { LANGUAGE } from "@docspace/shared/constants";
|
||||
import { TSettings } from "@docspace/shared/api/settings/types";
|
||||
|
||||
import { getI18NInstance } from "@/utils/i18n";
|
||||
import { setCookie } from "@docspace/shared/utils/cookie";
|
||||
|
||||
interface UseI18NProps {
|
||||
settings?: TSettings;
|
||||
|
@ -24,8 +24,10 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import useDeviceType from "@/hooks/useDeviceType";
|
||||
import ErrorBoundary from "@docspace/shared/components/error-boundary/ErrorBoundary";
|
||||
|
||||
import useDeviceType from "@/hooks/useDeviceType";
|
||||
|
||||
import { ErrorBoundaryProps } from "./ErrorBoundary.types";
|
||||
|
||||
const ErrorBoundaryWrapper = (props: ErrorBoundaryProps) => {
|
||||
|
@ -33,20 +33,18 @@ import { ThemeProvider } from "@docspace/shared/components/theme-provider";
|
||||
import { TFirebaseSettings } from "@docspace/shared/api/settings/types";
|
||||
import FirebaseHelper from "@docspace/shared/utils/firebase";
|
||||
import { TUser } from "@docspace/shared/api/people/types";
|
||||
import { ThemeKeys } from "@docspace/shared/enums";
|
||||
import { Base, Dark } from "@docspace/shared/themes";
|
||||
|
||||
import { TDataContext } from "@/types";
|
||||
import useI18N from "@/hooks/useI18N";
|
||||
import useTheme from "@/hooks/useTheme";
|
||||
|
||||
import pkgFile from "../../package.json";
|
||||
|
||||
import ErrorBoundaryWrapper from "./ErrorBoundary";
|
||||
|
||||
export const Providers = ({
|
||||
children,
|
||||
value,
|
||||
timers,
|
||||
redirectURL,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
@ -61,10 +59,6 @@ export const Providers = ({
|
||||
if (redirectURL) window.location.replace(redirectURL);
|
||||
}, [redirectURL]);
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log("Timers:", { ...timers });
|
||||
}, [timers]);
|
||||
|
||||
const { i18n } = useI18N({
|
||||
settings: value.settings,
|
||||
});
|
||||
|
@ -86,6 +86,8 @@ export type LoginFormProps = {
|
||||
reCaptchaPublicKey?: string;
|
||||
reCaptchaType?: RecaptchaType;
|
||||
cookieSettingsEnabled: boolean;
|
||||
ldapDomain?: string;
|
||||
ldapEnabled?: boolean;
|
||||
};
|
||||
|
||||
export type ForgotPasswordModalDialogProps = {
|
||||
|
@ -144,18 +144,3 @@ export async function getSSO() {
|
||||
|
||||
return sso.response as TGetSsoSettings;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -407,16 +407,10 @@ export async function getCustomSchemaList() {
|
||||
}
|
||||
|
||||
export function setAdditionalResources(
|
||||
feedbackAndSupportEnabled,
|
||||
videoGuidesEnabled,
|
||||
helpCenterEnabled,
|
||||
additionalResources: TAdditionalResources,
|
||||
) {
|
||||
const data = {
|
||||
settings: {
|
||||
helpCenterEnabled,
|
||||
feedbackAndSupportEnabled,
|
||||
videoGuidesEnabled,
|
||||
},
|
||||
settings: additionalResources,
|
||||
};
|
||||
|
||||
return request({
|
||||
|
@ -29,12 +29,15 @@ import { BoxProps } from "./Box.types";
|
||||
import { StyledBox } from "./Box.styled";
|
||||
|
||||
function Box(props: BoxProps) {
|
||||
const { as } = props;
|
||||
return <StyledBox {...props} as={as || "div"} data-testid="box" />;
|
||||
const { as, displayProp = "block" } = props;
|
||||
return (
|
||||
<StyledBox
|
||||
{...props}
|
||||
displayProp={displayProp}
|
||||
as={as || "div"}
|
||||
data-testid="box"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Box.defaultProps = {
|
||||
displayProp: "block",
|
||||
};
|
||||
|
||||
export { Box };
|
||||
|
@ -37,6 +37,8 @@ const StyledLabel = styled.label<{
|
||||
position: relative;
|
||||
margin: 0;
|
||||
|
||||
line-height: 16px;
|
||||
|
||||
user-select: none;
|
||||
-o-user-select: none;
|
||||
-moz-user-select: none;
|
||||
|
@ -142,6 +142,7 @@ const CheckboxPure = ({
|
||||
title={title}
|
||||
truncate={truncate}
|
||||
className="checkbox-text"
|
||||
lineHeight="16px"
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
|
@ -49,25 +49,29 @@ import type { ComboButtonProps } from "../Combobox.types";
|
||||
|
||||
const ComboButton = (props: ComboButtonProps) => {
|
||||
const {
|
||||
noBorder,
|
||||
onClick,
|
||||
isDisabled,
|
||||
|
||||
innerContainer,
|
||||
innerContainerClassName = "innerContainer",
|
||||
|
||||
selectedOption,
|
||||
optionsLength = 0,
|
||||
withOptions = true,
|
||||
withAdvancedOptions = false,
|
||||
isOpen,
|
||||
scaled = false,
|
||||
size,
|
||||
|
||||
comboIcon,
|
||||
fillIcon,
|
||||
modernView = false,
|
||||
tabIndex,
|
||||
isLoading,
|
||||
|
||||
type,
|
||||
plusBadgeValue,
|
||||
noBorder = false,
|
||||
isDisabled = false,
|
||||
withOptions = true,
|
||||
withAdvancedOptions = false,
|
||||
innerContainerClassName = "innerContainer",
|
||||
isOpen = false,
|
||||
size = ComboBoxSize.content,
|
||||
scaled = false,
|
||||
modernView = false,
|
||||
tabIndex = -1,
|
||||
isLoading = false,
|
||||
} = props;
|
||||
|
||||
const defaultOption = selectedOption?.default;
|
||||
@ -174,18 +178,4 @@ const ComboButton = (props: ComboButtonProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
ComboButton.defaultProps = {
|
||||
noBorder: false,
|
||||
isDisabled: false,
|
||||
withOptions: true,
|
||||
withAdvancedOptions: false,
|
||||
innerContainerClassName: "innerContainer",
|
||||
isOpen: false,
|
||||
size: ComboBoxSize.content,
|
||||
scaled: false,
|
||||
modernView: false,
|
||||
tabIndex: -1,
|
||||
isLoading: false,
|
||||
};
|
||||
|
||||
export { ComboButton };
|
||||
|
@ -46,21 +46,21 @@ import { DropDownItemProps } from "./DropDownItem.types";
|
||||
|
||||
const DropDownItem = (props: DropDownItemProps) => {
|
||||
const {
|
||||
isSeparator,
|
||||
isHeader,
|
||||
isSeparator = false,
|
||||
isHeader = false,
|
||||
withHeaderArrow,
|
||||
headerArrowAction,
|
||||
|
||||
icon,
|
||||
children,
|
||||
disabled,
|
||||
disabled = false,
|
||||
className,
|
||||
|
||||
fillIcon = true,
|
||||
isSubMenu,
|
||||
isActive,
|
||||
withoutIcon,
|
||||
noHover,
|
||||
isSubMenu = false,
|
||||
isActive = false,
|
||||
withoutIcon = false,
|
||||
noHover = false,
|
||||
|
||||
isSelected,
|
||||
isActiveDescendant,
|
||||
@ -72,8 +72,17 @@ const DropDownItem = (props: DropDownItemProps) => {
|
||||
const { t } = useTranslation(["Common"]);
|
||||
const theme = useTheme();
|
||||
|
||||
const { withToggle, checked, onClick, onClickSelectedItem, label, ...rest } =
|
||||
props;
|
||||
const {
|
||||
withToggle,
|
||||
checked,
|
||||
onClick,
|
||||
onClickSelectedItem,
|
||||
label = "",
|
||||
tabIndex = -1,
|
||||
textOverflow = false,
|
||||
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const onClickAction = (
|
||||
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
||||
@ -97,6 +106,8 @@ const DropDownItem = (props: DropDownItemProps) => {
|
||||
return (
|
||||
<StyledDropdownItem
|
||||
{...rest}
|
||||
tabIndex={tabIndex}
|
||||
textOverflow={textOverflow}
|
||||
noHover={noHover}
|
||||
className={className}
|
||||
onClick={onClickAction}
|
||||
@ -184,17 +195,6 @@ const DropDownItem = (props: DropDownItemProps) => {
|
||||
};
|
||||
|
||||
DropDownItem.defaultProps = {
|
||||
isSeparator: false,
|
||||
isHeader: false,
|
||||
tabIndex: -1,
|
||||
label: "",
|
||||
disabled: false,
|
||||
noHover: false,
|
||||
textOverflow: false,
|
||||
fillIcon: true,
|
||||
isSubMenu: false,
|
||||
isActive: false,
|
||||
withoutIcon: false,
|
||||
height: 32,
|
||||
heightTablet: 36,
|
||||
};
|
||||
|
@ -75,4 +75,6 @@ export interface DropDownItemProps {
|
||||
isBeta?: boolean;
|
||||
additionalElement?: React.ReactNode;
|
||||
setOpen?: (open: boolean) => void;
|
||||
height?: number;
|
||||
heightTablet?: number;
|
||||
}
|
||||
|
@ -45,6 +45,12 @@ const DropDown = (props: DropDownProps) => {
|
||||
eventTypes,
|
||||
forceCloseClickOutside,
|
||||
withoutBackground,
|
||||
|
||||
showDisabledItems = false,
|
||||
isDefaultMode = true,
|
||||
fixedDirection = false,
|
||||
offsetLeft = 0,
|
||||
enableKeyboardEvents = true,
|
||||
} = props;
|
||||
|
||||
const toggleDropDown = () => {
|
||||
@ -72,17 +78,17 @@ const DropDown = (props: DropDownProps) => {
|
||||
withoutBackground={withoutBackground}
|
||||
/>
|
||||
) : null}
|
||||
<EnhancedComponent {...eventTypesProp} {...props} />
|
||||
<EnhancedComponent
|
||||
{...eventTypesProp}
|
||||
showDisabledItems={showDisabledItems}
|
||||
isDefaultMode={isDefaultMode}
|
||||
fixedDirection={fixedDirection}
|
||||
offsetLeft={offsetLeft}
|
||||
enableKeyboardEvents={enableKeyboardEvents}
|
||||
{...props}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
DropDown.defaultProps = {
|
||||
withBackdrop: true,
|
||||
showDisabledItems: false,
|
||||
isDefaultMode: true,
|
||||
fixedDirection: false,
|
||||
offsetLeft: 0,
|
||||
enableKeyboardEvents: true,
|
||||
};
|
||||
|
||||
export { DropDown };
|
||||
|
@ -39,19 +39,33 @@ const TextInputWrapper = ({
|
||||
emailSettings,
|
||||
customValidate,
|
||||
...props
|
||||
}: EmailInputProps & TextInputProps & { isValidEmail?: boolean }) => (
|
||||
<StyledEmailInput {...props} data-testid="email-input" />
|
||||
);
|
||||
}: EmailInputProps & TextInputProps & { isValidEmail?: boolean }) => {
|
||||
return <StyledEmailInput {...props} data-testid="email-input" />;
|
||||
};
|
||||
|
||||
const EmailInput = ({
|
||||
value,
|
||||
onValidateInput,
|
||||
customValidate,
|
||||
emailSettings,
|
||||
|
||||
onBlur,
|
||||
onChange,
|
||||
hasError,
|
||||
|
||||
isAutoFocussed,
|
||||
autoComplete = "email",
|
||||
className = "",
|
||||
hasError = undefined,
|
||||
id = "",
|
||||
isDisabled = false,
|
||||
isReadOnly = false,
|
||||
maxLength = 255,
|
||||
name = "",
|
||||
placeholder = "",
|
||||
scale = false,
|
||||
size = InputSize.base,
|
||||
title = "",
|
||||
withBorder = true,
|
||||
value = "",
|
||||
emailSettings,
|
||||
...rest
|
||||
}: EmailInputProps) => {
|
||||
const [inputValue, setInputValue] = React.useState(value);
|
||||
@ -65,7 +79,7 @@ const EmailInput = ({
|
||||
return customValidate(v);
|
||||
}
|
||||
|
||||
const emailObj = parseAddress(v, emailSettings);
|
||||
const emailObj = parseAddress(v, emailSettings ?? new EmailSettings());
|
||||
const isValid = emailObj.isValid();
|
||||
const parsedErrors = emailObj.parseErrors;
|
||||
const errors = parsedErrors
|
||||
@ -124,6 +138,18 @@ const EmailInput = ({
|
||||
return (
|
||||
<TextInputWrapper
|
||||
{...rest}
|
||||
className={className}
|
||||
autoComplete={autoComplete}
|
||||
id={id}
|
||||
isDisabled={isDisabled}
|
||||
isReadOnly={isReadOnly}
|
||||
maxLength={maxLength}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
scale={scale}
|
||||
size={size}
|
||||
title={title}
|
||||
withBorder={withBorder}
|
||||
isAutoFocussed={isMobile && isIOS ? false : isAutoFocussed}
|
||||
hasError={isError}
|
||||
value={inputValue}
|
||||
@ -135,22 +161,4 @@ const EmailInput = ({
|
||||
);
|
||||
};
|
||||
|
||||
EmailInput.defaultProps = {
|
||||
autoComplete: "email",
|
||||
className: "",
|
||||
hasError: undefined,
|
||||
id: "",
|
||||
isDisabled: false,
|
||||
isReadOnly: false,
|
||||
maxLength: 255,
|
||||
name: "",
|
||||
placeholder: "",
|
||||
scale: false,
|
||||
size: InputSize.base,
|
||||
title: "",
|
||||
value: "",
|
||||
withBorder: true,
|
||||
emailSettings: new EmailSettings(),
|
||||
};
|
||||
|
||||
export { EmailInput };
|
||||
|
@ -72,4 +72,8 @@ export interface EmailInputProps {
|
||||
type: InputType;
|
||||
/** Used as HTML `tabindex` property */
|
||||
tabIndex?: number;
|
||||
|
||||
withBorder?: boolean;
|
||||
maxLength?: number;
|
||||
title?: string;
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ import { HelpButtonProps } from "./HelpButton.types";
|
||||
const HelpButton = (props: HelpButtonProps) => {
|
||||
const {
|
||||
id,
|
||||
className,
|
||||
className = "icon-button",
|
||||
iconName,
|
||||
size,
|
||||
size = 12,
|
||||
color,
|
||||
dataTip,
|
||||
getContent,
|
||||
@ -65,7 +65,7 @@ const HelpButton = (props: HelpButtonProps) => {
|
||||
id={currentId}
|
||||
className={classNames([className], "help-icon") || "help-icon"}
|
||||
isClickable
|
||||
iconName={iconName || InfoReactSvgUrl}
|
||||
iconName={iconName ?? InfoReactSvgUrl}
|
||||
size={size}
|
||||
color={color}
|
||||
data-for={currentId}
|
||||
@ -102,11 +102,4 @@ const HelpButton = (props: HelpButtonProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
HelpButton.defaultProps = {
|
||||
iconName: InfoReactSvgUrl,
|
||||
// place: "top",
|
||||
className: "icon-button",
|
||||
size: 12,
|
||||
};
|
||||
|
||||
export { HelpButton };
|
||||
|
@ -23,8 +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 React, { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { mapCulturesToArray } from "../../utils/common";
|
||||
@ -58,7 +57,7 @@ const LanguageCombobox = (props: ComboboxProps) => {
|
||||
onSelectLanguage(culture);
|
||||
};
|
||||
|
||||
if (!currentCulture) return <></>;
|
||||
if (!currentCulture) return null;
|
||||
|
||||
return (
|
||||
<StyledComboBox
|
||||
|
@ -23,4 +23,5 @@
|
||||
// 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 "./LanguageCombobox";
|
||||
|
@ -35,16 +35,34 @@ export { LinkType, LinkTarget };
|
||||
const Link = ({
|
||||
isTextOverflow,
|
||||
children,
|
||||
noHover,
|
||||
enableUserSelect,
|
||||
className = "",
|
||||
fontSize = "13px",
|
||||
href = undefined,
|
||||
isBold = false,
|
||||
isHovered = false,
|
||||
isSemitransparent = false,
|
||||
noHover = false,
|
||||
rel = "noopener noreferrer",
|
||||
tabIndex = -1,
|
||||
type = LinkType.page,
|
||||
enableUserSelect = false,
|
||||
...rest
|
||||
}: LinkProps) => {
|
||||
return (
|
||||
<StyledText
|
||||
className={className}
|
||||
fontSize={fontSize}
|
||||
href={href}
|
||||
isBold={isBold}
|
||||
isHovered={isHovered}
|
||||
isSemitransparent={isSemitransparent}
|
||||
rel={rel}
|
||||
tabIndex={tabIndex}
|
||||
type={type}
|
||||
tag="a"
|
||||
isTextOverflow={isTextOverflow}
|
||||
noHover={noHover}
|
||||
truncate={isTextOverflow || false}
|
||||
truncate={isTextOverflow ?? false}
|
||||
enableUserSelect={enableUserSelect}
|
||||
data-testid="link"
|
||||
{...rest}
|
||||
@ -54,19 +72,4 @@ const Link = ({
|
||||
);
|
||||
};
|
||||
|
||||
Link.defaultProps = {
|
||||
className: "",
|
||||
fontSize: "13px",
|
||||
href: undefined,
|
||||
isBold: false,
|
||||
isHovered: false,
|
||||
isSemitransparent: false,
|
||||
isTextOverflow: false,
|
||||
noHover: false,
|
||||
rel: "noopener noreferrer",
|
||||
tabIndex: -1,
|
||||
type: LinkType.page,
|
||||
enableUserSelect: false,
|
||||
};
|
||||
|
||||
export { Link };
|
||||
|
@ -65,23 +65,28 @@ const ModalDialog = ({
|
||||
children,
|
||||
visible,
|
||||
onClose,
|
||||
isLarge,
|
||||
zIndex,
|
||||
|
||||
className,
|
||||
displayType = ModalDialogType.modal,
|
||||
displayTypeDetailed,
|
||||
isLoading,
|
||||
|
||||
autoMaxHeight,
|
||||
autoMaxWidth,
|
||||
withBodyScroll,
|
||||
withFooterBorder,
|
||||
|
||||
isScrollLocked,
|
||||
containerVisible,
|
||||
|
||||
isDoubleFooterLine,
|
||||
isCloseable,
|
||||
|
||||
embedded,
|
||||
withForm,
|
||||
blur,
|
||||
zIndex = 310,
|
||||
isLarge = false,
|
||||
isLoading = false,
|
||||
isCloseable = true,
|
||||
withBodyScroll = false,
|
||||
withFooterBorder = false,
|
||||
containerVisible = false,
|
||||
}: ModalDialogProps) => {
|
||||
const onCloseEvent = React.useCallback(() => {
|
||||
if (embedded) return;
|
||||
@ -174,16 +179,6 @@ const ModalDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
ModalDialog.defaultProps = {
|
||||
zIndex: 310,
|
||||
isLarge: false,
|
||||
isLoading: false,
|
||||
isCloseable: true,
|
||||
withBodyScroll: false,
|
||||
withFooterBorder: false,
|
||||
containerVisible: false,
|
||||
};
|
||||
|
||||
ModalDialog.Header = Header;
|
||||
ModalDialog.Body = Body;
|
||||
ModalDialog.Footer = Footer;
|
||||
|
@ -89,9 +89,11 @@ const MoreLoginModal: React.FC<MoreLoginModalProps> = (props) => {
|
||||
const { icon, label } =
|
||||
PROVIDERS_DATA[item.provider as keyof ProvidersDataType];
|
||||
|
||||
const IconComponent = icon;
|
||||
|
||||
return (
|
||||
<ProviderRow key={`ProviderItem${label}`}>
|
||||
<ReactSVG src={icon} />
|
||||
<IconComponent />
|
||||
<Text
|
||||
fontSize="14px"
|
||||
fontWeight="600"
|
||||
|
@ -29,7 +29,7 @@ import equal from "fast-deep-equal/react";
|
||||
|
||||
import { getProviderLabel } from "@docspace/shared/utils/common";
|
||||
|
||||
import VerticalDotsReactSvgUrl from "PUBLIC_DIR/images/vertical-dots.react.svg?url";
|
||||
import VerticalDotsReactSvg from "PUBLIC_DIR/images/vertical-dots.react.svg";
|
||||
|
||||
import { SocialButton } from "../social-button";
|
||||
import StyledSocialButtonsGroup from "./SocialButtonsGroup.styled";
|
||||
@ -80,11 +80,11 @@ export const SocialButtonsGroup = memo(
|
||||
<div className="buttonWrapper" key={`${provider}ProviderItem`}>
|
||||
<SocialButton
|
||||
isDisabled={isDisabled}
|
||||
iconName={icon}
|
||||
label={length >= 2 ? "" : getProviderLabel(label, t)}
|
||||
$iconOptions={iconOptions}
|
||||
data-url={url}
|
||||
data-providername={provider}
|
||||
IconComponent={icon}
|
||||
onClick={onClick}
|
||||
className="social-button"
|
||||
/>
|
||||
@ -97,7 +97,7 @@ export const SocialButtonsGroup = memo(
|
||||
{ssoUrl && (
|
||||
<SocialButton
|
||||
isDisabled={isDisabled}
|
||||
iconName={ssoSVG}
|
||||
IconComponent={ssoSVG}
|
||||
className="sso-button social-button"
|
||||
label={ssoLabel || getProviderLabel("sso", t)}
|
||||
onClick={() => (window.location.href = ssoUrl)}
|
||||
@ -108,7 +108,7 @@ export const SocialButtonsGroup = memo(
|
||||
{elements}
|
||||
{length > 2 && (
|
||||
<SocialButton
|
||||
iconName={VerticalDotsReactSvgUrl}
|
||||
IconComponent={VerticalDotsReactSvg}
|
||||
onClick={moreAuthOpen}
|
||||
className="show-more-button"
|
||||
/>
|
||||
|
@ -24,13 +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 ShareAppleReactSvgUrl from "PUBLIC_DIR/images/share.apple.react.svg?url";
|
||||
import ShareGoogleReactSvgUrl from "PUBLIC_DIR/images/share.google.react.svg?url";
|
||||
import ShareFacebookReactSvgUrl from "PUBLIC_DIR/images/share.facebook.react.svg?url";
|
||||
import ShareTwitterReactSvgUrl from "PUBLIC_DIR/images/share.twitter.react.svg?url";
|
||||
import ShareLinkedinReactSvgUrl from "PUBLIC_DIR/images/share.linkedin.react.svg?url";
|
||||
import ShareMicrosoftReactSvgUrl from "PUBLIC_DIR/images/share.microsoft.react.svg?url";
|
||||
import ShareZoomReactSvgUrl from "PUBLIC_DIR/images/share.zoom.react.svg?url";
|
||||
import ShareAppleReactSvg from "PUBLIC_DIR/images/share.apple.react.svg";
|
||||
import ShareGoogleReactSvg from "PUBLIC_DIR/images/share.google.react.svg";
|
||||
import ShareFacebookReactSvg from "PUBLIC_DIR/images/share.facebook.react.svg";
|
||||
import ShareTwitterReactSvg from "PUBLIC_DIR/images/share.twitter.react.svg";
|
||||
import ShareLinkedinReactSvg from "PUBLIC_DIR/images/share.linkedin.react.svg";
|
||||
import ShareMicrosoftReactSvg from "PUBLIC_DIR/images/share.microsoft.react.svg";
|
||||
import ShareZoomReactSvg from "PUBLIC_DIR/images/share.zoom.react.svg";
|
||||
|
||||
export const LOADER_STYLE = Object.freeze({
|
||||
title: "",
|
||||
@ -100,37 +100,37 @@ export const FOLDER_NAMES = Object.freeze({
|
||||
export const PROVIDERS_DATA = Object.freeze({
|
||||
appleid: {
|
||||
label: "apple",
|
||||
icon: ShareAppleReactSvgUrl,
|
||||
icon: ShareAppleReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
google: {
|
||||
label: "google",
|
||||
icon: ShareGoogleReactSvgUrl,
|
||||
icon: ShareGoogleReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
facebook: {
|
||||
label: "facebook",
|
||||
icon: ShareFacebookReactSvgUrl,
|
||||
icon: ShareFacebookReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
twitter: {
|
||||
label: "twitter",
|
||||
icon: ShareTwitterReactSvgUrl,
|
||||
icon: ShareTwitterReactSvg,
|
||||
iconOptions: { color: "#2AA3EF" },
|
||||
},
|
||||
linkedin: {
|
||||
label: "linkedin",
|
||||
icon: ShareLinkedinReactSvgUrl,
|
||||
icon: ShareLinkedinReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
microsoft: {
|
||||
label: "microsoft",
|
||||
icon: ShareMicrosoftReactSvgUrl,
|
||||
icon: ShareMicrosoftReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
zoom: {
|
||||
label: "zoom",
|
||||
icon: ShareZoomReactSvgUrl,
|
||||
icon: ShareZoomReactSvg,
|
||||
iconOptions: undefined,
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user