Merge pull request #256 from ONLYOFFICE/feature/rewrite-more-login-modal

Feature/rewrite-more-login-modal
This commit is contained in:
Alexey Safronov 2024-02-13 22:03:49 +04:00 committed by GitHub
commit 4836c6a33c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 197 additions and 179 deletions

View File

@ -24,7 +24,7 @@ import {
import { login } from "@docspace/shared/utils/loginUtils"; import { login } from "@docspace/shared/utils/loginUtils";
import { PROVIDERS_DATA } from "@docspace/shared/constants"; import { PROVIDERS_DATA } from "@docspace/shared/constants";
import withLoader from "../withLoader"; import withLoader from "../withLoader";
import MoreLoginModal from "@docspace/common/components/MoreLoginModal"; import MoreLoginModal from "@docspace/shared/components/more-login-modal";
import { EmailInput } from "@docspace/shared/components/email-input"; import { EmailInput } from "@docspace/shared/components/email-input";
import { getPasswordErrorMessage } from "../../../helpers/utils"; import { getPasswordErrorMessage } from "../../../helpers/utils";
import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import { FormWrapper } from "@docspace/shared/components/form-wrapper";
@ -237,7 +237,7 @@ const CreateUserForm = (props) => {
const data = Object.assign( const data = Object.assign(
{ fromInviteLink: fromInviteLink }, { fromInviteLink: fromInviteLink },
registerData, registerData,
loginData loginData,
); );
await createUser(data, key); await createUser(data, key);
@ -317,7 +317,7 @@ const CreateUserForm = (props) => {
: window.open( : window.open(
url, url,
"login", "login",
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no" "width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no",
); );
getOAuthToken(tokenGetterWin).then((code) => { getOAuthToken(tokenGetterWin).then((code) => {
@ -326,7 +326,7 @@ const CreateUserForm = (props) => {
auth: providerName, auth: providerName,
mode: "popup", mode: "popup",
callback: "authCallback", callback: "authCallback",
}) }),
); );
tokenGetterWin.location.href = getLoginLink(token, code); tokenGetterWin.location.href = getLoginLink(token, code);
@ -417,7 +417,7 @@ const CreateUserForm = (props) => {
const onSignIn = () => { const onSignIn = () => {
return window.location.replace( return window.location.replace(
combineUrl(window.DocSpaceConfig?.proxy?.url, "/login") combineUrl(window.DocSpaceConfig?.proxy?.url, "/login"),
); );
}; };
@ -621,7 +621,7 @@ const CreateUserForm = (props) => {
labelVisible={false} labelVisible={false}
hasError={isPasswordErrorShow && !passwordValid} hasError={isPasswordErrorShow && !passwordValid}
errorMessage={`${t( errorMessage={`${t(
"Common:PasswordLimitMessage" "Common:PasswordLimitMessage",
)}: ${getPasswordErrorMessage(t, settings)}`} )}: ${getPasswordErrorMessage(t, settings)}`}
> >
<PasswordInput <PasswordInput
@ -645,19 +645,19 @@ const CreateUserForm = (props) => {
onKeyDown={onKeyPress} onKeyDown={onKeyPress}
onValidateInput={onValidatePassword} onValidateInput={onValidatePassword}
tooltipPasswordTitle={`${t( tooltipPasswordTitle={`${t(
"Common:PasswordLimitMessage" "Common:PasswordLimitMessage",
)}:`} )}:`}
tooltipPasswordLength={`${t( tooltipPasswordLength={`${t(
"Common:PasswordMinimumLength" "Common:PasswordMinimumLength",
)}: ${settings ? settings.minLength : 8}`} )}: ${settings ? settings.minLength : 8}`}
tooltipPasswordDigits={`${t( tooltipPasswordDigits={`${t(
"Common:PasswordLimitDigits" "Common:PasswordLimitDigits",
)}`} )}`}
tooltipPasswordCapital={`${t( tooltipPasswordCapital={`${t(
"Common:PasswordLimitUpperCase" "Common:PasswordLimitUpperCase",
)}`} )}`}
tooltipPasswordSpecial={`${t( tooltipPasswordSpecial={`${t(
"Common:PasswordLimitSpecialSymbols" "Common:PasswordLimitSpecialSymbols",
)}`} )}`}
generatePasswordTitle={t("Wizard:GeneratePassword")} generatePasswordTitle={t("Wizard:GeneratePassword")}
/> />
@ -759,6 +759,6 @@ export default inject(({ settingsStore, authStore }) => {
}; };
})( })(
withTranslation(["Confirm", "Common", "Wizard"])( withTranslation(["Confirm", "Common", "Wizard"])(
withLoader(observer(CreateUserForm)) withLoader(observer(CreateUserForm)),
) ),
); );

View File

@ -1,163 +0,0 @@
import React from "react";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
import { Text } from "@docspace/shared/components/text";
import { Button } from "@docspace/shared/components/button";
import { PROVIDERS_DATA } from "@docspace/shared/constants";
import styled, { css } from "styled-components";
import { ReactSVG } from "react-svg";
import { getProviderTranslation } from "@docspace/shared/utils/common";
import SsoReactSvgUrl from "PUBLIC_DIR/images/sso.react.svg?url";
import { mobile } from "@docspace/shared/utils";
const ProviderRow = styled.div`
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
align-content: center;
padding: 8px 0;
svg {
height: 24px;
width: 24px;
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 4px;
`
: css`
padding-left: 4px;
`}
path {
fill: ${(props) => !props.theme.isBase && "#fff"};
}
}
.provider-name {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 12px;
`
: css`
padding-left: 12px;
`}
line-height: 16px;
}
.signin-button {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin-right: auto;
`
: css`
margin-left: auto;
`}
}
`;
const Modal = styled(ModalDialog)`
.modal-dialog-aside {
transform: translateX(${(props) => (props.visible ? "0" : "480px")});
width: 480px;
@media ${mobile} {
width: 325px;
transform: translateX(${(props) => (props.visible ? "0" : "480px")});
}
}
`;
interface IMoreLoginNodalProps {
visible: boolean;
onClose: VoidFunction;
providers: ProvidersType;
onSocialLoginClick: (
e: HTMLElementEvent<HTMLButtonElement | HTMLElement>
) => void;
ssoLabel: string;
ssoUrl: string;
t: TFuncType;
isSignUp: boolean;
}
const MoreLoginModal: React.FC<IMoreLoginNodalProps> = (props) => {
const {
t,
visible,
onClose,
providers,
onSocialLoginClick,
ssoLabel,
ssoUrl,
isSignUp,
} = props;
console.log("more login render", props);
return (
<Modal
displayType="aside"
visible={visible}
onClose={onClose}
removeScroll={true}
>
<ModalDialog.Header>{t("Common:Authorization")}</ModalDialog.Header>
<ModalDialog.Body>
{ssoUrl && (
<ProviderRow key={`ProviderItemSSO`}>
<ReactSVG src={SsoReactSvgUrl} />
<Text
fontSize="14px"
fontWeight="600"
className="provider-name"
noSelect
>
{ssoLabel || getProviderTranslation("sso", t, false, isSignUp)}
</Text>
<Button
label={t("Common:LoginButton")}
className="signin-button"
size="small"
onClick={() => (window.location.href = ssoUrl)}
/>
</ProviderRow>
)}
{providers?.map((item, index) => {
if (!PROVIDERS_DATA[item.provider]) return;
const { icon, label } = PROVIDERS_DATA[item.provider];
return (
<ProviderRow key={`ProviderItem${index}`}>
<ReactSVG src={icon} />
<Text
fontSize="14px"
fontWeight="600"
className="provider-name"
noSelect
>
{getProviderTranslation(label, t, false, isSignUp)}
</Text>
<Button
label={t("Common:LoginButton")}
className="signin-button"
size="small"
data-url={item.url}
data-providername={item.provider}
onClick={onSocialLoginClick}
/>
</ProviderRow>
);
})}
</ModalDialog.Body>
</Modal>
);
};
export default MoreLoginModal;

View File

@ -14,7 +14,7 @@ import { PROVIDERS_DATA } from "@docspace/shared/constants";
import { Link } from "@docspace/shared/components/link"; import { Link } from "@docspace/shared/components/link";
import { Toast } from "@docspace/shared/components/toast"; import { Toast } from "@docspace/shared/components/toast";
import LoginForm from "./sub-components/LoginForm"; import LoginForm from "./sub-components/LoginForm";
import MoreLoginModal from "@docspace/common/components/MoreLoginModal"; import MoreLoginModal from "@docspace/shared/components/more-login-modal";
import RecoverAccessModalDialog from "@docspace/common/components/Dialogs/RecoverAccessModalDialog"; import RecoverAccessModalDialog from "@docspace/common/components/Dialogs/RecoverAccessModalDialog";
import { FormWrapper } from "@docspace/shared/components/form-wrapper"; import { FormWrapper } from "@docspace/shared/components/form-wrapper";
import Register from "./sub-components/register-container"; import Register from "./sub-components/register-container";
@ -216,8 +216,8 @@ const Login: React.FC<ILoginProps> = ({
const logoUrl = !logo const logoUrl = !logo
? undefined ? undefined
: !theme?.isBase : !theme?.isBase
? getLogoFromPath(logo.path.dark) ? getLogoFromPath(logo.path.dark)
: getLogoFromPath(logo.path.light); : getLogoFromPath(logo.path.light);
if (!mounted) return <></>; if (!mounted) return <></>;
if (isRestoringPortal) return <></>; if (isRestoringPortal) return <></>;

View File

@ -0,0 +1,68 @@
import styled, { css } from "styled-components";
import { mobile } from "@docspace/shared/utils";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
export const ProviderRow = styled.div`
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
align-content: center;
padding: 8px 0;
svg {
height: 24px;
width: 24px;
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 4px;
`
: css`
padding-left: 4px;
`}
path {
fill: ${(props) => !props.theme.isBase && "#fff"};
}
}
.provider-name {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 12px;
`
: css`
padding-left: 12px;
`}
line-height: 16px;
}
.signin-button {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin-right: auto;
`
: css`
margin-left: auto;
`}
}
`;
export const Modal = styled(ModalDialog)`
.modal-dialog-aside {
transform: translateX(${(props) => (props.visible ? "0" : "480px")});
width: 480px;
@media ${mobile} {
width: 325px;
transform: translateX(${(props) => (props.visible ? "0" : "480px")});
}
}
`;

View File

@ -0,0 +1,20 @@
import type { PROVIDERS_DATA } from "@docspace/shared/constants";
export type ProvidersDataType = typeof PROVIDERS_DATA;
interface IProvider {
linked: boolean;
provider: string;
url: string;
}
export interface MoreLoginModalProps {
visible: boolean;
onClose: VoidFunction;
providers?: IProvider[];
onSocialLoginClick: (e: React.MouseEvent<Element, MouseEvent>) => void;
ssoLabel: string;
ssoUrl: string;
t: (key: string, opts?: unknown) => string;
isSignUp: boolean;
}

View File

@ -0,0 +1,93 @@
import React from "react";
import { ReactSVG } from "react-svg";
import SsoReactSvgUrl from "PUBLIC_DIR/images/sso.react.svg?url";
import { Text } from "@docspace/shared/components/text";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { PROVIDERS_DATA } from "@docspace/shared/constants";
import {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { getProviderTranslation } from "@docspace/shared/utils/common";
import { Modal, ProviderRow } from "./MoreLoginModal.styled";
import type {
MoreLoginModalProps,
ProvidersDataType,
} from "./MoreLoginModal.types";
const MoreLoginModal: React.FC<MoreLoginModalProps> = (props) => {
const {
t,
visible,
onClose,
providers,
onSocialLoginClick,
ssoLabel,
ssoUrl,
isSignUp,
} = props;
return (
<Modal
visible={visible}
onClose={onClose}
displayType={ModalDialogType.aside}
>
<ModalDialog.Header>{t("Common:Authorization")}</ModalDialog.Header>
<ModalDialog.Body>
{ssoUrl && (
<ProviderRow key="ProviderItemSSO">
<ReactSVG src={SsoReactSvgUrl} />
<Text
fontSize="14px"
fontWeight="600"
className="provider-name"
noSelect
>
{ssoLabel || getProviderTranslation("sso", t, false, isSignUp)}
</Text>
<Button
label={t("Common:LoginButton")}
className="signin-button"
size={ButtonSize.small}
onClick={() => (window.location.href = ssoUrl)}
/>
</ProviderRow>
)}
{providers?.map((item) => {
if (!PROVIDERS_DATA[item.provider as keyof ProvidersDataType]) return;
const { icon, label } =
PROVIDERS_DATA[item.provider as keyof ProvidersDataType];
return (
<ProviderRow key={`ProviderItem${label}`}>
<ReactSVG src={icon} />
<Text
fontSize="14px"
fontWeight="600"
className="provider-name"
noSelect
>
{getProviderTranslation(label, t, false, isSignUp)}
</Text>
<Button
label={t("Common:LoginButton")}
className="signin-button"
size={ButtonSize.small}
data-url={item.url}
data-providername={item.provider}
onClick={onSocialLoginClick}
/>
</ProviderRow>
);
})}
</ModalDialog.Body>
</Modal>
);
};
export default MoreLoginModal;