fix: failed to correctly respond to optional fields in the child collection in the parent collection table (#2207)

* refactor: process inherited field uischema in table

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve
This commit is contained in:
katherinehhh 2023-07-11 17:43:25 +08:00 committed by GitHub
parent ff7b1aaf71
commit c20c68cc42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 59 deletions

View File

@ -1,10 +1,8 @@
import { ArrayField, createForm } from '@formily/core'; import { ArrayField, createForm } from '@formily/core';
import { FormContext, useField, useFieldSchema } from '@formily/react'; import { FormContext, useField, useFieldSchema } from '@formily/react';
import { boolean } from 'mathjs';
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { useCollectionManager } from '../collection-manager'; import { useCollectionManager } from '../collection-manager';
import { useFilterBlock } from '../filter-provider/FilterProvider'; import { useFilterBlock } from '../filter-provider/FilterProvider';
import { useRecord } from '../record-provider';
import { FixedBlockWrapper, removeNullCondition, SchemaComponentOptions } from '../schema-component'; import { FixedBlockWrapper, removeNullCondition, SchemaComponentOptions } from '../schema-component';
import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider'; import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider';
import { findFilterTargets } from './hooks'; import { findFilterTargets } from './hooks';
@ -68,60 +66,9 @@ const InternalTableBlockProvider = (props: Props) => {
); );
}; };
// export const useAssociationNames = (collection) => {
// const { getCollectionFields } = useCollectionManager();
// const collectionFields = getCollectionFields(collection);
// const associationFields = new Set();
// for (const collectionField of collectionFields) {
// if (collectionField.target) {
// associationFields.add(collectionField.name);
// const fields = getCollectionFields(collectionField.target);
// for (const field of fields) {
// if (field.target) {
// associationFields.add(`${collectionField.name}.${field.name}`);
// }
// }
// }
// }
// const fieldSchema = useFieldSchema();
// const tableSchema = fieldSchema.reduceProperties((buf, schema) => {
// if (schema['x-component'] === 'TableV2') {
// return schema;
// }
// if (schema['x-component'] === 'Gantt') {
// return schema.properties?.table;
// }
// return buf;
// }, new Schema({}));
// return uniq(
// tableSchema.reduceProperties((buf, schema) => {
// if (schema['x-component'] === 'TableV2.Column') {
// const s = schema.reduceProperties((buf, s) => {
// const [name] = (s.name as string).split('.');
// if (s['x-collection-field'] && associationFields.has(name)) {
// return s;
// }
// return buf;
// }, null);
// if (s) {
// // 关联字段和关联的关联字段
// const [firstName] = s.name.split('.');
// if (associationFields.has(s.name)) {
// buf.push(s.name);
// } else if (associationFields.has(firstName)) {
// buf.push(firstName);
// }
// }
// }
// return buf;
// }, []),
// );
// };
export const TableBlockProvider = (props) => { export const TableBlockProvider = (props) => {
const resourceName = props.resource; const resourceName = props.resource;
const params = { ...props.params }; const params = { ...props.params };
const record = useRecord();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { getCollection, getCollectionField } = useCollectionManager(); const { getCollection, getCollectionField } = useCollectionManager();
const collection = getCollection(props.collection); const collection = getCollection(props.collection);
@ -170,6 +117,7 @@ export const useTableBlockProps = () => {
useEffect(() => { useEffect(() => {
if (!ctx?.service?.loading) { if (!ctx?.service?.loading) {
field.value=[];
field.value = ctx?.service?.data?.data; field.value = ctx?.service?.data?.data;
field.data = field.data || {}; field.data = field.data || {};
field.data.selectedRowKeys = ctx?.field?.data?.selectedRowKeys; field.data.selectedRowKeys = ctx?.field?.data?.selectedRowKeys;

View File

@ -13,9 +13,13 @@ export const CollectionFieldProvider: React.FC<{
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { getField } = useCollection(); const { getField } = useCollection();
const { getCollectionJoinField } = useCollectionManager(); const { getCollectionJoinField } = useCollectionManager();
const value = field || getField(field?.name || name) || getCollectionJoinField(fieldSchema?.['x-collection-field']); const value = getCollectionJoinField(fieldSchema?.['x-collection-field']) || field || getField(field?.name || name);
if (!value) { if (!value) {
return fallback; return fallback;
} }
return <CollectionFieldContext.Provider value={value}>{children}</CollectionFieldContext.Provider>; return (
<CollectionFieldContext.Provider value={{ ...value, uiSchema: value.uiSchema }}>
{children}
</CollectionFieldContext.Provider>
);
}; };

View File

@ -19,6 +19,7 @@ import {
useTableSelectorContext, useTableSelectorContext,
} from '../../../'; } from '../../../';
import { useACLFieldWhitelist } from '../../../acl/ACLProvider'; import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils'; import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
const useArrayField = (props) => { const useArrayField = (props) => {
@ -58,11 +59,16 @@ const useTableColumns = (props) => {
return ( return (
<RecordIndexProvider index={record.__index || index}> <RecordIndexProvider index={record.__index || index}>
<RecordProvider record={record}> <RecordProvider record={record}>
<RecursionField <ColumnFieldProvider
basePath={field.address.concat(record.__index || index)}
schema={s} schema={s}
onlyRenderProperties basePath={field.address.concat(record.__index || index)}
/> >
<RecursionField
basePath={field.address.concat(record.__index || index)}
schema={s}
onlyRenderProperties
/>
</ColumnFieldProvider>
</RecordProvider> </RecordProvider>
</RecordIndexProvider> </RecordIndexProvider>
); );

View File

@ -0,0 +1,33 @@
import { observer, RecursionField } from '@formily/react';
import React from 'react';
import { useRecord } from '../../../../record-provider';
export const ColumnFieldProvider = observer(
(props: { schema: any; basePath: any; children: any }) => {
const { schema, basePath } = props;
const record = useRecord();
const fieldSchema = schema.reduceProperties((buf, s) => {
if (s['x-component'] === 'CollectionField') {
return s;
}
return buf;
}, null);
if (fieldSchema && record?.__collection) {
const fieldName = `${record.__collection}.${fieldSchema.name}`;
const newSchema = {
...schema.toJSON(),
properties: {
[fieldSchema.name]: {
...fieldSchema.toJSON(),
'x-collection-field': fieldName,
'x-component-props': {
...fieldSchema['x-component-props'],
},
},
},
};
return <RecursionField basePath={basePath} schema={newSchema} onlyRenderProperties />;
}
return props.children;
},
{ displayName: 'ColumnFieldProvider' },
);