diff --git a/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.test.ts b/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.test.ts index a797b0cfbbb..3bc5c19ce33 100644 --- a/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.test.ts +++ b/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.test.ts @@ -81,4 +81,30 @@ describe('objectUtils', () => { expect(ObjectUtils.flattenObjectValues(object)).toEqual(['value1', 'value2', 'value3']); }); }); + + describe('sortEntriesInObjectByKeys', () => { + it('Sorts all entries in an object by its keys', () => { + const unSortedObject = { b: 'b', a: 'a', c: 'c' }; + const sortedObject = ObjectUtils.sortEntriesInObjectByKeys(unSortedObject); + const sortedObjectKeys = Object.keys(sortedObject); + expect(sortedObjectKeys[0]).toBe('a'); + expect(sortedObjectKeys[1]).toBe('b'); + expect(sortedObjectKeys[2]).toBe('c'); + }); + + it('Returns same order if entries in is already sorted', () => { + const unSortedObject = { a: 'a', b: 'b', c: 'c' }; + const sortedObject = ObjectUtils.sortEntriesInObjectByKeys(unSortedObject); + const sortedObjectKeys = Object.keys(sortedObject); + expect(sortedObjectKeys[0]).toBe('a'); + expect(sortedObjectKeys[1]).toBe('b'); + expect(sortedObjectKeys[2]).toBe('c'); + }); + + it('Returns empty list if entries to sort is empty', () => { + const emptyObject = {}; + const sortedObject = ObjectUtils.sortEntriesInObjectByKeys(emptyObject); + expect(sortedObject).toEqual({}); + }); + }); }); diff --git a/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.ts b/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.ts index e911317a8f5..9f15a9743de 100644 --- a/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.ts +++ b/frontend/libs/studio-pure-functions/src/ObjectUtils/ObjectUtils.ts @@ -44,4 +44,14 @@ export class ObjectUtils { }) .flat(); }; + + /** + * Sorts all entries in an object by its keys. + * @param object The object to sort. + * @returns A new object with the entries sorted by key. + */ + static sortEntriesInObjectByKeys = (object: T): T => + Object.fromEntries( + Object.entries(object).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)), + ) as T; } diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts index 4d00f79aaf0..04d4a9551fd 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.test.ts @@ -33,6 +33,10 @@ describe('useUpdateOptionListIdMutation', () => { }); test('Sets the option lists cache with new id in correct alphabetical order', async () => { + const optionListA = 'optionListA'; + const optionListB = 'optionListB'; + const optionListC = 'optionListC'; + const optionListZ = 'optionListZ'; const queryClient = createQueryClientMock(); const oldData: OptionsLists = { optionListA: optionListMock, @@ -45,15 +49,14 @@ describe('useUpdateOptionListIdMutation', () => { { queryClient }, ).result; await renderUpdateOptionListMutationResult.current.mutateAsync({ - optionListId: 'optionListA', - newOptionListId: 'optionListC', + optionListId: optionListA, + newOptionListId: optionListC, }); const cacheData = queryClient.getQueryData([QueryKey.OptionLists, org, app]); - expect(cacheData).toEqual({ - optionListB: optionListMock, - optionListC: optionListMock, - optionListZ: optionListMock, - }); + const cacheDataKeys = Object.keys(cacheData); + expect(cacheDataKeys[0]).toEqual(optionListB); + expect(cacheDataKeys[1]).toEqual(optionListC); + expect(cacheDataKeys[2]).toEqual(optionListZ); }); test('Invalidates the optionListIds query cache', async () => { diff --git a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts index b4279c97429..d56dddb6c51 100644 --- a/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts +++ b/frontend/packages/shared/src/hooks/mutations/useUpdateOptionListIdMutation.ts @@ -2,6 +2,7 @@ import { QueryKey } from 'app-shared/types/QueryKey'; import type { OptionsLists } from 'app-shared/types/api/OptionsLists'; import { useQueryClient, useMutation } from '@tanstack/react-query'; import { useServicesContext } from 'app-shared/contexts/ServicesContext'; +import { ObjectUtils } from '@studio/pure-functions'; export interface UpdateOptionListIdMutationArgs { optionListId: string; @@ -21,14 +22,14 @@ export const useUpdateOptionListIdMutation = (org: string, app: string) => { }, onSuccess: ({ optionListId, newOptionListId }) => { const oldData: OptionsLists = queryClient.getQueryData([QueryKey.OptionLists, org, app]); - const ascSortedData = ChangeIdAndSortCacheData(optionListId, newOptionListId, oldData); + const ascSortedData = changeIdAndSortCacheData(optionListId, newOptionListId, oldData); queryClient.setQueryData([QueryKey.OptionLists, org, app], ascSortedData); queryClient.invalidateQueries({ queryKey: [QueryKey.OptionListIds, org, app] }); }, }); }; -const ChangeIdAndSortCacheData = ( +const changeIdAndSortCacheData = ( oldId: string, newId: string, oldData: OptionsLists, @@ -36,7 +37,5 @@ const ChangeIdAndSortCacheData = ( const newData = { ...oldData }; delete newData[oldId]; newData[newId] = oldData[oldId]; - return Object.fromEntries( - Object.entries(newData).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)), - ); + return ObjectUtils.sortEntriesInObjectByKeys(newData); };