fix(record-picker): fix the table paging problem (#1718)

* fix(record-picker): fix the table paging problem

* fix(recorder-picker): de-duplication
This commit is contained in:
被雨水过滤的空气-Rairn 2023-04-18 10:23:27 +08:00 committed by GitHub
parent 42152568ee
commit 2d2e949452
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 19 deletions

View File

@ -6,8 +6,39 @@ import { useCollectionManager } from '../collection-manager';
import { RecordProvider, useRecord } from '../record-provider'; import { RecordProvider, useRecord } from '../record-provider';
import { SchemaComponentOptions } from '../schema-component'; import { SchemaComponentOptions } from '../schema-component';
import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider'; import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestContext } from './BlockProvider';
import { mergeFilter } from './SharedFilterProvider';
type Params = {
filter?: any;
pageSize?: number;
page?: number;
sort?: any;
};
export const TableSelectorContext = createContext<any>({}); export const TableSelectorContext = createContext<any>({});
const TableSelectorParamsContext = createContext<Params>({}); // 用于传递参数
type TableSelectorProviderProps = {
params: Record<string, any>;
collection?: string;
dragSort?: boolean;
children?: any;
};
const useTableSelectorParams = () => {
return useContext(TableSelectorParamsContext);
};
export const TableSelectorParamsProvider = ({ params, children }: { params: Params; children: any }) => {
const parentParams = useTableSelectorParams();
try {
params.filter = mergeFilter([parentParams.filter, params.filter]);
params = { ...parentParams, ...params };
} catch (err) {
console.error(err);
}
return <TableSelectorParamsContext.Provider value={params}>{children}</TableSelectorParamsContext.Provider>;
};
const InternalTableSelectorProvider = (props) => { const InternalTableSelectorProvider = (props) => {
const { params, rowKey, extraFilter } = props; const { params, rowKey, extraFilter } = props;
@ -102,7 +133,8 @@ const useAssociationNames = (collection) => {
); );
}; };
export const TableSelectorProvider = (props) => { export const TableSelectorProvider = (props: TableSelectorProviderProps) => {
const parentParams = useTableSelectorParams();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { getCollectionJoinField, getCollectionFields } = useCollectionManager(); const { getCollectionJoinField, getCollectionFields } = useCollectionManager();
const record = useRecord(); const record = useRecord();
@ -111,12 +143,12 @@ export const TableSelectorProvider = (props) => {
const { treeTable } = fieldSchema?.['x-decorator-props'] || {}; const { treeTable } = fieldSchema?.['x-decorator-props'] || {};
const collectionFieldSchema = recursiveParent(fieldSchema, 'CollectionField'); const collectionFieldSchema = recursiveParent(fieldSchema, 'CollectionField');
const collectionField = getCollectionJoinField(collectionFieldSchema?.['x-collection-field']); const collectionField = getCollectionJoinField(collectionFieldSchema?.['x-collection-field']);
const params = { ...props.params };
const appends = useAssociationNames(props.collection); const appends = useAssociationNames(props.collection);
let params = { ...props.params };
if (props.dragSort) { if (props.dragSort) {
params['sort'] = ['sort']; params['sort'] = ['sort'];
} }
if (collection.tree && treeTable !== false) { if (collection?.tree && treeTable !== false) {
params['tree'] = true; params['tree'] = true;
if (collectionFieldSchema.name === 'parent') { if (collectionFieldSchema.name === 'parent') {
params.filter = { params.filter = {
@ -195,6 +227,14 @@ export const TableSelectorProvider = (props) => {
params['filter'] = extraFilter; params['filter'] = extraFilter;
} }
} }
try {
params.filter = mergeFilter([parentParams.filter, params.filter]);
params = { ...parentParams, ...params };
} catch (err) {
console.error(err);
}
return ( return (
<SchemaComponentOptions scope={{ treeTable }}> <SchemaComponentOptions scope={{ treeTable }}>
<BlockProvider {...props} params={params}> <BlockProvider {...props} params={params}>

View File

@ -3,7 +3,10 @@ import { RecursionField, useField, useFieldSchema } from '@formily/react';
import { Select } from 'antd'; import { Select } from 'antd';
import { differenceBy, unionBy } from 'lodash'; import { differenceBy, unionBy } from 'lodash';
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
import { useTableSelectorProps as useTsp } from '../../../block-provider/TableSelectorProvider'; import {
TableSelectorParamsProvider,
useTableSelectorProps as useTsp,
} from '../../../block-provider/TableSelectorProvider';
import { CollectionProvider, useCollection } from '../../../collection-manager'; import { CollectionProvider, useCollection } from '../../../collection-manager';
import { FormProvider, SchemaComponentOptions } from '../../core'; import { FormProvider, SchemaComponentOptions } from '../../core';
import { useCompile } from '../../hooks'; import { useCompile } from '../../hooks';
@ -47,7 +50,6 @@ const useTableSelectorProps = () => {
.filter((item) => options.every((row) => row[rowKey] !== item[rowKey])) .filter((item) => options.every((row) => row[rowKey] !== item[rowKey]))
.map((item) => item[rowKey]), .map((item) => item[rowKey]),
}, },
dataSource: field.value?.filter((item) => options.every((row) => row[rowKey] !== item[rowKey])),
onRowSelectionChange(selectedRowKeys, selectedRows) { onRowSelectionChange(selectedRowKeys, selectedRows) {
if (multiple) { if (multiple) {
const scopeRows = flatData(field.value) || []; const scopeRows = flatData(field.value) || [];
@ -69,11 +71,11 @@ const useTableSelectorProps = () => {
const usePickActionProps = () => { const usePickActionProps = () => {
const { setVisible } = useActionContext(); const { setVisible } = useActionContext();
const { multiple, selectedRows, onChange, options } = useContext(RecordPickerContext); const { multiple, selectedRows, onChange, options, collectionField } = useContext(RecordPickerContext);
return { return {
onClick() { onClick() {
if (multiple) { if (multiple) {
onChange([...options, ...selectedRows]); onChange(unionBy(selectedRows, options, collectionField?.targetKey || 'id'));
} else { } else {
onChange(selectedRows?.[0] || null); onChange(selectedRows?.[0] || null);
} }
@ -182,10 +184,10 @@ export const InputRecordPicker: React.FC<any> = (props: IRecordPickerProps) => {
allowClear allowClear
onChange={(changed: any) => { onChange={(changed: any) => {
if (!changed) { if (!changed) {
onChange(null); onChange([]);
setSelectedRows([]); setSelectedRows([]);
} else if (!changed?.length) { } else if (!changed?.length) {
onChange(null); onChange([]);
setSelectedRows([]); setSelectedRows([]);
} else if (Array.isArray(changed)) { } else if (Array.isArray(changed)) {
const values = options?.filter((option) => changed.includes(option[fieldNames.value])); const values = options?.filter((option) => changed.includes(option[fieldNames.value]));
@ -234,20 +236,32 @@ const Drawer: React.FunctionComponent<{
fieldSchema, fieldSchema,
options, options,
}) => { }) => {
console.log('collectionField', options);
const getFilter = () => {
const targetKey = collectionField.targetKey || 'id';
const list = options.map((option) => option[targetKey]);
const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {};
return filter;
};
return ( return (
<RecordPickerContext.Provider value={{ multiple, onChange, selectedRows, setSelectedRows, options }}> <RecordPickerContext.Provider
value={{ multiple, onChange, selectedRows, setSelectedRows, options, collectionField }}
>
<CollectionProvider allowNull name={collectionField?.target}> <CollectionProvider allowNull name={collectionField?.target}>
<ActionContext.Provider value={{ openMode: 'drawer', visible, setVisible }}> <ActionContext.Provider value={{ openMode: 'drawer', visible, setVisible }}>
<FormProvider> <FormProvider>
<SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}> <TableSelectorParamsProvider params={{ filter: getFilter() }}>
<RecursionField <SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}>
schema={fieldSchema} <RecursionField
onlyRenderProperties schema={fieldSchema}
filterProperties={(s) => { onlyRenderProperties
return s['x-component'] === 'RecordPicker.Selector'; filterProperties={(s) => {
}} return s['x-component'] === 'RecordPicker.Selector';
/> }}
</SchemaComponentOptions> />
</SchemaComponentOptions>
</TableSelectorParamsProvider>
</FormProvider> </FormProvider>
</ActionContext.Provider> </ActionContext.Provider>
</CollectionProvider> </CollectionProvider>