Merge pull request #256 from ONLYOFFICE/feature/rewrite-more-login-modal
Feature/rewrite-more-login-modal
This commit is contained in:
commit
4836c6a33c
@ -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)),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
@ -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;
|
|
@ -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 <></>;
|
||||||
|
@ -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")});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
@ -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;
|
||||||
|
}
|
93
packages/shared/components/more-login-modal/index.tsx
Normal file
93
packages/shared/components/more-login-modal/index.tsx
Normal 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;
|
Loading…
Reference in New Issue
Block a user