refactor: view synchronization field, source field support selected to inherited collection field (#2456)

* refactor: syncField action support inherited fields

* refactor: code improve

* style: style improve
This commit is contained in:
katherinehhh 2023-08-16 18:08:33 +08:00 committed by GitHub
parent 5581b4f872
commit 39dcb905f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 19 deletions

View File

@ -166,7 +166,7 @@ export const SyncFieldsActionCom = (props) => {
return ( return (
record.template === 'view' && ( record.template === 'view' && (
<RecordProvider record={record}> <RecordProvider record={record}>
<ActionContextProvider value={{ visible, setVisible }}> <ActionContextProvider value={{ visible, setVisible, drawerProps: { width: 900 } }}>
{children || ( {children || (
<Button <Button
icon={<PlusOutlined />} icon={<PlusOutlined />}

View File

@ -1,6 +1,8 @@
import { Cascader } from '@formily/antd-v5'; import { Cascader } from '@formily/antd-v5';
import { useField, useForm } from '@formily/react'; import { useField, useForm } from '@formily/react';
import { Input, Select, Spin, Table, Tag } from 'antd'; import { Input, Select, Spin, Table, Tag } from 'antd';
import { last } from 'lodash';
import { boolean } from 'mathjs';
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ResourceActionContext, useCompile } from '../../../'; import { ResourceActionContext, useCompile } from '../../../';
@ -30,19 +32,40 @@ const PreviewCom = (props) => {
const [sourceFields, setSourceFields] = useState([]); const [sourceFields, setSourceFields] = useState([]);
const field: any = useField(); const field: any = useField();
const form = useForm(); const form = useForm();
const { getCollection, getInterface } = useCollectionManager(); const { getCollection, getInterface, getCollectionFields, getInheritCollections, getParentCollectionFields } =
useCollectionManager();
const compile = useCompile(); const compile = useCompile();
const initOptions = getOptions().filter((v) => !['relation', 'systemInfo'].includes(v.key)); const initOptions = getOptions().filter((v) => !['relation', 'systemInfo'].includes(v.key));
useEffect(() => { useEffect(() => {
const data = []; const data = [];
sources.forEach((item) => { sources.forEach((item) => {
const collection = getCollection(item); const collection = getCollection(item);
const children = collection.fields?.map((v) => { const inherits = getInheritCollections(item);
return { value: v.name, label: v.uiSchema?.title }; const result = inherits.map((v) => {
const fields = getParentCollectionFields(v, item);
return {
type: 'group',
key: v,
label: t(`Parent collection fields`) + t(`(${getCollection(v).title})`),
children: fields
.filter((v) => !['hasOne', 'hasMany', 'belongsToMany'].includes(v?.type))
.map((k) => {
return {
value: k.name,
label: t(k.uiSchema?.title),
};
}),
};
}); });
const children = collection.fields
.filter((v) => !['hasOne', 'hasMany', 'belongsToMany'].includes(v?.type))
?.map((v) => {
return { value: v.name, label: t(v.uiSchema?.title) };
})
.concat(result);
data.push({ data.push({
value: item, value: item,
label: collection.title, label: t(collection.title),
children, children,
}); });
}); });
@ -70,7 +93,7 @@ const PreviewCom = (props) => {
setDataSource(fieldsData); setDataSource(fieldsData);
form.setValuesIn('sources', data.data?.sources); form.setValuesIn('sources', data.data?.sources);
} }
}); }).catch;
} }
}, [databaseView]); }, [databaseView]);
@ -78,9 +101,10 @@ const PreviewCom = (props) => {
dataSource.splice(index, 1, record); dataSource.splice(index, 1, record);
setDataSource(dataSource); setDataSource(dataSource);
field.value = dataSource.map((v) => { field.value = dataSource.map((v) => {
const source = typeof v.source === 'string' ? v.source : v.source?.filter?.(Boolean)?.join('.');
return { return {
...v, ...v,
source: typeof v.source === 'string' ? v.source : v.source?.join('.'), source,
}; };
}); });
}; };
@ -104,7 +128,8 @@ const PreviewCom = (props) => {
style={{ width: '100%' }} style={{ width: '100%' }}
options={compile(sourceFields)} options={compile(sourceFields)}
onChange={(value, selectedOptions) => { onChange={(value, selectedOptions) => {
handleFieldChange({ ...record, source: value }, index); const sourceField = getCollectionFields(value?.[0])?.find((v) => v.name === last(value));
handleFieldChange({ ...record, source: value, uiSchema: sourceField?.uiSchema }, index);
}} }}
placeholder={t('Select field source')} placeholder={t('Select field source')}
/> />
@ -177,7 +202,7 @@ const PreviewCom = (props) => {
const item = dataSource[index]; const item = dataSource[index];
return ( return (
<Input <Input
defaultValue={record?.uiSchema?.title || text} value={item?.uiSchema?.title || text}
onChange={(e) => onChange={(e) =>
handleFieldChange({ ...item, uiSchema: { ...item?.uiSchema, title: e.target.value } }, index) handleFieldChange({ ...item, uiSchema: { ...item?.uiSchema, title: e.target.value } }, index)
} }
@ -190,7 +215,7 @@ const PreviewCom = (props) => {
<Spin spinning={loading}> <Spin spinning={loading}>
{dataSource.length > 0 && ( {dataSource.length > 0 && (
<> <>
<div className="ant-formily-item-label"> <div className="ant-formily-item-label" style={{ display: 'flex', padding: '0 0 8px' }}>
<div className="ant-formily-item-label-content"> <div className="ant-formily-item-label-content">
<span> <span>
<label>{t('Fields')}</label> <label>{t('Fields')}</label>

View File

@ -12,7 +12,7 @@ export const PreviewTable = (props) => {
const [previewData, setPreviewData] = useState([]); const [previewData, setPreviewData] = useState([]);
const compile = useCompile(); const compile = useCompile();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { getCollection, getCollectionField, getInterface } = useCollectionManager(); const { getInterface, getCollectionFields } = useCollectionManager();
const api = useAPIClient(); const api = useAPIClient();
const { t } = useTranslation(); const { t } = useTranslation();
const form = useForm(); const form = useForm();
@ -37,7 +37,7 @@ export const PreviewTable = (props) => {
setLoading(false); setLoading(false);
setPreviewData(data?.data || []); setPreviewData(data?.data || []);
} }
}); }).catch;
}; };
const formatPreviewColumns = (data) => { const formatPreviewColumns = (data) => {
@ -45,12 +45,9 @@ export const PreviewTable = (props) => {
.filter((k) => k.source || k.interface) .filter((k) => k.source || k.interface)
?.map((item) => { ?.map((item) => {
const fieldSource = typeof item?.source === 'string' ? item?.source?.split('.') : item?.source; const fieldSource = typeof item?.source === 'string' ? item?.source?.split('.') : item?.source;
const sourceField = getCollection(fieldSource?.[0])?.fields.find((v) => v.name === fieldSource?.[1])?.uiSchema const sourceField = getCollectionFields(fieldSource?.[0])?.find((v) => v.name === fieldSource?.[1])?.uiSchema;
?.title; const target = item?.uiSchema?.title || sourceField?.title || item.name;
const target = item?.uiSchema?.title || sourceField || item.name; const schema: any = item.source ? sourceField : getInterface(item.interface)?.default?.uiSchema;
const schema: any = item.source
? getCollectionField(typeof item.source === 'string' ? item.source : item.source.join('.'))?.uiSchema
: getInterface(item.interface)?.default?.uiSchema;
return { return {
title: compile(target), title: compile(target),
dataIndex: item.name, dataIndex: item.name,
@ -81,7 +78,11 @@ export const PreviewTable = (props) => {
}} }}
> >
{previewColumns?.length > 0 && [ {previewColumns?.length > 0 && [
<div className="ant-formily-item-label" style={{ marginTop: 24 }}> <div
className="ant-formily-item-label"
style={{ marginTop: 24, display: 'flex', padding: '0 0 8px' }}
key={viewName}
>
<div className="ant-formily-item-label-content"> <div className="ant-formily-item-label-content">
<span> <span>
<label>{t('Preview')}</label> <label>{t('Preview')}</label>