Make filters work on export csv action (#8389)

- Create a new component state `contextStoreFiltersComponentState` and
refactor `contextStoreTargetedRecordsRuleComponentState`
- Refactor `computeContextStoreFilters` to use filters when no records
are selected
This commit is contained in:
Raphaël Bosi
2024-11-08 15:38:45 +01:00
committed by GitHub
parent d44f7a46b6
commit 5a53ef1ade
9 changed files with 78 additions and 28 deletions

View File

@@ -1,5 +1,6 @@
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries'; import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState'; import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
@@ -45,8 +46,13 @@ export const DeleteRecordsActionEffect = ({
contextStoreTargetedRecordsRuleComponentState, contextStoreTargetedRecordsRuleComponentState,
); );
const contextStoreFilters = useRecoilComponentValueV2(
contextStoreFiltersComponentState,
);
const graphqlFilter = computeContextStoreFilters( const graphqlFilter = computeContextStoreFilters(
contextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule,
contextStoreFilters,
objectMetadataItem, objectMetadataItem,
); );

View File

@@ -0,0 +1,11 @@
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const contextStoreFiltersComponentState = createComponentStateV2<
Filter[]
>({
key: 'contextStoreFiltersComponentState',
defaultValue: [],
componentInstanceContext: ContextStoreComponentInstanceContext,
});

View File

@@ -1,5 +1,4 @@
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext'; import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2'; import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
type ContextStoreTargetedRecordsRuleSelectionMode = { type ContextStoreTargetedRecordsRuleSelectionMode = {
@@ -10,7 +9,6 @@ type ContextStoreTargetedRecordsRuleSelectionMode = {
type ContextStoreTargetedRecordsRuleExclusionMode = { type ContextStoreTargetedRecordsRuleExclusionMode = {
mode: 'exclusion'; mode: 'exclusion';
excludedRecordIds: string[]; excludedRecordIds: string[];
filters: Filter[];
}; };
export type ContextStoreTargetedRecordsRule = export type ContextStoreTargetedRecordsRule =

View File

@@ -1,6 +1,8 @@
import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { expect } from '@storybook/test';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems'; import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
describe('computeContextStoreFilters', () => { describe('computeContextStoreFilters', () => {
const personObjectMetadataItem = generatedMockObjectMetadataItems.find( const personObjectMetadataItem = generatedMockObjectMetadataItems.find(
@@ -15,6 +17,7 @@ describe('computeContextStoreFilters', () => {
const filters = computeContextStoreFilters( const filters = computeContextStoreFilters(
contextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule,
[],
personObjectMetadataItem, personObjectMetadataItem,
); );
@@ -28,32 +31,35 @@ describe('computeContextStoreFilters', () => {
it('should work for exclusion mode', () => { it('should work for exclusion mode', () => {
const contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule = { const contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule = {
mode: 'exclusion', mode: 'exclusion',
filters: [
{
id: 'name-filter',
variant: 'default',
fieldMetadataId: personObjectMetadataItem.fields.find(
(field) => field.name === 'name',
)!.id,
value: 'John',
displayValue: 'John',
displayAvatarUrl: undefined,
operand: ViewFilterOperand.Contains,
definition: {
fieldMetadataId: personObjectMetadataItem.fields.find(
(field) => field.name === 'name',
)!.id,
label: 'Name',
iconName: 'person',
type: 'TEXT',
},
},
],
excludedRecordIds: ['1', '2', '3'], excludedRecordIds: ['1', '2', '3'],
}; };
const contextStoreFilters: Filter[] = [
{
id: 'name-filter',
variant: 'default',
fieldMetadataId: personObjectMetadataItem.fields.find(
(field) => field.name === 'name',
)!.id,
value: 'John',
displayValue: 'John',
displayAvatarUrl: undefined,
operand: ViewFilterOperand.Contains,
definition: {
fieldMetadataId: personObjectMetadataItem.fields.find(
(field) => field.name === 'name',
)!.id,
label: 'Name',
iconName: 'person',
type: 'TEXT',
},
},
];
const filters = computeContextStoreFilters( const filters = computeContextStoreFilters(
contextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule,
contextStoreFilters,
personObjectMetadataItem, personObjectMetadataItem,
); );

View File

@@ -1,11 +1,13 @@
import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter'; import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables'; import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables';
export const computeContextStoreFilters = ( export const computeContextStoreFilters = (
contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule,
contextStoreFilters: Filter[],
objectMetadataItem: ObjectMetadataItem, objectMetadataItem: ObjectMetadataItem,
) => { ) => {
let queryFilter: RecordGqlOperationFilter | undefined; let queryFilter: RecordGqlOperationFilter | undefined;
@@ -13,7 +15,7 @@ export const computeContextStoreFilters = (
if (contextStoreTargetedRecordsRule.mode === 'exclusion') { if (contextStoreTargetedRecordsRule.mode === 'exclusion') {
queryFilter = makeAndFilterVariables([ queryFilter = makeAndFilterVariables([
computeViewRecordGqlOperationFilter( computeViewRecordGqlOperationFilter(
contextStoreTargetedRecordsRule.filters, contextStoreFilters,
objectMetadataItem?.fields ?? [], objectMetadataItem?.fields ?? [],
[], [],
), ),
@@ -36,7 +38,11 @@ export const computeContextStoreFilters = (
in: contextStoreTargetedRecordsRule.selectedRecordIds, in: contextStoreTargetedRecordsRule.selectedRecordIds,
}, },
} }
: undefined; : computeViewRecordGqlOperationFilter(
contextStoreFilters,
objectMetadataItem?.fields ?? [],
[],
);
} }
return queryFilter; return queryFilter;

View File

@@ -1,3 +1,4 @@
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState'; import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
@@ -35,6 +36,10 @@ export const RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect =
objectMetadataItem?.namePlural ?? '', objectMetadataItem?.namePlural ?? '',
); );
const contextStoreFilters = useRecoilComponentValueV2(
contextStoreFiltersComponentState,
);
const { totalCount } = useFindManyRecords({ const { totalCount } = useFindManyRecords({
...findManyRecordsParams, ...findManyRecordsParams,
recordGqlFields: { recordGqlFields: {
@@ -42,6 +47,7 @@ export const RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect =
}, },
filter: computeContextStoreFilters( filter: computeContextStoreFilters(
contextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule,
contextStoreFilters,
objectMetadataItem, objectMetadataItem,
), ),
limit: 1, limit: 1,

View File

@@ -1,5 +1,6 @@
import { useContext, useEffect } from 'react'; import { useContext, useEffect } from 'react';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
@@ -99,7 +100,6 @@ export const RecordIndexTableContainerEffect = () => {
setContextStoreTargetedRecords({ setContextStoreTargetedRecords({
mode: 'exclusion', mode: 'exclusion',
excludedRecordIds: unselectedRowIds, excludedRecordIds: unselectedRowIds,
filters: recordIndexFilters,
}); });
} else { } else {
setContextStoreTargetedRecords({ setContextStoreTargetedRecords({
@@ -116,11 +116,22 @@ export const RecordIndexTableContainerEffect = () => {
}; };
}, [ }, [
hasUserSelectedAllRows, hasUserSelectedAllRows,
recordIndexFilters,
selectedRowIds, selectedRowIds,
setContextStoreTargetedRecords, setContextStoreTargetedRecords,
unselectedRowIds, unselectedRowIds,
]); ]);
const setContextStoreFilters = useSetRecoilComponentStateV2(
contextStoreFiltersComponentState,
);
useEffect(() => {
setContextStoreFilters(recordIndexFilters);
return () => {
setContextStoreFilters([]);
};
}, [recordIndexFilters, setContextStoreFilters]);
return <></>; return <></>;
}; };

View File

@@ -106,7 +106,7 @@ const mocks: MockedResponse[] = [
} }
`, `,
variables: { variables: {
filter: undefined, filter: {},
limit: 30, limit: 30,
orderBy: [{ position: 'AscNullsFirst' }], orderBy: [{ position: 'AscNullsFirst' }],
}, },

View File

@@ -6,6 +6,7 @@ import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefin
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters'; import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
@@ -81,8 +82,13 @@ export const useRecordData = ({
contextStoreTargetedRecordsRuleComponentState, contextStoreTargetedRecordsRuleComponentState,
); );
const contextStoreFilters = useRecoilComponentValueV2(
contextStoreFiltersComponentState,
);
const queryFilter = computeContextStoreFilters( const queryFilter = computeContextStoreFilters(
contextStoreTargetedRecordsRule, contextStoreTargetedRecordsRule,
contextStoreFilters,
objectMetadataItem, objectMetadataItem,
); );