Table virtualization fix (#15060)

- Added readableFields for visible record field selector to take
permission into account
- Force refresh of table virtualization when updating view fields
This commit is contained in:
Lucas Bordeau
2025-10-13 15:30:50 +02:00
committed by GitHub
parent 0dcf6c77b9
commit 56b0bbcad9
4 changed files with 42 additions and 1 deletions
@@ -3,6 +3,7 @@ import { isActiveFieldMetadataItem } from '@/object-metadata/utils/isActiveField
import { RecordFieldsComponentInstanceContext } from '@/object-record/record-field/states/context/RecordFieldsComponentInstanceContext';
import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState';
import { createComponentSelector } from '@/ui/utilities/state/component-state/utils/createComponentSelector';
import { findById } from 'twenty-shared/utils';
import { sortByProperty } from '~/utils/array/sortByProperty';
export const visibleRecordFieldsComponentSelector = createComponentSelector({
@@ -47,10 +48,16 @@ export const visibleRecordFieldsComponentSelector = createComponentSelector({
return false;
}
return isActiveFieldMetadataItem({
const isActive = isActiveFieldMetadataItem({
objectNameSingular: objectMetadataItem.nameSingular,
fieldMetadata: fieldMetadataItem,
});
const isReadable = objectMetadataItem.readableFields.some(
findById(fieldMetadataItem.id),
);
return isReadable && isActive;
},
);
@@ -3,12 +3,15 @@ import { useRecoilValue } from 'recoil';
import { useRecordIndexTableFetchMore } from '@/object-record/record-index/hooks/useRecordIndexTableFetchMore';
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector';
import { useTriggerInitialRecordTableDataLoad } from '@/object-record/record-table/virtualization/hooks/useTriggerInitialRecordTableDataLoad';
import { isInitializingVirtualTableDataLoadingComponentState } from '@/object-record/record-table/virtualization/states/isInitializingVirtualTableDataLoadingComponentState';
import { lastContextStoreVirtualizedViewIdComponentState } from '@/object-record/record-table/virtualization/states/lastContextStoreVirtualizedViewIdComponentState';
import { lastContextStoreVirtualizedVisibleRecordFieldsComponentState } from '@/object-record/record-table/virtualization/states/lastContextStoreVirtualizedVisibleRecordFieldsComponentState';
import { lastRecordTableQueryIdentifierComponentState } from '@/object-record/record-table/virtualization/states/lastRecordTableQueryIdentifierComponentState';
import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useEffect } from 'react';
@@ -21,6 +24,9 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => {
const [lastRecordTableQueryIdentifier, setLastRecordTableQueryIdentifier] =
useRecoilComponentState(lastRecordTableQueryIdentifierComponentState);
const visibleRecordFields = useRecoilComponentValue(
visibleRecordFieldsComponentSelector,
);
const [isInitializingVirtualTableDataLoading] = useRecoilComponentState(
isInitializingVirtualTableDataLoadingComponentState,
);
@@ -37,6 +43,13 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => {
setLastContextStoreVirtualizedViewId,
] = useRecoilComponentState(lastContextStoreVirtualizedViewIdComponentState);
const [
lastContextStoreVisibleRecordFields,
setLastContextStoreVisibleRecordFields,
] = useRecoilComponentState(
lastContextStoreVirtualizedVisibleRecordFieldsComponentState,
);
const { currentView } = useGetCurrentViewOnly();
useEffect(() => {
@@ -55,6 +68,13 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => {
) {
setLastRecordTableQueryIdentifier(queryIdentifier);
await triggerInitialRecordTableDataLoad();
} else if (
JSON.stringify(lastContextStoreVisibleRecordFields) !==
JSON.stringify(visibleRecordFields)
) {
setLastContextStoreVisibleRecordFields(visibleRecordFields);
await triggerInitialRecordTableDataLoad();
}
})();
@@ -68,6 +88,9 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => {
currentView,
lastContextStoreVirtualizedViewId,
setLastContextStoreVirtualizedViewId,
lastContextStoreVisibleRecordFields,
setLastContextStoreVisibleRecordFields,
visibleRecordFields,
]);
return <></>;
@@ -0,0 +1,10 @@
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { type RecordField } from '@/object-record/record-field/types/RecordField';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const lastContextStoreVirtualizedVisibleRecordFieldsComponentState =
createComponentState<RecordField[] | null>({
key: 'lastContextStoreVirtualizedVisibleRecordFieldsComponentState',
componentInstanceContext: ContextStoreComponentInstanceContext,
defaultValue: null,
});
@@ -16,6 +16,7 @@ import {
export const usePersistViewFieldRecords = () => {
const { triggerViewFieldOptimisticEffect } =
useTriggerViewFieldOptimisticEffect();
const [createCoreViewFieldMutation] = useCreateCoreViewFieldMutation();
const [updateCoreViewFieldMutation] = useUpdateCoreViewFieldMutation();
const [deleteCoreViewFieldMutation] = useDeleteCoreViewFieldMutation();