From cb96f019d652082267b60384f16c4e6b45e290ac Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Thu, 13 Mar 2025 19:17:48 +0100 Subject: [PATCH] Set record groups when view groups are updated (#10863) Currently we need to refresh to see view group updates. --- .../hooks/useRecordGroupReorder.ts | 8 ++-- ...etRecordGroup.ts => useSetRecordGroups.ts} | 33 +++++++++++++- .../hooks/useHandleRecordGroupField.ts | 17 +++++++- .../hooks/useLoadRecordIndexStates.ts | 43 ++++++------------- 4 files changed, 64 insertions(+), 37 deletions(-) rename packages/twenty-front/src/modules/object-record/record-group/hooks/{useSetRecordGroup.ts => useSetRecordGroups.ts} (76%) diff --git a/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupReorder.ts b/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupReorder.ts index 97fa3e914..20092c5b6 100644 --- a/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupReorder.ts +++ b/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupReorder.ts @@ -1,6 +1,6 @@ import { OnDragEndResponder } from '@hello-pangea/dnd'; -import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup'; +import { useSetRecordGroups } from '@/object-record/record-group/hooks/useSetRecordGroups'; import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState'; import { visibleRecordGroupIdsComponentFamilySelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentFamilySelector'; import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition'; @@ -23,7 +23,7 @@ export const useRecordGroupReorder = ({ viewBarId, viewType, }: UseRecordGroupHandlersParams) => { - const setRecordGroup = useSetRecordGroup(); + const { setRecordGroups } = useSetRecordGroups(); const visibleRecordGroupIdsFamilySelector = useRecoilComponentCallbackStateV2( visibleRecordGroupIdsComponentFamilySelector, @@ -78,14 +78,14 @@ export const useRecordGroupReorder = ({ ]; }, []); - setRecordGroup(updatedRecordGroups, viewBarId); + setRecordGroups(updatedRecordGroups, viewBarId); saveViewGroups( mapRecordGroupDefinitionsToViewGroups(updatedRecordGroups), ); }, [ saveViewGroups, - setRecordGroup, + setRecordGroups, viewBarId, viewType, visibleRecordGroupIdsFamilySelector, diff --git a/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroup.ts b/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts similarity index 76% rename from packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroup.ts rename to packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts index 9cbc214d1..1d7e87970 100644 --- a/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroup.ts +++ b/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts @@ -1,17 +1,24 @@ import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; +import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow'; import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState'; import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState'; import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState'; import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition'; +import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId'; import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; +import { ViewGroup } from '@/views/types/ViewGroup'; +import { mapViewGroupsToRecordGroupDefinitions } from '@/views/utils/mapViewGroupsToRecordGroupDefinitions'; +import { useCallback } from 'react'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -export const useSetRecordGroup = () => { - return useRecoilCallback( +export const useSetRecordGroups = () => { + const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(); + + const setRecordGroups = useRecoilCallback( ({ snapshot, set }) => (recordGroups: RecordGroupDefinition[], recordIndexId: string) => { const objectMetadataItemId = snapshot @@ -104,4 +111,26 @@ export const useSetRecordGroup = () => { }, [], ); + + const setRecordGroupsFromViewGroups = useCallback( + (viewId: string, viewGroups: ViewGroup[]) => { + const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId( + objectMetadataItem.namePlural, + viewId, + ); + + const newGroupDefinitions = mapViewGroupsToRecordGroupDefinitions({ + objectMetadataItem, + viewGroups, + }); + + setRecordGroups(newGroupDefinitions, recordIndexId); + }, + [objectMetadataItem, setRecordGroups], + ); + + return { + setRecordGroups, + setRecordGroupsFromViewGroups, + }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts index 6a0c5d03b..fedc1b13c 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts @@ -1,5 +1,6 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { useSetRecordGroups } from '@/object-record/record-group/hooks/useSetRecordGroups'; import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroupRecords'; import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState'; @@ -18,6 +19,8 @@ export const useHandleRecordGroupField = () => { const { getViewFromPrefetchState } = useGetViewFromPrefetchState(); + const { setRecordGroupsFromViewGroups } = useSetRecordGroups(); + const handleRecordGroupFieldChange = useRecoilCallback( ({ snapshot }) => async (fieldMetadataItem: FieldMetadataItem) => { @@ -86,6 +89,15 @@ export const useHandleRecordGroupField = () => { (group) => group.fieldMetadataId !== fieldMetadataItem.id, ); + const newViewGroupsList = [ + ...view.viewGroups.filter( + (group) => group.fieldMetadataId === fieldMetadataItem.id, + ), + ...viewGroupsToCreate, + ]; + + setRecordGroupsFromViewGroups(view.id, newViewGroupsList); + if (viewGroupsToCreate.length > 0) { await createViewGroupRecords({ viewGroupsToCreate, viewId: view.id }); } @@ -95,10 +107,11 @@ export const useHandleRecordGroupField = () => { } }, [ - createViewGroupRecords, - deleteViewGroupRecords, currentViewIdCallbackState, getViewFromPrefetchState, + setRecordGroupsFromViewGroups, + createViewGroupRecords, + deleteViewGroupRecords, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts index 3d3a9b0fd..44fa81a6a 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts @@ -4,7 +4,7 @@ import { availableFieldMetadataItemsForSortFamilySelector } from '@/object-metad import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; -import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup'; +import { useSetRecordGroups } from '@/object-record/record-group/hooks/useSetRecordGroups'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState'; import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState'; @@ -21,15 +21,13 @@ import { tableSortsComponentState } from '@/object-record/record-table/states/ta import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation'; import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns'; +import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { View } from '@/views/types/View'; import { ViewField } from '@/views/types/ViewField'; -import { ViewGroup } from '@/views/types/ViewGroup'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; -import { mapViewGroupsToRecordGroupDefinitions } from '@/views/utils/mapViewGroupsToRecordGroupDefinitions'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; -import { useCallback } from 'react'; import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; @@ -57,7 +55,7 @@ export const useLoadRecordIndexStates = () => { const setRecordIndexViewKanbanAggregateOperationState = useSetRecoilState( recordIndexKanbanAggregateOperationState, ); - const setRecordGroup = useSetRecordGroup(); + const { setRecordGroupsFromViewGroups } = useSetRecordGroups(); const { setTableColumns } = useSetTableColumns(); @@ -173,26 +171,13 @@ export const useLoadRecordIndexStates = () => { [setTableColumns], ); - const onViewGroupsChange = useCallback( - ( - viewGroups: ViewGroup[], - objectMetadataItem: ObjectMetadataItem, - recordIndexId: string, - ) => { - const newGroupDefinitions = mapViewGroupsToRecordGroupDefinitions({ - objectMetadataItem, - viewGroups, - }); - - setRecordGroup(newGroupDefinitions, recordIndexId); - }, - [setRecordGroup], - ); - const loadRecordIndexStates = useRecoilCallback( ({ snapshot, set }) => async (view: View, objectMetadataItem: ObjectMetadataItem) => { - const recordIndexId = `${objectMetadataItem.namePlural}-${view.id}`; + const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId( + objectMetadataItem.namePlural, + view.id, + ); const filterableFieldMetadataItems = snapshot .getLoadable( @@ -203,7 +188,7 @@ export const useLoadRecordIndexStates = () => { .getValue(); onViewFieldsChange(view.viewFields, objectMetadataItem, recordIndexId); - onViewGroupsChange(view.viewGroups, objectMetadataItem, recordIndexId); + setRecordGroupsFromViewGroups(view.id, view.viewGroups); set( tableFiltersComponentState.atomFamily({ @@ -259,16 +244,16 @@ export const useLoadRecordIndexStates = () => { }, [ onViewFieldsChange, - onViewGroupsChange, - setContextStoreTargetedRecordsRuleComponentState, + setRecordGroupsFromViewGroups, setRecordIndexFilters, - setRecordIndexIsCompactModeActive, - setRecordIndexSorts, setRecordIndexViewFilterGroups, - setRecordIndexViewKanbanAggregateOperationState, - setRecordIndexViewKanbanFieldMetadataIdState, + setContextStoreTargetedRecordsRuleComponentState, + setRecordIndexSorts, setRecordIndexViewType, setRecordIndexOpenRecordIn, + setRecordIndexViewKanbanFieldMetadataIdState, + setRecordIndexViewKanbanAggregateOperationState, + setRecordIndexIsCompactModeActive, ], );