diff --git a/packages/console/src/pages/Connectors/components/CreateForm/index.tsx b/packages/console/src/pages/Connectors/components/CreateForm/index.tsx index 50848092b..1cb71706d 100644 --- a/packages/console/src/pages/Connectors/components/CreateForm/index.tsx +++ b/packages/console/src/pages/Connectors/components/CreateForm/index.tsx @@ -50,7 +50,9 @@ const CreateForm = ({ onClose, isOpen: isFormOpen, type }: Props) => { ...group, connectors: group.connectors.map((connector) => ({ ...connector, - added: existingConnectors.some(({ connectorId }) => connector.id === connectorId), + added: group.isStandard + ? false + : existingConnectors.some(({ connectorId }) => connector.id === connectorId), })), })); }, [factories, type, existingConnectors]); diff --git a/packages/console/src/pages/Connectors/components/Guide/Form.tsx b/packages/console/src/pages/Connectors/components/Guide/Form.tsx new file mode 100644 index 000000000..a8d3a7fee --- /dev/null +++ b/packages/console/src/pages/Connectors/components/Guide/Form.tsx @@ -0,0 +1,92 @@ +import type { ConnectorFactoryResponse } from '@logto/schemas'; +import { useState } from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; + +import Button from '@/components/Button'; +import CodeEditor from '@/components/CodeEditor'; +import FormField from '@/components/FormField'; +import TextInput from '@/components/TextInput'; + +import * as styles from './index.module.scss'; +import type { CreateConnectorForm } from './types'; + +type Props = { + connector: ConnectorFactoryResponse; +}; + +const Form = ({ connector }: Props) => { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { configTemplate, isStandard } = connector; + const { control, register } = useFormContext(); + const [darkVisible, setDarkVisible] = useState(false); + + const toggleDarkVisible = () => { + setDarkVisible((previous) => !previous); + }; + + return ( +
+ {isStandard && ( + <> + + +
{t('connectors.guide.name_tip')}
+
+ + +
{t('connectors.guide.logo_tip')}
+
+ {!darkVisible && ( +
+ ); +}; + +export default Form; diff --git a/packages/console/src/pages/Connectors/components/Guide/index.module.scss b/packages/console/src/pages/Connectors/components/Guide/index.module.scss index d268d1d58..be2632775 100644 --- a/packages/console/src/pages/Connectors/components/Guide/index.module.scss +++ b/packages/console/src/pages/Connectors/components/Guide/index.module.scss @@ -42,11 +42,31 @@ background-color: var(--color-layer-1); border-radius: 16px; padding: 0 _.unit(6); - margin: _.unit(6) _.unit(10) _.unit(6) _.unit(18); + margin: _.unit(6) _.unit(3) _.unit(6) _.unit(18); } .setup { - padding: _.unit(6) _.unit(18) _.unit(6) 0; + background-color: var(--color-layer-1); + border-radius: 16px; + padding: 0 _.unit(6) _.unit(6); + margin: _.unit(6) _.unit(18) _.unit(6) _.unit(3); + + .title { + font: var(--font-title-large); + margin: _.unit(6) 0; + } + + .tip { + color: var(--color-text-secondary); + font: var(--font-body-medium); + margin-top: _.unit(0.5); + } + + .footer { + margin-top: _.unit(6); + display: flex; + justify-content: right; + } } form + div { @@ -55,7 +75,6 @@ } } -.editor, .tester { margin-top: _.unit(6); } diff --git a/packages/console/src/pages/Connectors/components/Guide/index.tsx b/packages/console/src/pages/Connectors/components/Guide/index.tsx index f767a7ad4..7a2b5062d 100644 --- a/packages/console/src/pages/Connectors/components/Guide/index.tsx +++ b/packages/console/src/pages/Connectors/components/Guide/index.tsx @@ -3,24 +3,24 @@ import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas import { ConnectorType } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import i18next from 'i18next'; -import { Controller, useForm } from 'react-hook-form'; +import { FormProvider, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import Close from '@/assets/images/close.svg'; +import Button from '@/components/Button'; import CardTitle from '@/components/CardTitle'; -import CodeEditor from '@/components/CodeEditor'; import DangerousRaw from '@/components/DangerousRaw'; import IconButton from '@/components/IconButton'; import Markdown from '@/components/Markdown'; import useApi from '@/hooks/use-api'; import useSettings from '@/hooks/use-settings'; -import Step from '@/mdx-components/Step'; import SenderTester from '@/pages/ConnectorDetails/components/SenderTester'; -import type { GuideForm } from '@/types/guide'; import { safeParseJson } from '@/utilities/json'; +import Form from './Form'; import * as styles from './index.module.scss'; +import type { CreateConnectorForm } from './types'; type Props = { connector: ConnectorFactoryResponse; @@ -31,25 +31,25 @@ const Guide = ({ connector, onClose }: Props) => { const api = useApi(); const { updateSettings } = useSettings(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const { id: connectorId, type: connectorType, name, configTemplate, readme } = connector; + const { id: connectorId, type: connectorType, name, readme, isStandard } = connector; const { language } = i18next; const connectorName = conditional(isLanguageTag(language) && name[language]) ?? name.en; const isSocialConnector = connectorType !== ConnectorType.Sms && connectorType !== ConnectorType.Email; - const methods = useForm({ reValidateMode: 'onBlur' }); + const methods = useForm({ reValidateMode: 'onBlur' }); const { - control, formState: { isSubmitting }, handleSubmit, watch, } = methods; - const onSubmit = handleSubmit(async ({ connectorConfigJson }) => { + const onSubmit = handleSubmit(async (data) => { if (isSubmitting) { return; } - const result = safeParseJson(connectorConfigJson); + const { config, name, ...otherData } = data; + const result = safeParseJson(config); if (!result.success) { toast.error(result.error); @@ -60,7 +60,18 @@ const Guide = ({ connector, onClose }: Props) => { const { id: connectorId } = connector; await api - .post('/api/connectors', { json: { config: result.data, connectorId } }) + .post('/api/connectors', { + json: { + config: result.data, + connectorId, + metadata: conditional( + isStandard && { + ...otherData, + name: { en: name }, + } + ), + }, + }) .json(); await updateSettings({ @@ -88,39 +99,28 @@ const Guide = ({ connector, onClose }: Props) => {
{readme}
- -
- ( - - )} - /> +
{t('connectors.guide.connector_setting')}
+ + + + {!isSocialConnector && ( + + )} +
+
- {!isSocialConnector && ( - - )} -
+
diff --git a/packages/console/src/pages/Connectors/components/Guide/types.ts b/packages/console/src/pages/Connectors/components/Guide/types.ts new file mode 100644 index 000000000..8baebf461 --- /dev/null +++ b/packages/console/src/pages/Connectors/components/Guide/types.ts @@ -0,0 +1,7 @@ +export type CreateConnectorForm = { + config: string; + name: string; + logo: string; + logoDark: string; + target: string; +}; diff --git a/packages/console/src/pages/Connectors/utils/index.ts b/packages/console/src/pages/Connectors/utils/index.ts index 8cff69858..79212e0e0 100644 --- a/packages/console/src/pages/Connectors/utils/index.ts +++ b/packages/console/src/pages/Connectors/utils/index.ts @@ -25,6 +25,7 @@ export const getConnectorGroups = < description: item.description, target: item.target, type: item.type, + isStandard: item.isStandard, connectors: [item], }, ]; diff --git a/packages/console/src/types/connector.ts b/packages/console/src/types/connector.ts index 061a65f04..08e8f58e0 100644 --- a/packages/console/src/types/connector.ts +++ b/packages/console/src/types/connector.ts @@ -2,7 +2,7 @@ import type { ConnectorResponse } from '@logto/schemas'; export type ConnectorGroup = Pick< ConnectorResponse, - 'name' | 'logo' | 'logoDark' | 'target' | 'type' | 'description' + 'name' | 'logo' | 'logoDark' | 'target' | 'type' | 'description' | 'isStandard' > & { id: string; connectors: T[]; diff --git a/packages/console/src/types/guide.ts b/packages/console/src/types/guide.ts index 10418f263..9a22384dc 100644 --- a/packages/console/src/types/guide.ts +++ b/packages/console/src/types/guide.ts @@ -1,5 +1,4 @@ export type GuideForm = { redirectUris: string[]; postLogoutRedirectUris: string[]; - connectorConfigJson: string; }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/connectors.ts b/packages/phrases/src/locales/de/translation/admin-console/connectors.ts index 012a55a52..33af5d7f9 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/connectors.ts @@ -30,6 +30,21 @@ const connectors = { }, guide: { subtitle: 'Eine Schritt-für-Schritt-Anleitung zur Konfiguration deines Connectors', + connector_setting: 'Connector setting', // UNTRANSLATED + name: 'Connector name', // UNTRANSLATED + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', // UNTRANSLATED + logo: 'Connector logo URL', // UNTRANSLATED + logo_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_tip: 'The logo image will also display on the connector button.', // UNTRANSLATED + logo_dark: 'Connector logo URL (Dark mode)', // UNTRANSLATED + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', // UNTRANSLATED + logo_dark_collapse: 'Collapse', // UNTRANSLATED + logo_dark_show: 'Show "Logo for dark mode"', // UNTRANSLATED + target: 'Connector identity target', // UNTRANSLATED + target_tip: 'A unique identifier for the connector.', // UNTRANSLATED + config: 'Enter your JSON here', // UNTRANSLATED }, platform: { universal: 'Universal', diff --git a/packages/phrases/src/locales/en/translation/admin-console/connectors.ts b/packages/phrases/src/locales/en/translation/admin-console/connectors.ts index 993947c0a..1aebb7034 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/connectors.ts @@ -30,6 +30,21 @@ const connectors = { }, guide: { subtitle: 'A step by step guide to configure your connector', + connector_setting: 'Connector setting', + name: 'Connector name', + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', + logo: 'Connector logo URL', + logo_placelholder: 'https://your.cdn.domain/logo.png', + logo_tip: 'The logo image will also display on the connector button.', + logo_dark: 'Connector logo URL (Dark mode)', + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', + logo_dark_collapse: 'Collapse', + logo_dark_show: 'Show "Logo for dark mode"', + target: 'Connector identity target', + target_tip: 'A unique identifier for the connector.', + config: 'Enter your JSON here', }, platform: { universal: 'Universal', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/connectors.ts b/packages/phrases/src/locales/fr/translation/admin-console/connectors.ts index 894bb377f..dfc02a9eb 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/connectors.ts @@ -31,6 +31,21 @@ const connectors = { }, guide: { subtitle: 'Un guide étape par étape pour configurer votre connecteur', + connector_setting: 'Connector setting', // UNTRANSLATED + name: 'Connector name', // UNTRANSLATED + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', // UNTRANSLATED + logo: 'Connector logo URL', // UNTRANSLATED + logo_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_tip: 'The logo image will also display on the connector button.', // UNTRANSLATED + logo_dark: 'Connector logo URL (Dark mode)', // UNTRANSLATED + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', // UNTRANSLATED + logo_dark_collapse: 'Collapse', // UNTRANSLATED + logo_dark_show: 'Show "Logo for dark mode"', // UNTRANSLATED + target: 'Connector identity target', // UNTRANSLATED + target_tip: 'A unique identifier for the connector.', // UNTRANSLATED + config: 'Enter your JSON here', // UNTRANSLATED }, platform: { universal: 'Universel', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/connectors.ts b/packages/phrases/src/locales/ko/translation/admin-console/connectors.ts index f6936ee0e..096d18946 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/connectors.ts @@ -30,6 +30,21 @@ const connectors = { }, guide: { subtitle: '단계별 가이드를 따라, 연동해주세요.', + connector_setting: 'Connector setting', // UNTRANSLATED + name: 'Connector name', // UNTRANSLATED + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', // UNTRANSLATED + logo: 'Connector logo URL', // UNTRANSLATED + logo_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_tip: 'The logo image will also display on the connector button.', // UNTRANSLATED + logo_dark: 'Connector logo URL (Dark mode)', // UNTRANSLATED + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', // UNTRANSLATED + logo_dark_collapse: 'Collapse', // UNTRANSLATED + logo_dark_show: 'Show "Logo for dark mode"', // UNTRANSLATED + target: 'Connector identity target', // UNTRANSLATED + target_tip: 'A unique identifier for the connector.', // UNTRANSLATED + config: 'Enter your JSON here', // UNTRANSLATED }, platform: { universal: 'Universal', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/connectors.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/connectors.ts index 2499f0edf..8f336f598 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/connectors.ts @@ -30,6 +30,21 @@ const connectors = { }, guide: { subtitle: 'Um guia passo a passo para configurar o conector', + connector_setting: 'Connector setting', // UNTRANSLATED + name: 'Connector name', // UNTRANSLATED + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', // UNTRANSLATED + logo: 'Connector logo URL', // UNTRANSLATED + logo_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_tip: 'The logo image will also display on the connector button.', // UNTRANSLATED + logo_dark: 'Connector logo URL (Dark mode)', // UNTRANSLATED + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', // UNTRANSLATED + logo_dark_collapse: 'Collapse', // UNTRANSLATED + logo_dark_show: 'Show "Logo for dark mode"', // UNTRANSLATED + target: 'Connector identity target', // UNTRANSLATED + target_tip: 'A unique identifier for the connector.', // UNTRANSLATED + config: 'Enter your JSON here', // UNTRANSLATED }, platform: { universal: 'Universal', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/connectors.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/connectors.ts index 92c226579..32af270a5 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/connectors.ts @@ -31,6 +31,21 @@ const connectors = { }, guide: { subtitle: 'Connectorı yapılandırmak için adım adım kılavuz', + connector_setting: 'Connector setting', // UNTRANSLATED + name: 'Connector name', // UNTRANSLATED + name_tip: 'Connector button’s name will display as "Continue with {{Connector Name}}".', // UNTRANSLATED + logo: 'Connector logo URL', // UNTRANSLATED + logo_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_tip: 'The logo image will also display on the connector button.', // UNTRANSLATED + logo_dark: 'Connector logo URL (Dark mode)', // UNTRANSLATED + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', // UNTRANSLATED + logo_dark_tip: + 'This will be used when opening “Enable dark mode” in the setting of sign in experience.', // UNTRANSLATED + logo_dark_collapse: 'Collapse', // UNTRANSLATED + logo_dark_show: 'Show "Logo for dark mode"', // UNTRANSLATED + target: 'Connector identity target', // UNTRANSLATED + target_tip: 'A unique identifier for the connector.', // UNTRANSLATED + config: 'Enter your JSON here', // UNTRANSLATED }, platform: { universal: 'Evrensel', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/connectors.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/connectors.ts index 206191760..70380b49e 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/connectors.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/connectors.ts @@ -29,6 +29,20 @@ const connectors = { }, guide: { subtitle: '参考以下步骤完成你的连接器设置', + connector_setting: '连接器设置', + name: '连接器名称', + name_tip: '连接器按钮名将会是「通过 {{连接器名称}} 登录」。', + logo: '连接器图标地址', + logo_placelholder: 'https://your.cdn.domain/logo.png', + logo_tip: '图标将会在连接器按钮中展示', + logo_dark: '连接器图标地址(深色模式)', + logo_dark_placelholder: 'https://your.cdn.domain/logo.png', + logo_dark_tip: '在登录体验设置中打开「启用深色模式」后生效', + logo_dark_collapse: '折叠', + logo_dark_show: '显示「深色模式图标」', + target: '连接器 target', + target_tip: '连接器标识符', + config: '请在此输入你的 JSON 配置', }, platform: { universal: '通用',