From d34ec4da2d67a5f5dcae65f84556f1e6bd4aa746 Mon Sep 17 00:00:00 2001 From: Weiko Date: Fri, 14 Mar 2025 17:27:25 +0100 Subject: [PATCH] Fix kanban view picker total count (#10898) Fixes https://github.com/twentyhq/twenty/issues/9790 Before https://github.com/user-attachments/assets/332ec338-ce87-4d4d-ac47-a4e76dceb5b0 After https://github.com/user-attachments/assets/93a03842-386a-4e75-a709-85a91bbc7679 --------- Co-authored-by: Charles Bochet --- .../hooks/useAggregateRecords.ts | 4 +- .../RecordIndexTableContainerEffect.tsx | 11 ----- .../hooks/useLoadRecordIndexBoardColumn.ts | 9 ---- .../hooks/useSetRecordIndexEntityCount.ts | 38 --------------- ...xEntityCountNoGroupComponentFamilyState.ts | 9 ---- ...recordIndexEntityCountComponentSelector.ts | 39 ---------------- .../SignInBackgroundMockContainerEffect.tsx | 11 +---- .../internal/useGetRecordIndexTotalCount.ts | 46 +++++++++++++++++++ .../components/ViewPickerDropdown.tsx | 9 ++-- 9 files changed, 52 insertions(+), 124 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexEntityCount.ts delete mode 100644 packages/twenty-front/src/modules/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/object-record/record-index/states/selectors/recordIndexEntityCountComponentSelector.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts diff --git a/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts index 0805c2f3f..bc8c88fea 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useAggregateRecords.ts @@ -15,7 +15,7 @@ export type AggregateRecordsData = { }; }; -export const useAggregateRecords = ({ +export const useAggregateRecords = ({ objectNameSingular, filter, recordGqlFieldsAggregate, @@ -63,7 +63,7 @@ export const useAggregateRecords = ({ return { objectMetadataItem, - data: formattedData, + data: formattedData as T, loading, error, }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx index 10b483fd0..1edaf1051 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx @@ -5,7 +5,6 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; import { useHandleToggleColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleColumnFilter'; import { useHandleToggleColumnSort } from '@/object-record/record-index/hooks/useHandleToggleColumnSort'; -import { useSetRecordIndexEntityCount } from '@/object-record/record-index/hooks/useSetRecordIndexEntityCount'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState'; import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation'; @@ -21,7 +20,6 @@ export const RecordIndexTableContainerEffect = () => { const { setAvailableTableColumns, - setOnEntityCountChange, setOnToggleColumnFilter, setOnToggleColumnSort, } = useRecordTable({ @@ -35,8 +33,6 @@ export const RecordIndexTableContainerEffect = () => { const { columnDefinitions } = useColumnDefinitionsFromFieldMetadata(objectMetadataItem); - const { setRecordIndexEntityCount } = useSetRecordIndexEntityCount(viewBarId); - useEffect(() => { setAvailableTableColumns(columnDefinitions); }, [columnDefinitions, setAvailableTableColumns]); @@ -66,13 +62,6 @@ export const RecordIndexTableContainerEffect = () => { ); }, [setOnToggleColumnSort, handleToggleColumnSort]); - useEffect(() => { - setOnEntityCountChange( - () => (entityCount: number, currentRecordGroupId?: string) => - setRecordIndexEntityCount(entityCount, currentRecordGroupId), - ); - }, [setRecordIndexEntityCount, setOnEntityCountChange]); - const setViewFieldAggregateOperation = useRecoilCallback( ({ set, snapshot }) => (viewField: ViewField) => { diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts index ead6b4b3e..d857365ca 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoardColumn.ts @@ -11,7 +11,6 @@ import { currentRecordFiltersComponentState } from '@/object-record/record-filte import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter'; import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState'; import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields'; -import { useSetRecordIndexEntityCount } from '@/object-record/record-index/hooks/useSetRecordIndexEntityCount'; import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; @@ -88,7 +87,6 @@ export const useLoadRecordIndexBoardColumn = ({ fetchMoreRecords, queryStateIdentifier, hasNextPage, - totalCount, } = useFindManyRecords({ objectNameSingular, filter, @@ -97,13 +95,6 @@ export const useLoadRecordIndexBoardColumn = ({ limit: 10, }); - const { setRecordIndexEntityCount } = - useSetRecordIndexEntityCount(recordBoardId); - - useEffect(() => { - setRecordIndexEntityCount(totalCount ?? 0, columnId); - }, [setRecordIndexEntityCount, totalCount, columnId]); - useEffect(() => { setRecordIdsForColumn(columnId, records); }, [records, setRecordIdsForColumn, columnId]); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexEntityCount.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexEntityCount.ts deleted file mode 100644 index 1abdeb8a9..000000000 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexEntityCount.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { recordIndexEntityCountByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexEntityCountByGroupComponentFamilyState'; -import { recordIndexEntityCountNoGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState'; -import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; -import { useRecoilCallback } from 'recoil'; -import { isDefined } from 'twenty-shared'; - -export const useSetRecordIndexEntityCount = (viewBarComponentId?: string) => { - const recordIndexEntityCountNoGroupFamilyState = - useRecoilComponentCallbackStateV2( - recordIndexEntityCountNoGroupComponentFamilyState, - viewBarComponentId, - ); - - const recordIndexEntityCountByGroupFamilyState = - useRecoilComponentCallbackStateV2( - recordIndexEntityCountByGroupComponentFamilyState, - viewBarComponentId, - ); - - const setRecordIndexEntityCount = useRecoilCallback( - ({ set }) => - (count: number, recordGroupId?: string) => { - if (isDefined(recordGroupId)) { - set(recordIndexEntityCountByGroupFamilyState(recordGroupId), count); - } else { - set(recordIndexEntityCountNoGroupFamilyState, count); - } - }, - [ - recordIndexEntityCountByGroupFamilyState, - recordIndexEntityCountNoGroupFamilyState, - ], - ); - - return { - setRecordIndexEntityCount, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState.ts b/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState.ts deleted file mode 100644 index 911f7ae24..000000000 --- a/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2'; -import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; - -export const recordIndexEntityCountNoGroupComponentFamilyState = - createComponentStateV2({ - key: 'recordIndexEntityCountNoGroupComponentFamilyState', - defaultValue: undefined, - componentInstanceContext: ViewComponentInstanceContext, - }); diff --git a/packages/twenty-front/src/modules/object-record/record-index/states/selectors/recordIndexEntityCountComponentSelector.ts b/packages/twenty-front/src/modules/object-record/record-index/states/selectors/recordIndexEntityCountComponentSelector.ts deleted file mode 100644 index 1c364c7ea..000000000 --- a/packages/twenty-front/src/modules/object-record/record-index/states/selectors/recordIndexEntityCountComponentSelector.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState'; -import { recordIndexEntityCountByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexEntityCountByGroupComponentFamilyState'; -import { recordIndexEntityCountNoGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexEntityCountNoGroupComponentFamilyState'; -import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2'; -import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; - -export const recordIndexEntityCountComponentSelector = - createComponentSelectorV2({ - key: 'recordIndexEntityCountComponentSelector', - get: - ({ instanceId }) => - ({ get }) => { - const recordGroupIds = get( - recordGroupIdsComponentState.atomFamily({ - instanceId, - }), - ); - - if (recordGroupIds.length === 0) { - return get( - recordIndexEntityCountNoGroupComponentFamilyState.atomFamily({ - instanceId, - }), - ); - } - - return recordGroupIds.reduce((acc, recordGroupId) => { - const count = get( - recordIndexEntityCountByGroupComponentFamilyState.atomFamily({ - instanceId, - familyKey: recordGroupId, - }), - ); - - return acc + (count ?? 0); - }, 0); - }, - componentInstanceContext: ViewComponentInstanceContext, - }); diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx index ef155910a..e39f080b0 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx @@ -4,7 +4,6 @@ import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainCo import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; -import { useSetRecordIndexEntityCount } from '@/object-record/record-index/hooks/useSetRecordIndexEntityCount'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useSetTableColumns } from '@/object-record/record-table/hooks/useSetTableColumns'; import { SIGN_IN_BACKGROUND_MOCK_COLUMN_DEFINITIONS } from '@/sign-in-background-mock/constants/SignInBackgroundMockColumnDefinitions'; @@ -30,7 +29,7 @@ export const SignInBackgroundMockContainerEffect = ({ MAIN_CONTEXT_STORE_INSTANCE_ID, ); - const { setAvailableTableColumns, setOnEntityCountChange } = useRecordTable({ + const { setAvailableTableColumns } = useRecordTable({ recordTableId, }); @@ -47,8 +46,6 @@ export const SignInBackgroundMockContainerEffect = ({ const { setAvailableFieldDefinitions, setViewObjectMetadataId } = useInitViewBar(viewId); - const { setRecordIndexEntityCount } = useSetRecordIndexEntityCount(viewId); - useEffect(() => { setViewObjectMetadataId?.(objectMetadataItem.id); @@ -75,11 +72,5 @@ export const SignInBackgroundMockContainerEffect = ({ setContextStoreCurrentObjectMetadataItemId, ]); - useEffect(() => { - setOnEntityCountChange( - () => (entityCount: number) => setRecordIndexEntityCount(entityCount), - ); - }, [setRecordIndexEntityCount, setOnEntityCountChange]); - return <>; }; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts b/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts new file mode 100644 index 000000000..9179192cf --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/internal/useGetRecordIndexTotalCount.ts @@ -0,0 +1,46 @@ +import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow'; +import { useAggregateRecords } from '@/object-record/hooks/useAggregateRecords'; +import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; +import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies'; +import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; +import { computeRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter'; +import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations'; +import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; + +export const useGetRecordIndexTotalCount = () => { + const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(); + + const currentRecordFilterGroups = useRecoilComponentValueV2( + currentRecordFilterGroupsComponentState, + ); + + const currentRecordFilters = useRecoilComponentValueV2( + currentRecordFiltersComponentState, + ); + + const { filterValueDependencies } = useFilterValueDependencies(); + + const filter = computeRecordGqlOperationFilter({ + filterValueDependencies, + recordFilters: currentRecordFilters, + recordFilterGroups: currentRecordFilterGroups, + fields: objectMetadataItem.fields, + }); + + const { data, loading } = useAggregateRecords<{ + id: { COUNT: number }; + }>({ + objectNameSingular: objectMetadataItem.nameSingular, + filter, + recordGqlFieldsAggregate: { + id: [AGGREGATE_OPERATIONS.count], + }, + }); + + const totalCount = data?.id?.COUNT; + + return { + totalCount, + loading, + }; +}; diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx index 9ea2d2107..a4f031bae 100644 --- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx +++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx @@ -7,11 +7,10 @@ import { useIcons, } from 'twenty-ui'; -import { recordIndexEntityCountComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexEntityCountComponentSelector'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; -import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { useGetRecordIndexTotalCount } from '@/views/hooks/internal/useGetRecordIndexTotalCount'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { ViewsHotkeyScope } from '@/views/types/ViewsHotkeyScope'; import { ViewPickerContentCreateMode } from '@/views/view-picker/components/ViewPickerContentCreateMode'; @@ -55,9 +54,7 @@ export const ViewPickerDropdown = () => { const { updateViewFromCurrentState } = useUpdateViewFromCurrentState(); - const entityCount = useRecoilComponentValueV2( - recordIndexEntityCountComponentSelector, - ); + const { totalCount } = useGetRecordIndexTotalCount(); const { isDropdownOpen: isViewsListDropdownOpen } = useDropdown( VIEW_PICKER_DROPDOWN_ID, @@ -92,7 +89,7 @@ export const ViewPickerDropdown = () => { )} {currentView?.name ?? 'All'} - {isDefined(entityCount) && <>· {entityCount} } + {isDefined(totalCount) && <>· {totalCount} }