Fix sort direction toggle when clicking on existing sort (#17046)

Closes #17032

  Summary

When a sort is already applied to a column, clicking "Sort" from the
column header dropdown now toggles the sort direction (ASC → DESC or
DESC → ASC) instead of doing nothing.

  Problem

Previously, clicking "Sort" on a column that already had a sort applied
would always try to create a new sort with ASC direction. Since the
upsertRecordSort function updates an existing sort with the same field,
this effectively did nothing when the sort was already ASC—which felt
unintuitive.

  Solution

  Modified useHandleToggleColumnSort to:
  - Check if a sort already exists for the clicked field
  - If it exists, toggle the direction
- If it doesn't exist, create a new sort with ASC direction (existing
behavior)

---

Contribution by Gittensor, see my contribution statistics at
https://gittensor.io/miners/details?githubId=132382032
This commit is contained in:
Match
2026-01-10 06:04:26 -08:00
committed by GitHub
parent d4d5f57347
commit 9e22c74b2d
@@ -1,9 +1,11 @@
import { useCallback } from 'react';
import { useColumnDefinitionsFromObjectMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromObjectMetadata';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { type RecordSort } from '@/object-record/record-sort/types/RecordSort';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { ViewSortDirection } from '~/generated/graphql';
@@ -24,24 +26,42 @@ export const useHandleToggleColumnSort = ({
const { upsertRecordSort } = useUpsertRecordSort();
const handleToggleColumnSort = useCallback(
async (fieldMetadataId: string) => {
const correspondingColumnDefinition = columnDefinitions.find(
(columnDefinition) =>
columnDefinition.fieldMetadataId === fieldMetadataId,
);
const currentRecordSortsCallbackState = useRecoilComponentCallbackState(
currentRecordSortsComponentState,
);
if (!isDefined(correspondingColumnDefinition)) return;
const handleToggleColumnSort = useRecoilCallback(
({ snapshot }) =>
(fieldMetadataId: string) => {
const correspondingColumnDefinition = columnDefinitions.find(
(columnDefinition) =>
columnDefinition.fieldMetadataId === fieldMetadataId,
);
const newSort: RecordSort = {
id: v4(),
fieldMetadataId,
direction: ViewSortDirection.ASC,
};
if (!isDefined(correspondingColumnDefinition)) return;
upsertRecordSort(newSort);
},
[columnDefinitions, upsertRecordSort],
const currentRecordSorts = getSnapshotValue(
snapshot,
currentRecordSortsCallbackState,
);
const existingSort = currentRecordSorts.find(
(sort) => sort.fieldMetadataId === fieldMetadataId,
);
const newSort: RecordSort = {
id: existingSort?.id ?? v4(),
fieldMetadataId,
direction: existingSort
? existingSort.direction === ViewSortDirection.ASC
? ViewSortDirection.DESC
: ViewSortDirection.ASC
: ViewSortDirection.ASC,
};
upsertRecordSort(newSort);
},
[columnDefinitions, currentRecordSortsCallbackState, upsertRecordSort],
);
return handleToggleColumnSort;