fix: improve filter (#1333)
Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
		
							parent
							
								
									85a032f87c
								
							
						
					
					
						commit
						550db03615
					
				@ -17,6 +17,17 @@ export type SharedFilterContextValue = {
 | 
				
			|||||||
  getFilterParams: (filterStore?: SharedFilterStore) => any;
 | 
					  getFilterParams: (filterStore?: SharedFilterStore) => any;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const mergeFilter = (filters: any[], op = '$and') => {
 | 
				
			||||||
 | 
					  const items = filters.filter(Boolean);
 | 
				
			||||||
 | 
					  if (items.length === 0) {
 | 
				
			||||||
 | 
					    return {};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (items.length === 1) {
 | 
				
			||||||
 | 
					    return items[0];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return { [op]: items };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getFilterParams = (filterStore?: SharedFilterStore) => {
 | 
					export const getFilterParams = (filterStore?: SharedFilterStore) => {
 | 
				
			||||||
  const newAssociationFilterList = Object.entries(filterStore).map(([key, filter]) => filter);
 | 
					  const newAssociationFilterList = Object.entries(filterStore).map(([key, filter]) => filter);
 | 
				
			||||||
  const newAssociationFilter = newAssociationFilterList.length
 | 
					  const newAssociationFilter = newAssociationFilterList.length
 | 
				
			||||||
@ -35,8 +46,8 @@ export const SharedFilterContext = createContext<SharedFilterContextValue>({
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const concatFilter = (f1: SharedFilter, f2: SharedFilter): SharedFilter => {
 | 
					export const concatFilter = (f1: SharedFilter, f2: SharedFilter): SharedFilter => {
 | 
				
			||||||
  const newAnd = [f1.$and, f2.$and].filter((i) => i).reduce((pre, cur) => pre.concat(cur), []);
 | 
					  const newAnd = [f1?.$and, f2?.$and].filter((i) => i).reduce((pre, cur) => pre.concat(cur), []);
 | 
				
			||||||
  const newOr = [f1.$or, f2.$or].filter((i) => i).reduce((pre, cur) => pre.concat(cur), []);
 | 
					  const newOr = [f1?.$or, f2?.$or].filter((i) => i).reduce((pre, cur) => pre.concat(cur), []);
 | 
				
			||||||
  const newFilter: SharedFilter = {};
 | 
					  const newFilter: SharedFilter = {};
 | 
				
			||||||
  newAnd.length && (newFilter.$and = newAnd);
 | 
					  newAnd.length && (newFilter.$and = newAnd);
 | 
				
			||||||
  newOr.length && (newFilter.$or = newOr);
 | 
					  newOr.length && (newFilter.$or = newOr);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,10 @@ import { css } from '@emotion/css';
 | 
				
			|||||||
import { useFieldSchema } from '@formily/react';
 | 
					import { useFieldSchema } from '@formily/react';
 | 
				
			||||||
import { Col, Collapse, Input, Row, Tree } from 'antd';
 | 
					import { Col, Collapse, Input, Row, Tree } from 'antd';
 | 
				
			||||||
import cls from 'classnames';
 | 
					import cls from 'classnames';
 | 
				
			||||||
import React, { ChangeEvent, MouseEvent, useContext, useState } from 'react';
 | 
					import React, { ChangeEvent, MouseEvent, useState } from 'react';
 | 
				
			||||||
import { useRequest } from '../../../api-client';
 | 
					import { useRequest } from '../../../api-client';
 | 
				
			||||||
import { useBlockRequestContext } from '../../../block-provider';
 | 
					import { useBlockRequestContext } from '../../../block-provider';
 | 
				
			||||||
import { SharedFilterContext } from '../../../block-provider/SharedFilterProvider';
 | 
					import { mergeFilter } from '../../../block-provider/SharedFilterProvider';
 | 
				
			||||||
import { SortableItem } from '../../common';
 | 
					import { SortableItem } from '../../common';
 | 
				
			||||||
import { useCompile, useDesigner } from '../../hooks';
 | 
					import { useCompile, useDesigner } from '../../hooks';
 | 
				
			||||||
import { AssociationFilter } from './AssociationFilter';
 | 
					import { AssociationFilter } from './AssociationFilter';
 | 
				
			||||||
@ -24,7 +24,6 @@ export const AssociationFilterItem = (props) => {
 | 
				
			|||||||
  const Designer = useDesigner();
 | 
					  const Designer = useDesigner();
 | 
				
			||||||
  const compile = useCompile();
 | 
					  const compile = useCompile();
 | 
				
			||||||
  const { service } = useBlockRequestContext();
 | 
					  const { service } = useBlockRequestContext();
 | 
				
			||||||
  const { setSharedFilterStore, sharedFilterStore, getFilterParams } = useContext(SharedFilterContext);
 | 
					 | 
				
			||||||
  const [searchVisible, setSearchVisible] = useState(false);
 | 
					  const [searchVisible, setSearchVisible] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const collectionFieldName = collectionField.name;
 | 
					  const collectionFieldName = collectionField.name;
 | 
				
			||||||
@ -67,31 +66,17 @@ export const AssociationFilterItem = (props) => {
 | 
				
			|||||||
  const onSelect = (selectedKeysValue: React.Key[]) => {
 | 
					  const onSelect = (selectedKeysValue: React.Key[]) => {
 | 
				
			||||||
    setSelectedKeys(selectedKeysValue);
 | 
					    setSelectedKeys(selectedKeysValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const orList = selectedKeysValue.map((item) => ({
 | 
					    const filters = service.params?.[1]?.filters || {};
 | 
				
			||||||
      [collectionFieldName]: {
 | 
					 | 
				
			||||||
        [valueKey]: {
 | 
					 | 
				
			||||||
          $eq: item,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const newFilter =
 | 
					    if (selectedKeysValue.length) {
 | 
				
			||||||
      orList.length > 0
 | 
					      filters[`af.${collectionFieldName}`] = {
 | 
				
			||||||
        ? {
 | 
					        [`${collectionFieldName}.${valueKey}.$in`]: selectedKeysValue,
 | 
				
			||||||
            $or: orList,
 | 
					      };
 | 
				
			||||||
          }
 | 
					    } else {
 | 
				
			||||||
        : {};
 | 
					      delete filters[`af.${collectionFieldName}`];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const newAssociationFilterStore = {
 | 
					    service.run({ ...service.params?.[0], pageSize: 200, page: 1, filter: mergeFilter(Object.values(filters)) }, { filters });
 | 
				
			||||||
      ...sharedFilterStore,
 | 
					 | 
				
			||||||
      [collectionFieldName]: newFilter,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setSharedFilterStore(newAssociationFilterStore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const paramFilter = getFilterParams(newAssociationFilterStore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    service.run({ ...service.params?.[0], pageSize: 200, page: 1, filter: paramFilter });
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleSearchToggle = (e: MouseEvent) => {
 | 
					  const handleSearchToggle = (e: MouseEvent) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,9 @@
 | 
				
			|||||||
import { Field } from '@formily/core';
 | 
					import { Field } from '@formily/core';
 | 
				
			||||||
import { useField, useFieldSchema } from '@formily/react';
 | 
					import { useField, useFieldSchema } from '@formily/react';
 | 
				
			||||||
import flat from 'flat';
 | 
					import flat from 'flat';
 | 
				
			||||||
import { useContext } from 'react';
 | 
					 | 
				
			||||||
import { useTranslation } from 'react-i18next';
 | 
					import { useTranslation } from 'react-i18next';
 | 
				
			||||||
import { useBlockRequestContext } from '../../../block-provider';
 | 
					import { useBlockRequestContext } from '../../../block-provider';
 | 
				
			||||||
import { concatFilter, SharedFilterContext } from '../../../block-provider/SharedFilterProvider';
 | 
					import { mergeFilter } from '../../../block-provider/SharedFilterProvider';
 | 
				
			||||||
import { useCollection, useCollectionManager } from '../../../collection-manager';
 | 
					import { useCollection, useCollectionManager } from '../../../collection-manager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useFilterOptions = (collectionName: string) => {
 | 
					export const useFilterOptions = (collectionName: string) => {
 | 
				
			||||||
@ -99,7 +98,6 @@ export const useFilterActionProps = () => {
 | 
				
			|||||||
export const useFilterFieldProps = ({ options, service, params }) => {
 | 
					export const useFilterFieldProps = ({ options, service, params }) => {
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  const field = useField<Field>();
 | 
				
			||||||
  const { sharedFilterStore, setSharedFilterStore, getFilterParams } = useContext(SharedFilterContext);
 | 
					 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    options,
 | 
					    options,
 | 
				
			||||||
    onSubmit(values) {
 | 
					    onSubmit(values) {
 | 
				
			||||||
@ -108,16 +106,10 @@ export const useFilterFieldProps = ({ options, service, params }) => {
 | 
				
			|||||||
      // filter parameter for the filter action
 | 
					      // filter parameter for the filter action
 | 
				
			||||||
      const filter = removeNullCondition(values?.filter);
 | 
					      const filter = removeNullCondition(values?.filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const newSharedFilterStore = {
 | 
					      const filters = service.params?.[1]?.filters || {};
 | 
				
			||||||
        ...sharedFilterStore,
 | 
					      filters[`default`] = mergeFilter([defaultFilter, filter]);
 | 
				
			||||||
        ActionBar: concatFilter(defaultFilter, filter),
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      setSharedFilterStore(newSharedFilterStore);
 | 
					      service.run({ ...service.params?.[0], page: 1, filter: mergeFilter(Object.values(filters)) }, { filters });
 | 
				
			||||||
 | 
					 | 
				
			||||||
      const paramFilter = getFilterParams(newSharedFilterStore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      service.run({ ...service.params?.[0], page: 1, filter: paramFilter });
 | 
					 | 
				
			||||||
      const items = filter?.$and || filter?.$or;
 | 
					      const items = filter?.$and || filter?.$or;
 | 
				
			||||||
      if (items?.length) {
 | 
					      if (items?.length) {
 | 
				
			||||||
        field.title = t('{{count}} filter items', { count: items?.length || 0 });
 | 
					        field.title = t('{{count}} filter items', { count: items?.length || 0 });
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user