0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00

feat(console): new style for create and edit connector (#3126)

This commit is contained in:
wangsijie 2023-02-20 18:04:43 +08:00 committed by GitHub
parent ae5046fc8b
commit 312b899a20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 148 additions and 46 deletions

View file

@ -1,9 +1,5 @@
@use '@/scss/underscore' as _;
.configForm {
margin-top: _.unit(6);
}
.senderTest {
margin-top: _.unit(6);
}

View file

@ -1,5 +1,6 @@
import type { ConnectorResponse } from '@logto/schemas';
import { ConnectorType } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
@ -43,6 +44,7 @@ const ConnectorContent = ({ isDeleted, connectorData, onConnectorUpdated }: Prop
watch,
reset,
} = methods;
const isSocialConnector = connectorData.type === ConnectorType.Social;
useEffect(() => {
const { formItems, metadata, config, syncProfile } = connectorData;
@ -64,13 +66,12 @@ const ConnectorContent = ({ isDeleted, connectorData, onConnectorUpdated }: Prop
const config = formItems ? parseFormConfig(data, formItems) : parseJsonConfig(data.config);
const { syncProfile, name, logo, logoDark, target } = data;
const payload =
connectorData.type === ConnectorType.Social
? {
config,
syncProfile: syncProfile === SyncProfileMode.EachSignIn,
}
: { config };
const payload = isSocialConnector
? {
config,
syncProfile: syncProfile === SyncProfileMode.EachSignIn,
}
: { config };
const standardConnectorPayload = {
...payload,
metadata: { name: { en: name }, logo, logoDark, target },
@ -95,26 +96,39 @@ const ConnectorContent = ({ isDeleted, connectorData, onConnectorUpdated }: Prop
onDiscard={reset}
onSubmit={onSubmit}
>
{isSocialConnector && (
<FormCard
title="connector_details.settings"
description="connector_details.settings_description"
learnMoreLink={getDocumentationUrl('/docs/references/connectors')}
>
<BasicForm
connectorType={connectorData.type}
isStandard={connectorData.isStandard}
isDarkDefaultVisible={Boolean(connectorData.metadata.logoDark)}
/>
</FormCard>
)}
<FormCard
title="connector_details.settings"
description="connector_details.settings_description"
learnMoreLink={getDocumentationUrl('/docs/references/connectors')}
title="connector_details.parameter_configuaration"
description={conditional(!isSocialConnector && 'connector_details.settings_description')}
learnMoreLink={conditional(
!isSocialConnector && getDocumentationUrl('/docs/references/connectors')
)}
>
<BasicForm
connectorType={connectorData.type}
isStandard={connectorData.isStandard}
isDarkDefaultVisible={Boolean(connectorData.metadata.logoDark)}
/>
<ConfigForm className={styles.configForm} formItems={connectorData.formItems} />
{connectorData.type !== ConnectorType.Social && (
<ConfigForm formItems={connectorData.formItems} />
</FormCard>
{/* Tell typescript that the connectorType is Email or Sms */}
{connectorData.type !== ConnectorType.Social && (
<FormCard title="connector_details.test_connection">
<SenderTester
className={styles.senderTest}
connectorId={connectorData.id}
connectorType={connectorData.type}
config={watch('config')}
/>
)}
</FormCard>
</FormCard>
)}
</DetailsForm>
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleted && isDirty} />
</FormProvider>

View file

@ -9,7 +9,7 @@
.header {
display: flex;
align-items: center;
background-color: var(--color-layer-1);
background: none;
height: 64px;
padding: 0 _.unit(21) 0 _.unit(2);
@ -40,19 +40,51 @@
.readme {
background-color: var(--color-layer-1);
border: 1.5px solid var(--color-focused-variant);
border-radius: 16px;
padding: 0 _.unit(6);
margin: _.unit(6) _.unit(3) _.unit(6) _.unit(18);
margin: _.unit(2) _.unit(3) _.unit(6) _.unit(18);
overflow: hidden;
.readmeTitle {
font: var(--font-title-1);
padding: _.unit(5) _.unit(6) _.unit(4);
border-bottom: 1px solid var(--color-focused-variant);
}
.readmeContent {
padding: 0 _.unit(6);
overflow-y: auto;
height: 100%;
}
}
.setup {
margin: _.unit(6) _.unit(18) _.unit(6) _.unit(3);
margin: _.unit(2) _.unit(18) _.unit(6) _.unit(3);
.block {
background-color: var(--color-layer-1);
border-radius: 16px;
padding: _.unit(6);
padding: 0 _.unit(6) _.unit(6);
margin-bottom: _.unit(6);
.blockTitle {
font: var(--font-title-1);
padding: _.unit(5) 0 _.unit(6);
display: flex;
align-items: center;
gap: _.unit(4);
.number {
width: 28px;
height: 28px;
border-radius: 50%;
background-color: var(--color-focused-variant);
color: var(--color-primary);
font: var(--font-title-2);
text-align: center;
line-height: 28px;
}
}
}
.footer {

View file

@ -21,6 +21,7 @@ import SenderTester from '@/pages/ConnectorDetails/components/SenderTester';
import type { ConnectorFormType } from '../../types';
import { SyncProfileMode } from '../../types';
import { splitMarkdownByTitle } from '../../utils';
import BasicForm from '../ConnectorForm/BasicForm';
import ConfigForm from '../ConnectorForm/ConfigForm';
import { useConfigParser } from '../ConnectorForm/hooks';
@ -38,7 +39,8 @@ const Guide = ({ connector, onClose }: Props) => {
const { updateConfigs } = useConfigs();
const parseJsonConfig = useConfigParser();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { id: connectorId, type: connectorType, name, readme, isStandard, formItems } = connector;
const { id: connectorId, type: connectorType, name, readme, formItems } = connector;
const { title, content } = splitMarkdownByTitle(readme);
const { language } = i18next;
const connectorName = conditional(isLanguageTag(language) && name[language]) ?? name.en;
const isSocialConnector =
@ -116,12 +118,19 @@ const Guide = ({ connector, onClose }: Props) => {
/>
</div>
<div className={styles.content}>
<Markdown className={styles.readme}>{readme}</Markdown>
<div className={styles.readme}>
<div className={styles.readmeTitle}>README: {title}</div>
<Markdown className={styles.readmeContent}>{content}</Markdown>
</div>
<div className={styles.setup}>
<FormProvider {...methods}>
<form onSubmit={onSubmit}>
{isSocialConnector && (
<div className={styles.block}>
<div className={styles.blockTitle}>
<div className={styles.number}>1</div>
<div>{t('connectors.guide.general_setting')}</div>
</div>
<BasicForm
isAllowEditTarget
connectorType={connector.type}
@ -130,6 +139,10 @@ const Guide = ({ connector, onClose }: Props) => {
</div>
)}
<div className={styles.block}>
<div className={styles.blockTitle}>
<div className={styles.number}>{isSocialConnector ? 2 : 1}</div>
<div>{t('connectors.guide.parameter_configuaration')}</div>
</div>
<ConfigForm
configTemplate={connector.configTemplate}
formItems={connector.formItems}
@ -137,6 +150,10 @@ const Guide = ({ connector, onClose }: Props) => {
</div>
{!isSocialConnector && (
<div className={styles.block}>
<div className={styles.blockTitle}>
<div className={styles.number}>2</div>
<div>{t('connectors.guide.general_setting')}</div>
</div>
<SenderTester
connectorId={connectorId}
connectorType={connectorType}

View file

@ -43,3 +43,14 @@ export const getConnectorGroups = <
});
}, []);
};
export const splitMarkdownByTitle = (markdown: string) => {
const match = /# (.*)/.exec(markdown);
const title = (match ? match[1] : '') ?? '';
return {
title,
content: markdown.replace(title, ''),
};
};

View file

@ -1,10 +1,12 @@
const connector_details = {
back_to_connectors: 'Zurück zu Connectoren',
check_readme: 'Zur README',
settings: 'Settings', // UNTRANSLATED
settings: 'General settings', // UNTRANSLATED
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.', // UNTRANSLATED
save_error_empty_config: 'Bitte fülle die Konfiguration aus',
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
send: 'Senden',
send_error_invalid_format: 'Ungültige Eingabe',
edit_config_label: 'Gib deine JSON-Konfiguration ein',

View file

@ -30,7 +30,9 @@ const connectors = {
},
guide: {
subtitle: 'Eine Schritt-für-Schritt-Anleitung zur Konfiguration deines Connectors',
connector_setting: 'Connector setting', // UNTRANSLATED
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: 'Connector name', // UNTRANSLATED
name_tip:
'The name of the connector button will be displayed as "Continue with {{name}}." Be mindful of the length of the naming in case it gets too long.', // UNTRANSLATED

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: 'Back to Connectors',
check_readme: 'Check README',
settings: 'Settings',
settings: 'General settings',
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.',
parameter_configuaration: 'Parameter configuration',
test_connection: 'Test connection',
save_error_empty_config: 'Please enter config',
send: 'Send',
send_error_invalid_format: 'Invalid input',

View file

@ -30,7 +30,9 @@ const connectors = {
},
guide: {
subtitle: 'A step by step guide to configure your connector',
connector_setting: 'Connector setting',
general_setting: 'General settings',
parameter_configuaration: 'Parameter configuration',
test_connection: 'Test connection',
name: 'Connector name',
name_tip:
'The name of the connector button will be displayed as "Continue with {{name}}." Be mindful of the length of the naming in case it gets too long.',

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: 'Retour à Connecteurs',
check_readme: 'Vérifier le README',
settings: 'Settings', // UNTRANSLATED
settings: 'General settings', // UNTRANSLATED
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
save_error_empty_config: 'Veuillez entrer la configuration',
send: 'Envoyer',
send_error_invalid_format: 'Entrée non valide',

View file

@ -31,7 +31,9 @@ const connectors = {
},
guide: {
subtitle: 'Un guide étape par étape pour configurer votre connecteur',
connector_setting: 'Connector setting', // UNTRANSLATED
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: 'Connector name', // UNTRANSLATED
name_tip:
'The name of the connector button will be displayed as "Continue with {{name}}." Be mindful of the length of the naming in case it gets too long.', // UNTRANSLATED

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: '연동으로 돌아가기',
check_readme: 'README 확인',
settings: '설정',
settings: 'General settings', // UNTRANSLATED
settings_description:
'Logto에서 연동은 중요한 역할을 해요. 연동 시스템을 통하여, 사용자들에게 비밀번호 없이 회원 가입을 하고 로그인을 할 수 있게 하거나, 소셜 계정을 통하여 로그인을 할 수 있게 도와줘요.',
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
save_error_empty_config: '설정을 입력해 주세요.',
send: '보내기',
send_error_invalid_format: '유효하지 않은 입력',

View file

@ -31,7 +31,9 @@ const connectors = {
},
guide: {
subtitle: '단계별 가이드를 따라, 연동해 주세요.',
connector_setting: '연동 설정',
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: '연동 이름',
name_tip: '다음과 같이 연동 이름이 출력돼요. "{{name}}으로 계속하기".',
logo: '연동 로고 URL',

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: 'Voltar para Conectores',
check_readme: 'Visualize o README',
settings: 'Configurações',
settings: 'General settings', // UNTRANSLATED
settings_description:
'Os conectores desempenham um papel crítico no Logto. Com a ajuda deles, a Logto permite que os usuários finais usem o registro ou login sem senha e os recursos de login com contas sociais.',
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
save_error_empty_config: 'Por favor insira a configuração',
send: 'Enviar',
send_error_invalid_format: 'Campo inválido',

View file

@ -31,7 +31,9 @@ const connectors = {
},
guide: {
subtitle: 'Um guia passo a passo para configurar seu conector',
connector_setting: 'Configuração do conector',
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: 'Nome do conector',
name_tip: 'O nome do botão do conector será exibido como "Continue com {{Connector Name}}".',
logo: 'URL do logotipo do conector',

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: 'Voltar para Conectores',
check_readme: 'Verifique o README',
settings: 'Settings', // UNTRANSLATED
settings: 'General settings', // UNTRANSLATED
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
save_error_empty_config: 'Por favor, insira a configuração',
send: 'Enviar',
send_error_invalid_format: 'Entrada inválida',

View file

@ -30,7 +30,9 @@ const connectors = {
},
guide: {
subtitle: 'Um guia passo a passo para configurar o conector',
connector_setting: 'Connector setting', // UNTRANSLATED
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: 'Connector name', // UNTRANSLATED
name_tip:
'The name of the connector button will be displayed as "Continue with {{name}}." Be mindful of the length of the naming in case it gets too long.', // UNTRANSLATED

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: 'Connectorlara dön',
check_readme: 'READMEye göz at',
settings: 'Settings', // UNTRANSLATED
settings: 'General settings', // UNTRANSLATED
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
save_error_empty_config: 'Lütfen yapılandırmayı girin',
send: 'Gönder',
send_error_invalid_format: 'Geçersiz input',

View file

@ -31,7 +31,9 @@ const connectors = {
},
guide: {
subtitle: 'Connectorı yapılandırmak için adım adım kılavuz',
connector_setting: 'Connector setting', // UNTRANSLATED
general_setting: 'General settings', // UNTRANSLATED
parameter_configuaration: 'Parameter configuration', // UNTRANSLATED
test_connection: 'Test connection', // UNTRANSLATED
name: 'Connector name', // UNTRANSLATED
name_tip:
'The name of the connector button will be displayed as "Continue with {{name}}." Be mindful of the length of the naming in case it gets too long.', // UNTRANSLATED

View file

@ -1,9 +1,11 @@
const connector_details = {
back_to_connectors: '返回连接器',
check_readme: '查看 README',
settings: '设置',
settings: '通用设置',
settings_description:
'Connectors play a critical role in Logto. With their help, Logto enables end-users to use passwordless registration or sign-in and the capabilities of signing in with social accounts.', // UNTRANSLATED
parameter_configuaration: '参数配置',
test_connection: '连接测试',
save_error_empty_config: '请输入配置内容',
send: '发送',
send_error_invalid_format: '无效输入',

View file

@ -29,7 +29,9 @@ const connectors = {
},
guide: {
subtitle: '参考以下步骤完成你的连接器设置',
connector_setting: '设置连接器',
general_setting: '通用设置',
parameter_configuaration: '参数配置',
test_connection: '连接测试',
name: '连接器名称',
name_tip: '按钮上将展示「通过 {{name}} 继续」。名字不宜过长而导致信息无法展示完整。',
logo: 'Logo 图片链接',