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:
		
							parent
							
								
									42152568ee
								
							
						
					
					
						commit
						2d2e949452
					
				@ -6,8 +6,39 @@ import { useCollectionManager } from '../collection-manager';
 | 
			
		||||
import { RecordProvider, useRecord } from '../record-provider';
 | 
			
		||||
import { SchemaComponentOptions } from '../schema-component';
 | 
			
		||||
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>({});
 | 
			
		||||
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 { 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 { getCollectionJoinField, getCollectionFields } = useCollectionManager();
 | 
			
		||||
  const record = useRecord();
 | 
			
		||||
@ -111,12 +143,12 @@ export const TableSelectorProvider = (props) => {
 | 
			
		||||
  const { treeTable } = fieldSchema?.['x-decorator-props'] || {};
 | 
			
		||||
  const collectionFieldSchema = recursiveParent(fieldSchema, 'CollectionField');
 | 
			
		||||
  const collectionField = getCollectionJoinField(collectionFieldSchema?.['x-collection-field']);
 | 
			
		||||
  const params = { ...props.params };
 | 
			
		||||
  const appends = useAssociationNames(props.collection);
 | 
			
		||||
  let params = { ...props.params };
 | 
			
		||||
  if (props.dragSort) {
 | 
			
		||||
    params['sort'] = ['sort'];
 | 
			
		||||
  }
 | 
			
		||||
  if (collection.tree && treeTable !== false) {
 | 
			
		||||
  if (collection?.tree && treeTable !== false) {
 | 
			
		||||
    params['tree'] = true;
 | 
			
		||||
    if (collectionFieldSchema.name === 'parent') {
 | 
			
		||||
      params.filter = {
 | 
			
		||||
@ -195,6 +227,14 @@ export const TableSelectorProvider = (props) => {
 | 
			
		||||
      params['filter'] = extraFilter;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    params.filter = mergeFilter([parentParams.filter, params.filter]);
 | 
			
		||||
    params = { ...parentParams, ...params };
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    console.error(err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaComponentOptions scope={{ treeTable }}>
 | 
			
		||||
      <BlockProvider {...props} params={params}>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,10 @@ import { RecursionField, useField, useFieldSchema } from '@formily/react';
 | 
			
		||||
import { Select } from 'antd';
 | 
			
		||||
import { differenceBy, unionBy } from 'lodash';
 | 
			
		||||
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 { FormProvider, SchemaComponentOptions } from '../../core';
 | 
			
		||||
import { useCompile } from '../../hooks';
 | 
			
		||||
@ -47,7 +50,6 @@ const useTableSelectorProps = () => {
 | 
			
		||||
        .filter((item) => options.every((row) => row[rowKey] !== item[rowKey]))
 | 
			
		||||
        .map((item) => item[rowKey]),
 | 
			
		||||
    },
 | 
			
		||||
    dataSource: field.value?.filter((item) => options.every((row) => row[rowKey] !== item[rowKey])),
 | 
			
		||||
    onRowSelectionChange(selectedRowKeys, selectedRows) {
 | 
			
		||||
      if (multiple) {
 | 
			
		||||
        const scopeRows = flatData(field.value) || [];
 | 
			
		||||
@ -69,11 +71,11 @@ const useTableSelectorProps = () => {
 | 
			
		||||
 | 
			
		||||
const usePickActionProps = () => {
 | 
			
		||||
  const { setVisible } = useActionContext();
 | 
			
		||||
  const { multiple, selectedRows, onChange, options } = useContext(RecordPickerContext);
 | 
			
		||||
  const { multiple, selectedRows, onChange, options, collectionField } = useContext(RecordPickerContext);
 | 
			
		||||
  return {
 | 
			
		||||
    onClick() {
 | 
			
		||||
      if (multiple) {
 | 
			
		||||
        onChange([...options, ...selectedRows]);
 | 
			
		||||
        onChange(unionBy(selectedRows, options, collectionField?.targetKey || 'id'));
 | 
			
		||||
      } else {
 | 
			
		||||
        onChange(selectedRows?.[0] || null);
 | 
			
		||||
      }
 | 
			
		||||
@ -182,10 +184,10 @@ export const InputRecordPicker: React.FC<any> = (props: IRecordPickerProps) => {
 | 
			
		||||
          allowClear
 | 
			
		||||
          onChange={(changed: any) => {
 | 
			
		||||
            if (!changed) {
 | 
			
		||||
              onChange(null);
 | 
			
		||||
              onChange([]);
 | 
			
		||||
              setSelectedRows([]);
 | 
			
		||||
            } else if (!changed?.length) {
 | 
			
		||||
              onChange(null);
 | 
			
		||||
              onChange([]);
 | 
			
		||||
              setSelectedRows([]);
 | 
			
		||||
            } else if (Array.isArray(changed)) {
 | 
			
		||||
              const values = options?.filter((option) => changed.includes(option[fieldNames.value]));
 | 
			
		||||
@ -234,20 +236,32 @@ const Drawer: React.FunctionComponent<{
 | 
			
		||||
  fieldSchema,
 | 
			
		||||
  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 (
 | 
			
		||||
    <RecordPickerContext.Provider value={{ multiple, onChange, selectedRows, setSelectedRows, options }}>
 | 
			
		||||
    <RecordPickerContext.Provider
 | 
			
		||||
      value={{ multiple, onChange, selectedRows, setSelectedRows, options, collectionField }}
 | 
			
		||||
    >
 | 
			
		||||
      <CollectionProvider allowNull name={collectionField?.target}>
 | 
			
		||||
        <ActionContext.Provider value={{ openMode: 'drawer', visible, setVisible }}>
 | 
			
		||||
          <FormProvider>
 | 
			
		||||
            <SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}>
 | 
			
		||||
              <RecursionField
 | 
			
		||||
                schema={fieldSchema}
 | 
			
		||||
                onlyRenderProperties
 | 
			
		||||
                filterProperties={(s) => {
 | 
			
		||||
                  return s['x-component'] === 'RecordPicker.Selector';
 | 
			
		||||
                }}
 | 
			
		||||
              />
 | 
			
		||||
            </SchemaComponentOptions>
 | 
			
		||||
            <TableSelectorParamsProvider params={{ filter: getFilter() }}>
 | 
			
		||||
              <SchemaComponentOptions scope={{ useTableSelectorProps, usePickActionProps }}>
 | 
			
		||||
                <RecursionField
 | 
			
		||||
                  schema={fieldSchema}
 | 
			
		||||
                  onlyRenderProperties
 | 
			
		||||
                  filterProperties={(s) => {
 | 
			
		||||
                    return s['x-component'] === 'RecordPicker.Selector';
 | 
			
		||||
                  }}
 | 
			
		||||
                />
 | 
			
		||||
              </SchemaComponentOptions>
 | 
			
		||||
            </TableSelectorParamsProvider>
 | 
			
		||||
          </FormProvider>
 | 
			
		||||
        </ActionContext.Provider>
 | 
			
		||||
      </CollectionProvider>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user