Add initialization of new record sorts state and added remove record sorts util (#10358)
This PR adds the same synchronization utils and hooks from view to record sorts, as we did with view and record filters. The goal is to apply what's in the view sorts only when needed. Also added tests for those utils and hooks. We also add useRemoveRecordSorts.
This commit is contained in:
@ -6,7 +6,7 @@ import { useCloseSortDropdown } from '@/object-record/object-sort-dropdown/hooks
|
||||
import { useResetRecordSortDropdownSearchInput } from '@/object-record/object-sort-dropdown/hooks/useResetRecordSortDropdownSearchInput';
|
||||
import { useResetSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useResetSortDropdown';
|
||||
import { useToggleSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useToggleSortDropdown';
|
||||
import { isRecordSortDirectionMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionMenuUnfoldedComponentState';
|
||||
import { isRecordSortDirectionDropdownMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionDropdownMenuUnfoldedComponentState';
|
||||
import { objectSortDropdownSearchInputComponentState } from '@/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState';
|
||||
import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState';
|
||||
import { selectedRecordSortDirectionComponentState } from '@/object-record/object-sort-dropdown/states/selectedRecordSortDirectionComponentState';
|
||||
@ -84,7 +84,7 @@ export const ObjectSortDropdownButton = ({
|
||||
);
|
||||
|
||||
const isRecordSortDirectionMenuUnfolded = useRecoilComponentValueV2(
|
||||
isRecordSortDirectionMenuUnfoldedComponentState,
|
||||
isRecordSortDirectionDropdownMenuUnfoldedComponentState,
|
||||
);
|
||||
|
||||
const { resetSortDropdown } = useResetSortDropdown();
|
||||
@ -168,7 +168,7 @@ export const ObjectSortDropdownButton = ({
|
||||
useRecoilComponentStateV2(selectedRecordSortDirectionComponentState);
|
||||
|
||||
const setIsRecordSortDirectionMenuUnfolded = useSetRecoilComponentStateV2(
|
||||
isRecordSortDirectionMenuUnfoldedComponentState,
|
||||
isRecordSortDirectionDropdownMenuUnfoldedComponentState,
|
||||
);
|
||||
|
||||
const handleSortDirectionClick = (sortDirection: RecordSortDirection) => {
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import { isRecordSortDirectionMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionMenuUnfoldedComponentState';
|
||||
import { isRecordSortDirectionDropdownMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionDropdownMenuUnfoldedComponentState';
|
||||
import { selectedRecordSortDirectionComponentState } from '@/object-record/object-sort-dropdown/states/selectedRecordSortDirectionComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
export const useResetSortDropdown = () => {
|
||||
const setIsRecordSortDirectionMenuUnfolded = useSetRecoilComponentStateV2(
|
||||
isRecordSortDirectionMenuUnfoldedComponentState,
|
||||
);
|
||||
const setIsRecordSortDirectionDropdownMenuUnfolded =
|
||||
useSetRecoilComponentStateV2(
|
||||
isRecordSortDirectionDropdownMenuUnfoldedComponentState,
|
||||
);
|
||||
|
||||
const setSelectedRecordSortDirection = useSetRecoilComponentStateV2(
|
||||
selectedRecordSortDirectionComponentState,
|
||||
);
|
||||
|
||||
const resetSortDropdown = () => {
|
||||
setIsRecordSortDirectionMenuUnfolded(false);
|
||||
setIsRecordSortDirectionDropdownMenuUnfolded(false);
|
||||
setSelectedRecordSortDirection('asc');
|
||||
};
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { ObjectSortDropdownComponentInstanceContext } from '@/object-record/object-sort-dropdown/states/context/ObjectSortDropdownComponentInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const isRecordSortDirectionMenuUnfoldedComponentState =
|
||||
export const isRecordSortDirectionDropdownMenuUnfoldedComponentState =
|
||||
createComponentStateV2<boolean>({
|
||||
key: 'isRecordSortDirectionMenuUnfoldedComponentState',
|
||||
key: 'isRecordSortDirectionDropdownMenuUnfoldedComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: ObjectSortDropdownComponentInstanceContext,
|
||||
});
|
||||
@ -1,5 +1,6 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useRemoveRecordSort } from '@/object-record/record-sort/hooks/useRemoveRecordSort';
|
||||
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useDeleteCombinedViewSorts } from '@/views/hooks/useDeleteCombinedViewSorts';
|
||||
@ -22,9 +23,12 @@ export const RecordIndexRemoveSortingModal = ({
|
||||
|
||||
const { deleteCombinedViewSort } = useDeleteCombinedViewSorts(recordIndexId);
|
||||
|
||||
const { removeRecordSort } = useRemoveRecordSort();
|
||||
|
||||
const handleRemoveClick = () => {
|
||||
fieldMetadataIds.forEach((id) => {
|
||||
deleteCombinedViewSort(id);
|
||||
removeRecordSort(id);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ export const useHandleToggleColumnSort = ({
|
||||
const { upsertRecordSort } = useUpsertRecordSort();
|
||||
|
||||
const handleToggleColumnSort = useCallback(
|
||||
(fieldMetadataId: string) => {
|
||||
async (fieldMetadataId: string) => {
|
||||
const correspondingColumnDefinition = columnDefinitions.find(
|
||||
(columnDefinition) =>
|
||||
columnDefinition.fieldMetadataId === fieldMetadataId,
|
||||
@ -48,8 +48,9 @@ export const useHandleToggleColumnSort = ({
|
||||
direction: 'asc',
|
||||
};
|
||||
|
||||
upsertCombinedViewSort(newSort);
|
||||
upsertRecordSort(newSort);
|
||||
|
||||
await upsertCombinedViewSort(newSort);
|
||||
},
|
||||
[columnDefinitions, upsertCombinedViewSort, upsertRecordSort],
|
||||
);
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
export const useRemoveRecordSort = () => {
|
||||
const currentRecordSortsCallbackState = useRecoilComponentCallbackStateV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
const removeRecordSort = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(fieldMetadataId: string) => {
|
||||
const currentRecordSorts = getSnapshotValue(
|
||||
snapshot,
|
||||
currentRecordSortsCallbackState,
|
||||
);
|
||||
|
||||
const hasFoundRecordSortInCurrentRecordSorts = currentRecordSorts.some(
|
||||
(existingSort) => existingSort.fieldMetadataId === fieldMetadataId,
|
||||
);
|
||||
|
||||
if (hasFoundRecordSortInCurrentRecordSorts) {
|
||||
set(currentRecordSortsCallbackState, (currentRecordSorts) => {
|
||||
const newCurrentRecordSorts = [...currentRecordSorts];
|
||||
|
||||
const indexOfSortToRemove = newCurrentRecordSorts.findIndex(
|
||||
(existingSort) =>
|
||||
existingSort.fieldMetadataId === fieldMetadataId,
|
||||
);
|
||||
|
||||
if (indexOfSortToRemove < 0) {
|
||||
return newCurrentRecordSorts;
|
||||
}
|
||||
|
||||
newCurrentRecordSorts.splice(indexOfSortToRemove, 1);
|
||||
|
||||
return newCurrentRecordSorts;
|
||||
});
|
||||
}
|
||||
},
|
||||
[currentRecordSortsCallbackState],
|
||||
);
|
||||
|
||||
return {
|
||||
removeRecordSort,
|
||||
};
|
||||
};
|
||||
@ -1,5 +1,6 @@
|
||||
import { IconArrowDown, IconArrowUp } from 'twenty-ui';
|
||||
|
||||
import { useRemoveRecordSort } from '@/object-record/record-sort/hooks/useRemoveRecordSort';
|
||||
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||
@ -13,12 +14,15 @@ type EditableSortChipProps = {
|
||||
export const EditableSortChip = ({ recordSort }: EditableSortChipProps) => {
|
||||
const { deleteCombinedViewSort } = useDeleteCombinedViewSorts();
|
||||
|
||||
const { removeRecordSort } = useRemoveRecordSort();
|
||||
|
||||
const { upsertCombinedViewSort } = useUpsertCombinedViewSorts();
|
||||
|
||||
const { upsertRecordSort } = useUpsertRecordSort();
|
||||
|
||||
const handleRemoveClick = () => {
|
||||
deleteCombinedViewSort(recordSort.fieldMetadataId);
|
||||
removeRecordSort(recordSort.fieldMetadataId);
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
|
||||
@ -17,6 +17,7 @@ import { useCheckIsSoftDeleteFilter } from '@/object-record/record-filter/hooks/
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { SoftDeleteFilterChip } from '@/views/components/SoftDeleteFilterChip';
|
||||
import { useApplyCurrentViewFiltersToCurrentRecordFilters } from '@/views/hooks/useApplyCurrentViewFiltersToCurrentRecordFilters';
|
||||
import { useApplyCurrentViewSortsToCurrentRecordSorts } from '@/views/hooks/useApplyCurrentViewSortsToCurrentRecordSorts';
|
||||
import { useAreViewFiltersDifferentFromRecordFilters } from '@/views/hooks/useAreViewFiltersDifferentFromRecordFilters';
|
||||
import { useAreViewSortsDifferentFromRecordSorts } from '@/views/hooks/useAreViewSortsDifferentFromRecordSorts';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
@ -163,10 +164,14 @@ export const ViewBarDetails = ({
|
||||
const { applyCurrentViewFiltersToCurrentRecordFilters } =
|
||||
useApplyCurrentViewFiltersToCurrentRecordFilters();
|
||||
|
||||
const { applyCurrentViewSortsToCurrentRecordSorts } =
|
||||
useApplyCurrentViewSortsToCurrentRecordSorts();
|
||||
|
||||
const handleCancelClick = () => {
|
||||
if (isDefined(viewId)) {
|
||||
resetUnsavedViewStates(viewId);
|
||||
applyCurrentViewFiltersToCurrentRecordFilters();
|
||||
applyCurrentViewSortsToCurrentRecordSorts();
|
||||
toggleSoftDeleteFilterState(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,196 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
|
||||
|
||||
import { View } from '@/views/types/View';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
import { mockedViewsData } from '~/testing/mock-data/views';
|
||||
import { useApplyCurrentViewSortsToCurrentRecordSorts } from '../useApplyCurrentViewSortsToCurrentRecordSorts';
|
||||
|
||||
const mockObjectMetadataItemNameSingular = 'company';
|
||||
|
||||
describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
|
||||
const mockObjectMetadataItem = generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === mockObjectMetadataItemNameSingular,
|
||||
);
|
||||
|
||||
if (!isDefined(mockObjectMetadataItem)) {
|
||||
throw new Error(
|
||||
'Missing mock object metadata item with name singular "company"',
|
||||
);
|
||||
}
|
||||
|
||||
const mockFieldMetadataItem = mockObjectMetadataItem.fields.find(
|
||||
(field) => field.name === 'name',
|
||||
);
|
||||
|
||||
if (!isDefined(mockFieldMetadataItem)) {
|
||||
throw new Error('Missing mock field metadata item with type TEXT');
|
||||
}
|
||||
|
||||
const mockViewSort: ViewSort = {
|
||||
__typename: 'ViewSort',
|
||||
id: 'sort-1',
|
||||
fieldMetadataId: mockFieldMetadataItem.id,
|
||||
direction: 'asc',
|
||||
};
|
||||
|
||||
const allCompaniesView = mockedViewsData[0];
|
||||
|
||||
const mockView = {
|
||||
...allCompaniesView,
|
||||
viewSorts: [mockViewSort],
|
||||
} satisfies View;
|
||||
|
||||
it('should apply sorts from current view', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyCurrentViewSortsToCurrentRecordSorts } =
|
||||
useApplyCurrentViewSortsToCurrentRecordSorts();
|
||||
|
||||
const currentSorts = useRecoilComponentValueV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
applyCurrentViewSortsToCurrentRecordSorts,
|
||||
currentSorts,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: 'instanceId',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
mockObjectMetadataItemNameSingular,
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
|
||||
snapshot.set(prefetchViewsState, [mockView]);
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.applyCurrentViewSortsToCurrentRecordSorts();
|
||||
});
|
||||
|
||||
expect(result.current.currentSorts).toEqual([
|
||||
{
|
||||
id: mockViewSort.id,
|
||||
fieldMetadataId: mockViewSort.fieldMetadataId,
|
||||
direction: mockViewSort.direction,
|
||||
definition: {
|
||||
fieldMetadataId: mockViewSort.fieldMetadataId,
|
||||
iconName: mockFieldMetadataItem.icon ?? '',
|
||||
label: mockFieldMetadataItem.label,
|
||||
},
|
||||
} satisfies RecordSort,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not apply sorts when current view is not found', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyCurrentViewSortsToCurrentRecordSorts } =
|
||||
useApplyCurrentViewSortsToCurrentRecordSorts();
|
||||
|
||||
const currentSorts = useRecoilComponentValueV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
applyCurrentViewSortsToCurrentRecordSorts,
|
||||
currentSorts,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: 'instanceId',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
mockObjectMetadataItemNameSingular,
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
|
||||
snapshot.set(prefetchViewsState, []);
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.applyCurrentViewSortsToCurrentRecordSorts();
|
||||
});
|
||||
|
||||
expect(result.current.currentSorts).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle view with empty sorts', () => {
|
||||
const viewWithNoSorts = {
|
||||
...mockView,
|
||||
viewSorts: [],
|
||||
};
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyCurrentViewSortsToCurrentRecordSorts } =
|
||||
useApplyCurrentViewSortsToCurrentRecordSorts();
|
||||
|
||||
const currentSorts = useRecoilComponentValueV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
return {
|
||||
applyCurrentViewSortsToCurrentRecordSorts,
|
||||
currentSorts,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: 'instanceId',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
mockObjectMetadataItemNameSingular,
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
|
||||
snapshot.set(prefetchViewsState, [viewWithNoSorts]);
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.applyCurrentViewSortsToCurrentRecordSorts();
|
||||
});
|
||||
|
||||
expect(result.current.currentSorts).toEqual([]);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,110 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
import { useApplyViewSortsToCurrentRecordSorts } from '../useApplyViewSortsToCurrentRecordSorts';
|
||||
|
||||
const mockObjectMetadataItemNameSingular = 'company';
|
||||
|
||||
describe('useApplyViewSortsToCurrentRecordSorts', () => {
|
||||
const mockObjectMetadataItem = generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === mockObjectMetadataItemNameSingular,
|
||||
);
|
||||
|
||||
if (!isDefined(mockObjectMetadataItem)) {
|
||||
throw new Error(
|
||||
`Missing mock object metadata item with name singular ${mockObjectMetadataItemNameSingular}`,
|
||||
);
|
||||
}
|
||||
|
||||
const mockFieldMetadataItem = mockObjectMetadataItem.fields.find(
|
||||
(field) => field.name === 'name',
|
||||
);
|
||||
|
||||
if (!isDefined(mockFieldMetadataItem)) {
|
||||
throw new Error(`Missing mock field metadata Name`);
|
||||
}
|
||||
|
||||
const mockViewSort: ViewSort = {
|
||||
__typename: 'ViewSort',
|
||||
id: 'sort-1',
|
||||
fieldMetadataId: mockFieldMetadataItem.id,
|
||||
direction: 'asc',
|
||||
};
|
||||
|
||||
it('should apply view sorts to current record sorts', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyViewSortsToCurrentRecordSorts } =
|
||||
useApplyViewSortsToCurrentRecordSorts();
|
||||
|
||||
const currentSorts = useRecoilComponentValueV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
return { applyViewSortsToCurrentRecordSorts, currentSorts };
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: 'instanceId',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
mockObjectMetadataItemNameSingular,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.applyViewSortsToCurrentRecordSorts([mockViewSort]);
|
||||
});
|
||||
|
||||
expect(result.current.currentSorts).toEqual([
|
||||
{
|
||||
id: mockViewSort.id,
|
||||
fieldMetadataId: mockViewSort.fieldMetadataId,
|
||||
direction: mockViewSort.direction,
|
||||
definition: {
|
||||
fieldMetadataId: mockViewSort.fieldMetadataId,
|
||||
label: mockFieldMetadataItem.label,
|
||||
iconName: mockFieldMetadataItem.icon ?? '',
|
||||
},
|
||||
} satisfies RecordSort,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle empty view sorts array', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyViewSortsToCurrentRecordSorts } =
|
||||
useApplyViewSortsToCurrentRecordSorts();
|
||||
|
||||
const currentSorts = useRecoilComponentValueV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
return { applyViewSortsToCurrentRecordSorts, currentSorts };
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
apolloMocks: [],
|
||||
componentInstanceId: 'instanceId',
|
||||
contextStoreCurrentObjectMetadataNameSingular:
|
||||
mockObjectMetadataItemNameSingular,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.applyViewSortsToCurrentRecordSorts([]);
|
||||
});
|
||||
|
||||
expect(result.current.currentSorts).toEqual([]);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,46 @@
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { formatFieldMetadataItemsAsSortDefinitions } from '@/object-metadata/utils/formatFieldMetadataItemsAsSortDefinitions';
|
||||
import { useSortableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-sort/hooks/useSortableFieldMetadataItemsInRecordIndexContext';
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
export const useApplyCurrentViewSortsToCurrentRecordSorts = () => {
|
||||
const currentViewId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
|
||||
const currentView = useRecoilValue(
|
||||
prefetchViewFromViewIdFamilySelector({
|
||||
viewId: currentViewId ?? '',
|
||||
}),
|
||||
);
|
||||
|
||||
const setCurrentRecordSorts = useSetRecoilComponentStateV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
const { sortableFieldMetadataItems } =
|
||||
useSortableFieldMetadataItemsInRecordIndexContext();
|
||||
|
||||
const applyCurrentViewSortsToCurrentRecordSorts = () => {
|
||||
const sortDefinitions = formatFieldMetadataItemsAsSortDefinitions({
|
||||
fields: sortableFieldMetadataItems,
|
||||
});
|
||||
|
||||
if (isDefined(currentView)) {
|
||||
setCurrentRecordSorts(
|
||||
mapViewSortsToSorts(currentView.viewSorts, sortDefinitions),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
applyCurrentViewSortsToCurrentRecordSorts,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
import { formatFieldMetadataItemsAsSortDefinitions } from '@/object-metadata/utils/formatFieldMetadataItemsAsSortDefinitions';
|
||||
import { useSortableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-sort/hooks/useSortableFieldMetadataItemsInRecordIndexContext';
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
||||
|
||||
export const useApplyViewSortsToCurrentRecordSorts = () => {
|
||||
const setCurrentRecordSorts = useSetRecoilComponentStateV2(
|
||||
currentRecordSortsComponentState,
|
||||
);
|
||||
|
||||
const { sortableFieldMetadataItems } =
|
||||
useSortableFieldMetadataItemsInRecordIndexContext();
|
||||
|
||||
const applyViewSortsToCurrentRecordSorts = (viewSorts: ViewSort[]) => {
|
||||
const sortDefinitions = formatFieldMetadataItemsAsSortDefinitions({
|
||||
fields: sortableFieldMetadataItems,
|
||||
});
|
||||
|
||||
const recordSortsToApply = mapViewSortsToSorts(viewSorts, sortDefinitions);
|
||||
|
||||
setCurrentRecordSorts(recordSortsToApply);
|
||||
};
|
||||
|
||||
return {
|
||||
applyViewSortsToCurrentRecordSorts,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user