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:
parent
43ecf01ce8
commit
fd1f81cbe9
8 changed files with 106 additions and 72 deletions
|
@ -0,0 +1,9 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.configForm {
|
||||
margin-top: _.unit(6);
|
||||
}
|
||||
|
||||
.senderTest {
|
||||
margin-top: _.unit(6);
|
||||
}
|
|
@ -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}
|
||||
|
|
|
@ -89,10 +89,6 @@
|
|||
margin-bottom: _.unit(6);
|
||||
}
|
||||
|
||||
.senderTest {
|
||||
margin-top: _.unit(6);
|
||||
}
|
||||
|
||||
.resetIcon {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue