diff --git a/client/packages/design/package.json b/client/packages/design/package.json index c295fc46..6bb5a092 100644 --- a/client/packages/design/package.json +++ b/client/packages/design/package.json @@ -29,7 +29,7 @@ "antd": "^4.19.5", "clsx": "^1.1.1", "lodash": "^4.17.21", - "react-fastify-form": "1.0.11", + "react-fastify-form": "1.0.12", "remirror": "^2.0.9", "str2int": "^1.1.0" }, diff --git a/client/web/src/components/modals/GroupPanel/CreateGroupPanel.tsx b/client/web/src/components/modals/GroupPanel/CreateGroupPanel.tsx index c90b8737..b8039684 100644 --- a/client/web/src/components/modals/GroupPanel/CreateGroupPanel.tsx +++ b/client/web/src/components/modals/GroupPanel/CreateGroupPanel.tsx @@ -5,24 +5,12 @@ import { createGroupPanel, showToasts, } from 'tailchat-shared'; -import { - createMetaFormSchema, - metaFormFieldSchema, - WebMetaForm, -} from 'tailchat-design'; +import { WebMetaForm } from 'tailchat-design'; import { ModalWrapper } from '../../Modal'; import { buildDataFromValues } from './helper'; import type { GroupPanelValues } from './types'; import { useGroupPanelFields } from './useGroupPanelFields'; -const schema = createMetaFormSchema({ - name: metaFormFieldSchema - .string() - .required(t('面板名不能为空')) - .max(20, t('面板名过长')), - type: metaFormFieldSchema.string().required(t('面板类型不能为空')), -}); - /** * 创建群组面板 */ @@ -41,7 +29,7 @@ export const ModalCreateGroupPanel: React.FC<{ [props.groupId, props.onSuccess] ); - const fields = useGroupPanelFields(props.groupId, currentValues); + const { fields, schema } = useGroupPanelFields(props.groupId, currentValues); return ( diff --git a/client/web/src/components/modals/GroupPanel/ModifyGroupPanel.tsx b/client/web/src/components/modals/GroupPanel/ModifyGroupPanel.tsx index 4d0d325c..8d65e973 100644 --- a/client/web/src/components/modals/GroupPanel/ModifyGroupPanel.tsx +++ b/client/web/src/components/modals/GroupPanel/ModifyGroupPanel.tsx @@ -8,23 +8,10 @@ import { useGroupPanelInfo, } from 'tailchat-shared'; import { ModalWrapper } from '../../Modal'; -import { - createMetaFormSchema, - metaFormFieldSchema, - WebMetaForm, -} from 'tailchat-design'; +import { WebMetaForm } from 'tailchat-design'; import { buildDataFromValues, pickValuesFromGroupPanelInfo } from './helper'; import type { GroupPanelValues } from './types'; import { useGroupPanelFields } from './useGroupPanelFields'; -import _omit from 'lodash/omit'; - -const schema = createMetaFormSchema({ - name: metaFormFieldSchema - .string() - .required(t('面板名不能为空')) - .max(20, t('面板名过长')), - type: metaFormFieldSchema.string().required(t('面板类型不能为空')), -}); /** * 修改群组面板 @@ -50,7 +37,7 @@ export const ModalModifyGroupPanel: React.FC<{ [props.groupId, props.groupPanelId, props.onSuccess] ); - const fields = useGroupPanelFields(props.groupId, currentValues); + const { fields, schema } = useGroupPanelFields(props.groupId, currentValues); if (!groupPanelInfo) { return ; diff --git a/client/web/src/components/modals/GroupPanel/useGroupPanelFields.tsx b/client/web/src/components/modals/GroupPanel/useGroupPanelFields.tsx index 03e60dbe..882f504c 100644 --- a/client/web/src/components/modals/GroupPanel/useGroupPanelFields.tsx +++ b/client/web/src/components/modals/GroupPanel/useGroupPanelFields.tsx @@ -7,9 +7,16 @@ import { t, useGroupMemberIds, } from 'tailchat-shared'; -import { MetaFormFieldMeta, useMetaFormContext } from 'tailchat-design'; +import { + createMetaFormSchema, + MetaFormFieldMeta, + metaFormFieldSchema, + useMetaFormContext, +} from 'tailchat-design'; import type { GroupPanelValues } from './types'; import _compact from 'lodash/compact'; +import _groupBy from 'lodash/groupBy'; +import _mapValues from 'lodash/mapValues'; import { pluginGroupPanel } from '@/plugin/common'; import { findPluginPanelInfoByName } from '@/utils/plugin-helper'; @@ -36,6 +43,14 @@ const baseFields: MetaFormFieldMeta[] = [ }, ]; +const baseSchema = { + name: metaFormFieldSchema + .string() + .required(t('面板名不能为空')) + .max(20, t('面板名过长')), + type: metaFormFieldSchema.string().required(t('面板类型不能为空')), +}; + export function useGroupPanelFields( groupId: string, currentValues: Partial @@ -63,36 +78,59 @@ export function useGroupPanelFields( return DisableSendMessageWithoutComponent; }, [groupId]); - const fields = useMemo(() => { + const ret = useMemo(() => { // NOTICE: 仅开发环境有这个配置 if (isDevelopment && currentValues.type === GroupPanelType.TEXT) { - return _compact([ - ...baseFields, - { - type: 'checkbox', - name: 'disableSendMessage', - label: t('禁止所有人发言'), - }, - currentValues.disableSendMessage === true && { - type: 'custom', - name: 'disableSendMessageWithout', - label: t('仅允许指定用户发言'), - render: disableSendMessageWithoutRender, - }, - ]) as MetaFormFieldMeta[]; + return { + fields: _compact([ + ...baseFields, + { + type: 'checkbox', + name: 'disableSendMessage', + label: t('禁止所有人发言'), + }, + currentValues.disableSendMessage === true && { + type: 'custom', + name: 'disableSendMessageWithout', + label: t('仅允许指定用户发言'), + render: disableSendMessageWithoutRender, + }, + ]) as MetaFormFieldMeta[], + schema: createMetaFormSchema({ + ...baseSchema, + disableSendMessage: metaFormFieldSchema.mixed(), + disableSendMessageWithout: metaFormFieldSchema.mixed(), + }), + }; } + let fields = baseFields; + let schema = baseSchema; + if (typeof currentValues.type === 'string') { // 如果当前选择的面板类型为插件类型 // 需要从插件信息中获取额外的字段 const panelInfo = findPluginPanelInfoByName(currentValues.type); if (panelInfo) { - return [...baseFields, ...(panelInfo.extraFormMeta ?? [])]; + const extraFormMeta = Array.isArray(panelInfo.extraFormMeta) + ? panelInfo.extraFormMeta + : []; + fields = [...baseFields, ...extraFormMeta]; + + const extraSchema = _mapValues( + _groupBy(extraFormMeta, (f) => f.name), + () => metaFormFieldSchema.mixed() + ); + + schema = { + ...extraSchema, + ...baseSchema, + }; } } - return baseFields; + return { fields, schema: createMetaFormSchema(schema) }; }, [currentValues]); - return fields; + return ret; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 656295f5..9b17188a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -186,7 +186,7 @@ importers: lodash: ^4.17.21 react: 18.2.0 react-dom: 18.2.0 - react-fastify-form: 1.0.11 + react-fastify-form: 1.0.12 remirror: ^2.0.9 str2int: ^1.1.0 typescript: ^4.5.2 @@ -199,7 +199,7 @@ importers: antd: 4.22.8_biqbaboplfbrettd7655fr4n2y clsx: 1.2.1 lodash: 4.17.21 - react-fastify-form: 1.0.11_react@18.2.0 + react-fastify-form: 1.0.12_react@18.2.0 remirror: 2.0.9_@remirror+pm@2.0.0 str2int: 1.1.0 devDependencies: @@ -26165,6 +26165,17 @@ packages: yup: 0.32.11 dev: false + /react-fastify-form/1.0.12_react@18.2.0: + resolution: {integrity: sha512-ml0F2wXMm4pAYHBsWmMOsuJQD0vwlUzOrhP46g6oxKag9Nbq+74iCbchePBXZxAhRT4ZJgNj4iJUndYFdsX+xg==} + peerDependencies: + react: ^16.14.0 + dependencies: + formik: 2.2.9_react@18.2.0 + lodash: 4.17.21 + react: 18.2.0 + yup: 0.32.11 + dev: false + /react-focus-lock/2.9.1_w5j4k42lgipnm43s3brx6h3c34: resolution: {integrity: sha512-pSWOQrUmiKLkffPO6BpMXN7SNKXMsuOakl652IBuALAu1esk+IcpJyM+ALcYzPTTFz1rD0R54aB9A4HuP5t1Wg==} peerDependencies: