0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

feat(console): group connector form items (#3115)

This commit is contained in:
wangsijie 2023-02-16 10:42:03 +08:00 committed by GitHub
parent 43ecf01ce8
commit fd1f81cbe9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 106 additions and 72 deletions

View file

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

View file

@ -10,13 +10,14 @@ import FormCard from '@/components/FormCard';
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
import useApi from '@/hooks/use-api';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import ConnectorForm from '@/pages/Connectors/components/ConnectorForm';
import BasicForm from '@/pages/Connectors/components/ConnectorForm/BasicForm';
import ConfigForm from '@/pages/Connectors/components/ConnectorForm/ConfigForm';
import { useConfigParser } from '@/pages/Connectors/components/ConnectorForm/hooks';
import { initFormData, parseFormConfig } from '@/pages/Connectors/components/ConnectorForm/utils';
import type { ConnectorFormType } from '@/pages/Connectors/types';
import { SyncProfileMode } from '@/pages/Connectors/types';
import * as styles from '../index.module.scss';
import * as styles from './ConnectorContent.module.scss';
import SenderTester from './SenderTester';
type Props = {
@ -99,12 +100,12 @@ const ConnectorContent = ({ isDeleted, connectorData, onConnectorUpdated }: Prop
description="connector_details.settings_description"
learnMoreLink={getDocumentationUrl('/docs/references/connectors')}
>
<ConnectorForm
<BasicForm
connectorType={connectorData.type}
isStandard={connectorData.isStandard}
isDarkDefaultVisible={Boolean(connectorData.metadata.logoDark)}
formItems={connectorData.formItems}
/>
<ConfigForm className={styles.configForm} formItems={connectorData.formItems} />
{connectorData.type !== ConnectorType.Social && (
<SenderTester
className={styles.senderTest}

View file

@ -89,10 +89,6 @@
margin-bottom: _.unit(6);
}
.senderTest {
margin-top: _.unit(6);
}
.resetIcon {
color: var(--color-text-secondary);
}

View file

@ -1,6 +1,4 @@
import type { ConnectorConfigFormItem } from '@logto/connector-kit';
import type { ConnectorFactoryResponse } from '@logto/schemas';
import { ConnectorType } from '@logto/schemas';
import { ConnectorType } from '@logto/connector-kit';
import { useState } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
@ -8,35 +6,29 @@ import { Trans, useTranslation } from 'react-i18next';
import CaretDown from '@/assets/images/caret-down.svg';
import CaretUp from '@/assets/images/caret-up.svg';
import Button from '@/components/Button';
import CodeEditor from '@/components/CodeEditor';
import FormField from '@/components/FormField';
import Select from '@/components/Select';
import TextInput from '@/components/TextInput';
import TextLink from '@/components/TextLink';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import { uriValidator, jsonValidator } from '@/utils/validator';
import { uriValidator } from '@/utils/validator';
import type { ConnectorFormType } from '../../types';
import { SyncProfileMode } from '../../types';
import ConfigForm from '../ConfigForm';
import * as styles from './index.module.scss';
import * as styles from './BasicForm.module.scss';
type Props = {
connectorType: ConnectorType;
isStandard: ConnectorFactoryResponse['isStandard'];
configTemplate?: ConnectorFactoryResponse['configTemplate'];
isAllowEditTarget?: boolean;
isDarkDefaultVisible?: boolean;
formItems?: ConnectorConfigFormItem[];
isStandard?: boolean;
connectorType: ConnectorType;
};
const ConnectorForm = ({
configTemplate,
isStandard,
const BasicForm = ({
isAllowEditTarget,
isDarkDefaultVisible,
connectorType,
formItems,
isStandard,
}: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { getDocumentationUrl } = useDocumentationUrl();
@ -136,29 +128,6 @@ const ConnectorForm = ({
</FormField>
</>
)}
{formItems ? (
<ConfigForm formItems={formItems} />
) : (
<FormField title="connectors.guide.config">
<Controller
name="config"
control={control}
defaultValue={configTemplate}
rules={{
validate: (value) => jsonValidator(value) || t('errors.invalid_json_format'),
}}
render={({ field: { onChange, value } }) => (
<CodeEditor
hasError={Boolean(errors.config)}
errorMessage={errors.config?.message}
language="json"
value={value}
onChange={onChange}
/>
)}
/>
</FormField>
)}
{connectorType === ConnectorType.Social && (
<FormField title="connectors.guide.sync_profile">
<Controller
@ -176,4 +145,4 @@ const ConnectorForm = ({
);
};
export default ConnectorForm;
export default BasicForm;

View file

@ -0,0 +1,55 @@
import type { ConnectorConfigFormItem } from '@logto/connector-kit';
import type { ConnectorFactoryResponse } from '@logto/schemas';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import CodeEditor from '@/components/CodeEditor';
import FormField from '@/components/FormField';
import { jsonValidator } from '@/utils/validator';
import type { ConnectorFormType } from '../../types';
import ConfigFormItems from '../ConfigForm';
type Props = {
configTemplate?: ConnectorFactoryResponse['configTemplate'];
formItems?: ConnectorConfigFormItem[];
className?: string;
};
const ConfigForm = ({ configTemplate, formItems, className }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const {
control,
formState: { errors },
} = useFormContext<ConnectorFormType>();
return (
<div className={className}>
{formItems ? (
<ConfigFormItems formItems={formItems} />
) : (
<FormField title="connectors.guide.config">
<Controller
name="config"
control={control}
defaultValue={configTemplate}
rules={{
validate: (value) => jsonValidator(value) || t('errors.invalid_json_format'),
}}
render={({ field: { onChange, value } }) => (
<CodeEditor
hasError={Boolean(errors.config)}
errorMessage={errors.config?.message}
language="json"
value={value}
onChange={onChange}
/>
)}
/>
</FormField>
)}
</div>
);
};
export default ConfigForm;

View file

@ -46,14 +46,13 @@
}
.setup {
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-1);
margin: _.unit(6) 0;
.block {
background-color: var(--color-layer-1);
border-radius: 16px;
padding: _.unit(6);
margin-bottom: _.unit(6);
}
.footer {
@ -68,7 +67,3 @@
}
}
}
.tester {
margin-top: _.unit(6);
}

View file

@ -21,7 +21,8 @@ import SenderTester from '@/pages/ConnectorDetails/components/SenderTester';
import type { ConnectorFormType } from '../../types';
import { SyncProfileMode } from '../../types';
import ConnectorForm from '../ConnectorForm';
import BasicForm from '../ConnectorForm/BasicForm';
import ConfigForm from '../ConnectorForm/ConfigForm';
import { useConfigParser } from '../ConnectorForm/hooks';
import { initFormData, parseFormConfig } from '../ConnectorForm/utils';
import * as styles from './index.module.scss';
@ -117,23 +118,31 @@ const Guide = ({ connector, onClose }: Props) => {
<div className={styles.content}>
<Markdown className={styles.readme}>{readme}</Markdown>
<div className={styles.setup}>
<div className={styles.title}>{t('connectors.guide.connector_setting')}</div>
<FormProvider {...methods}>
<form onSubmit={onSubmit}>
<ConnectorForm
isAllowEditTarget
connectorType={connector.type}
configTemplate={connector.configTemplate}
isStandard={connector.isStandard}
formItems={connector.formItems}
/>
{!isSocialConnector && (
<SenderTester
className={styles.tester}
connectorId={connectorId}
connectorType={connectorType}
config={watch('config')}
{isSocialConnector && (
<div className={styles.block}>
<BasicForm
isAllowEditTarget
connectorType={connector.type}
isStandard={connector.isStandard}
/>
</div>
)}
<div className={styles.block}>
<ConfigForm
configTemplate={connector.configTemplate}
formItems={connector.formItems}
/>
</div>
{!isSocialConnector && (
<div className={styles.block}>
<SenderTester
connectorId={connectorId}
connectorType={connectorType}
config={watch('config')}
/>
</div>
)}
<div className={styles.footer}>
<Button