From cb46ad9fd6fd1e7ee9edd1009a1d30bb56644118 Mon Sep 17 00:00:00 2001
From: Xiao Yijun <xiaoyijun@silverhand.io>
Date: Mon, 31 Oct 2022 18:41:29 +0800
Subject: [PATCH] refactor(console): add sign in method button (#2277)

---
 .../src/components/ActionMenu/index.tsx       |  9 ++-
 .../SignInMethodEditBox/AddButton.tsx         | 63 +++++++++++++++++++
 .../AddSignInMethodButton.tsx                 | 46 --------------
 .../SignInMethodEditBox/index.module.scss     | 10 ++-
 .../components/SignInMethodEditBox/index.tsx  |  8 ++-
 .../AddButton.module.scss                     |  4 ++
 .../SocialConnectorEditBox/AddButton.tsx      |  7 ++-
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 .../translation/admin-console/sign-in-exp.ts  |  1 +
 13 files changed, 100 insertions(+), 53 deletions(-)
 create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddButton.tsx
 delete mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddSignInMethodButton.tsx

diff --git a/packages/console/src/components/ActionMenu/index.tsx b/packages/console/src/components/ActionMenu/index.tsx
index 680423105..81362fdec 100644
--- a/packages/console/src/components/ActionMenu/index.tsx
+++ b/packages/console/src/components/ActionMenu/index.tsx
@@ -16,7 +16,8 @@ type Props = {
   buttonProps: ButtonProps;
   title?: ReactNode;
   dropdownHorizontalAlign?: HorizontalAlignment;
-  dropDownClassName?: string;
+  dropdownClassName?: string;
+  isDropdownFullWidth?: boolean;
 };
 
 const ActionMenu = ({
@@ -24,7 +25,8 @@ const ActionMenu = ({
   buttonProps,
   title,
   dropdownHorizontalAlign,
-  dropDownClassName,
+  dropdownClassName,
+  isDropdownFullWidth = false,
 }: Props) => {
   const [isOpen, setIsOpen] = useState(false);
   const anchorReference = useRef<HTMLDivElement>(null);
@@ -42,8 +44,9 @@ const ActionMenu = ({
         title={title}
         anchorRef={anchorReference}
         isOpen={isOpen}
-        className={classNames(styles.content, dropDownClassName)}
+        className={classNames(styles.content, dropdownClassName)}
         horizontalAlign={dropdownHorizontalAlign}
+        isFullWidth={isDropdownFullWidth}
         onClose={() => {
           setIsOpen(false);
         }}
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddButton.tsx
new file mode 100644
index 000000000..e0a516fe0
--- /dev/null
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddButton.tsx
@@ -0,0 +1,63 @@
+import type { SignInIdentifier } from '@logto/schemas';
+import classNames from 'classnames';
+import { useTranslation } from 'react-i18next';
+import { snakeCase } from 'snake-case';
+
+import Plus from '@/assets/images/plus.svg';
+import ActionMenu from '@/components/ActionMenu';
+import type { Props as ButtonProps } from '@/components/Button';
+import { DropdownItem } from '@/components/Dropdown';
+
+import * as styles from './index.module.scss';
+
+type Props = {
+  options: SignInIdentifier[];
+  onSelected: (signInIdentifier: SignInIdentifier) => void;
+  hasSelectedIdentifiers: boolean;
+};
+
+const AddButton = ({ options, onSelected, hasSelectedIdentifiers }: Props) => {
+  const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
+
+  if (options.length === 0) {
+    return null;
+  }
+  const addSignInMethodButtonProps: ButtonProps = {
+    type: 'default',
+    size: 'medium',
+    title: 'sign_in_exp.sign_up_and_sign_in.sign_in.add_sign_in_method',
+    icon: <Plus className={styles.plusIcon} />,
+  };
+
+  const addAnotherButtonProps: ButtonProps = {
+    type: 'text',
+    size: 'small',
+    title: 'general.add_another',
+  };
+
+  return (
+    <ActionMenu
+      buttonProps={hasSelectedIdentifiers ? addAnotherButtonProps : addSignInMethodButtonProps}
+      dropdownHorizontalAlign="start"
+      dropdownClassName={classNames(
+        hasSelectedIdentifiers
+          ? styles.addAnotherSignInMethodDropdown
+          : styles.addSignInMethodDropDown
+      )}
+      isDropdownFullWidth={!hasSelectedIdentifiers}
+    >
+      {options.map((identifier) => (
+        <DropdownItem
+          key={identifier}
+          onClick={() => {
+            onSelected(identifier);
+          }}
+        >
+          {t('sign_in_exp.sign_up_and_sign_in.identifiers', { context: snakeCase(identifier) })}
+        </DropdownItem>
+      ))}
+    </ActionMenu>
+  );
+};
+
+export default AddButton;
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddSignInMethodButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddSignInMethodButton.tsx
deleted file mode 100644
index c7d31f9e6..000000000
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/AddSignInMethodButton.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import type { SignInIdentifier } from '@logto/schemas';
-import { useTranslation } from 'react-i18next';
-import { snakeCase } from 'snake-case';
-
-import ActionMenu from '@/components/ActionMenu';
-import { DropdownItem } from '@/components/Dropdown';
-
-import * as styles from './index.module.scss';
-
-type Props = {
-  options: SignInIdentifier[];
-  onSelected: (signInIdentifier: SignInIdentifier) => void;
-};
-
-const AddSignInMethodButton = ({ options, onSelected }: Props) => {
-  const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
-
-  if (options.length === 0) {
-    return null;
-  }
-
-  return (
-    <ActionMenu
-      buttonProps={{
-        type: 'text',
-        size: 'small',
-        title: 'general.add_another',
-      }}
-      dropdownHorizontalAlign="start"
-      dropDownClassName={styles.addSignInMethodDropdown}
-    >
-      {options.map((identifier) => (
-        <DropdownItem
-          key={identifier}
-          onClick={() => {
-            onSelected(identifier);
-          }}
-        >
-          {t('sign_in_exp.sign_up_and_sign_in.identifiers', { context: snakeCase(identifier) })}
-        </DropdownItem>
-      ))}
-    </ActionMenu>
-  );
-};
-
-export default AddSignInMethodButton;
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.module.scss
index 169b16b33..31111b57a 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.module.scss
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.module.scss
@@ -42,6 +42,14 @@
   }
 }
 
-.addSignInMethodDropdown {
+.plusIcon {
+  color: var(--color-text-secondary);
+}
+
+.addAnotherSignInMethodDropdown {
   min-width: 208px;
 }
+
+.addSignInMethodDropDown {
+  min-width: unset;
+}
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.tsx
index aa4505cfa..7203b95c7 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.tsx
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SignInMethodEditBox/index.tsx
@@ -7,7 +7,7 @@ import DraggableItem from '@/components/Transfer/DraggableItem';
 
 import { signInIdentifiers, signInIdentifierToRequiredConnectorMapping } from '../../constants';
 import ConnectorSetupWarning from '../ConnectorSetupWarning';
-import AddSignInMethodButton from './AddSignInMethodButton';
+import AddButton from './AddButton';
 import SignInMethodItem from './SignInMethodItem';
 import type { SignInMethod } from './types';
 import {
@@ -166,7 +166,11 @@ const SignInMethodEditBox = ({
           []
         )}
       />
-      <AddSignInMethodButton options={signInIdentifierOptions} onSelected={addSignInMethod} />
+      <AddButton
+        options={signInIdentifierOptions}
+        hasSelectedIdentifiers={value.length > 0}
+        onSelected={addSignInMethod}
+      />
     </div>
   );
 };
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss
index 12944b76b..ca906becb 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss
@@ -1,6 +1,10 @@
 @use '@/scss/underscore' as _;
 
 .dropdown {
+  min-width: unset;
+}
+
+.addAnotherDropdown {
   min-width: 208px;
 }
 
diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx
index 468dc1c25..a16d19fd1 100644
--- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx
+++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx
@@ -1,3 +1,5 @@
+import classNames from 'classnames';
+
 import Plus from '@/assets/images/plus.svg';
 import ActionMenu from '@/components/ActionMenu';
 import type { Props as ButtonProps } from '@/components/Button';
@@ -36,7 +38,10 @@ const AddButton = ({ options, onSelected, hasSelectedConnectors }: Props) => {
     <ActionMenu
       buttonProps={hasSelectedConnectors ? addAnotherButtonProps : addSocialConnectorButtonProps}
       dropdownHorizontalAlign="start"
-      dropDownClassName={styles.dropdown}
+      dropdownClassName={classNames(
+        hasSelectedConnectors ? styles.addAnotherDropdown : styles.dropdown
+      )}
+      isDropdownFullWidth={!hasSelectedConnectors}
     >
       {options.map(({ target, logo, name, connectors }) => (
         <DropdownItem
diff --git a/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts
index 3b435a6df..0f2bd4588 100644
--- a/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts
@@ -58,6 +58,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication',
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.',
+      add_sign_in_method: 'Add Sign-in Method',
       password_auth: 'Password',
       verification_code_auth: 'Verification code',
       auth_swap_tip: 'Swap to change the priority',
diff --git a/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts
index cce17e7b5..b90bd7f06 100644
--- a/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts
@@ -60,6 +60,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication', // UNTRANSLATED
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.', // UNTRANSLATED
+      add_sign_in_method: 'Add Sign-in Method', // UNTRANSLATED
       password_auth: 'Password', // UNTRANSLATED
       verification_code_auth: 'Verification code', // UNTRANSLATED
       auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED
diff --git a/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts
index 6b50591d1..fbb085769 100644
--- a/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts
@@ -55,6 +55,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication', // UNTRANSLATED
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.', // UNTRANSLATED
+      add_sign_in_method: 'Add Sign-in Method', // UNTRANSLATED
       password_auth: 'Password', // UNTRANSLATED
       verification_code_auth: 'Verification code', // UNTRANSLATED
       auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED
diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts
index 32535bb5e..8c2d39d23 100644
--- a/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts
@@ -58,6 +58,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication', // UNTRANSLATED
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.', // UNTRANSLATED
+      add_sign_in_method: 'Add Sign-in Method', // UNTRANSLATED
       password_auth: 'Password', // UNTRANSLATED
       verification_code_auth: 'Verification code', // UNTRANSLATED
       auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED
diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts
index 9e9f60fee..5bc870bb0 100644
--- a/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts
@@ -59,6 +59,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication', // UNTRANSLATED
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.', // UNTRANSLATED
+      add_sign_in_method: 'Add Sign-in Method', // UNTRANSLATED
       password_auth: 'Password', // UNTRANSLATED
       verification_code_auth: 'Verification code', // UNTRANSLATED
       auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED
diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts
index 500544914..c57d1859a 100644
--- a/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts
+++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts
@@ -56,6 +56,7 @@ const sign_in_exp = {
       sign_in_identifier_and_auth: 'Sign in identifier and authentication', // UNTRANSLATED
       description:
         'Users can use any one of the selected ways to sign in. Drag and drop to define identifier priority regarding the sign in flow. You can also define the password or verification code priority.', // UNTRANSLATED
+      add_sign_in_method: 'Add Sign-in Method', // UNTRANSLATED
       password_auth: 'Password', // UNTRANSLATED
       verification_code_auth: 'Verification code', // UNTRANSLATED
       auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED