Skip to content

Commit

Permalink
refactor: Clean up option list typing (#14429)
Browse files Browse the repository at this point in the history
Co-authored-by: Erling Hauan <[email protected]>
  • Loading branch information
TomasEng and ErlingHauan authored Jan 17, 2025
1 parent 81889bc commit 5dda0fd
Show file tree
Hide file tree
Showing 32 changed files with 227 additions and 247 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import type { UserEvent } from '@testing-library/user-event';
import userEvent from '@testing-library/user-event';
import type { CodeList } from '@studio/components';
import type { ServicesContextProps } from 'app-shared/contexts/ServicesContext';
import type { OptionsListsResponse } from 'app-shared/types/api/OptionsLists';
import type { OptionListData } from 'app-shared/types/OptionList';

const uploadCodeListButtonTextMock = 'Upload Code List';
const updateCodeListButtonTextMock = 'Update Code List';
const updateCodeListIdButtonTextMock = 'Update Code List Id';
const codeListNameMock = 'codeListNameMock';
const newCodeListNameMock = 'newCodeListNameMock';
const codeListMock: CodeList = [{ value: '', label: '' }];
const optionListsDataMock: OptionsListsResponse = [{ title: codeListNameMock, data: codeListMock }];
const optionListsDataMock: OptionListData[] = [{ title: codeListNameMock, data: codeListMock }];
jest.mock(
'../../../libs/studio-content-library/src/ContentLibrary/LibraryBody/pages/CodeListPage',
() => ({
Expand Down Expand Up @@ -147,7 +147,7 @@ const goToLibraryPage = async (user: UserEvent, libraryPage: string) => {
type renderAppContentLibraryProps = {
queries?: Partial<ServicesContextProps>;
shouldPutDataOnCache?: boolean;
optionListsData?: OptionsListsResponse;
optionListsData?: OptionListData[];
};

const renderAppContentLibrary = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ResourceContentLibraryImpl } from '@studio/content-library';
import React from 'react';
import { useOptionListsQuery, useOptionListsReferencesQuery } from 'app-shared/hooks/queries';
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
import { convertOptionsListsDataToCodeListsData } from './utils/convertOptionsListsDataToCodeListsData';
import { mapToCodeListDataList } from './utils/mapToCodeListDataList';
import { StudioPageSpinner } from '@studio/components';
import { useTranslation } from 'react-i18next';
import type { ApiError } from 'app-shared/types/api/ApiError';
Expand All @@ -16,7 +16,7 @@ import {
useUpdateOptionListIdMutation,
useDeleteOptionListMutation,
} from 'app-shared/hooks/mutations';
import { mapToCodeListsUsage } from './utils/mapToCodeListsUsage';
import { mapToCodeListUsages } from './utils/mapToCodeListUsages';

export function AppContentLibrary(): React.ReactElement {
const { org, app } = useStudioEnvironmentParams();
Expand All @@ -31,15 +31,15 @@ export function AppContentLibrary(): React.ReactElement {
});
const { mutate: updateOptionList } = useUpdateOptionListMutation(org, app);
const { mutate: updateOptionListId } = useUpdateOptionListIdMutation(org, app);
const { data: optionListsUsages, isPending: optionListsUsageIsPending } =
const { data: optionListUsages, isPending: optionListsUsageIsPending } =
useOptionListsReferencesQuery(org, app);

if (optionListsDataPending || optionListsUsageIsPending)
return <StudioPageSpinner spinnerTitle={t('general.loading')}></StudioPageSpinner>;

const codeListsData = convertOptionsListsDataToCodeListsData(optionListsData);
const codeListsData = mapToCodeListDataList(optionListsData);

const codeListsUsages: CodeListReference[] = mapToCodeListsUsage({ optionListsUsages });
const codeListsUsages: CodeListReference[] = mapToCodeListUsages(optionListUsages);

const handleUpdateCodeListId = (optionListId: string, newOptionListId: string) => {
updateOptionListId({ optionListId, newOptionListId });
Expand All @@ -59,7 +59,7 @@ export function AppContentLibrary(): React.ReactElement {
};

const handleUpdate = ({ title, codeList }: CodeListWithMetadata) => {
updateOptionList({ optionListId: title, optionsList: codeList });
updateOptionList({ optionListId: title, optionList: codeList });
};

const { getContentResourceLibrary } = new ResourceContentLibraryImpl({
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { CodeListData } from '@studio/content-library';
import { convertOptionsListsDataToCodeListsData } from './convertOptionsListsDataToCodeListsData';
import type { OptionsListsResponse } from 'app-shared/types/api/OptionsLists';
import { mapToCodeListDataList } from './mapToCodeListDataList';
import type { OptionListData } from 'app-shared/types/OptionList';

describe('convertOptionsListsDataToCodeListsData', () => {
describe('mapToCodeListDataList', () => {
it('converts option lists data to code lists data correctly', () => {
const optionListId: string = 'optionListId';
const optionListsData: OptionsListsResponse = [
const optionListDataList: OptionListData[] = [
{
title: optionListId,
data: [
Expand All @@ -15,7 +15,7 @@ describe('convertOptionsListsDataToCodeListsData', () => {
hasError: false,
},
];
const result: CodeListData[] = convertOptionsListsDataToCodeListsData(optionListsData);
const result: CodeListData[] = mapToCodeListDataList(optionListDataList);
expect(result).toEqual([
{
title: optionListId,
Expand All @@ -30,20 +30,20 @@ describe('convertOptionsListsDataToCodeListsData', () => {

it('sets hasError to true in result when optionListsResponse returns an option list with error', () => {
const optionListId: string = 'optionListId';
const optionListsData: OptionsListsResponse = [
const optionListDataList: OptionListData[] = [
{
title: optionListId,
data: null,
hasError: true,
},
];
const result: CodeListData[] = convertOptionsListsDataToCodeListsData(optionListsData);
const result: CodeListData[] = mapToCodeListDataList(optionListDataList);
expect(result).toEqual([{ title: optionListId, data: null, hasError: true }]);
});

it('returns a result with empty code list data array when the input option list data is empty', () => {
const optionListsData: OptionsListsResponse = [];
const result: CodeListData[] = convertOptionsListsDataToCodeListsData(optionListsData);
const optionListDataList: OptionListData[] = [];
const result: CodeListData[] = mapToCodeListDataList(optionListDataList);
expect(result).toEqual([]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { OptionListData } from 'app-shared/types/OptionList';
import type { CodeListData } from '@studio/content-library';

export const mapToCodeListDataList = (optionListDataList: OptionListData[]): CodeListData[] =>
optionListDataList.map(convertOptionListDataToCodeListData);

const convertOptionListDataToCodeListData = (optionListData: OptionListData): CodeListData => ({
title: optionListData.title,
data: optionListData.data,
hasError: optionListData.hasError,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { CodeListIdSource } from '@studio/content-library';
import { mapToCodeListUsages } from './mapToCodeListUsages';
import type { OptionListReferences } from 'app-shared/types/OptionListReferences';

const optionListId: string = 'optionListId';
const optionListIdSources: CodeListIdSource[] = [
{
layoutSetId: 'layoutSetId',
layoutName: 'layoutName',
componentIds: ['componentId1', 'componentId2'],
},
];
const optionListUsages: OptionListReferences = [
{
optionListId,
optionListIdSources,
},
];

describe('mapToCodeListUsages', () => {
it('maps optionListsUsages to codeListUsages', () => {
const codeListUsages = mapToCodeListUsages(optionListUsages);
expect(codeListUsages).toEqual([
{
codeListId: optionListId,
codeListIdSources: optionListIdSources,
},
]);
});

it('maps undefined optionListUsages to empty array', () => {
const codeListUsages = mapToCodeListUsages(undefined);
expect(codeListUsages).toEqual([]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { OptionListReferences } from 'app-shared/types/OptionListReferences';
import type { CodeListReference } from '@studio/content-library';

export const mapToCodeListUsages = (
optionListUsages: OptionListReferences,
): CodeListReference[] => {
if (!optionListUsages) return [];
return optionListUsages.map((optionListsUsage) => ({
codeListId: optionListsUsage.optionListId,
codeListIdSources: optionListsUsage.optionListIdSources,
}));
};

This file was deleted.

This file was deleted.

10 changes: 6 additions & 4 deletions frontend/packages/shared/src/api/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ import type { Policy } from 'app-shared/types/Policy';
import type { RepoDiffResponse } from 'app-shared/types/api/RepoDiffResponse';
import type { ExternalImageUrlValidationResponse } from 'app-shared/types/api/ExternalImageUrlValidationResponse';
import type { MaskinportenScopes } from 'app-shared/types/MaskinportenScope';
import type { OptionListsReferences, OptionsList, OptionsListsResponse } from 'app-shared/types/api/OptionsLists';
import type { OptionList } from 'app-shared/types/OptionList';
import type { OptionListsResponse } from 'app-shared/types/api/OptionListsResponse';
import type { OptionListReferences } from 'app-shared/types/OptionListReferences';
import type { LayoutSetsModel } from '../types/api/dto/LayoutSetsModel';
import type { AccessPackageResource, PolicyAccessPackageAreaGroup } from 'app-shared/types/PolicyAccessPackages';
import type { DataType } from '../types/DataType';
Expand Down Expand Up @@ -121,9 +123,9 @@ export const getImageFileNames = (owner: string, app: string) => get<string[]>(g
export const getLayoutNames = (owner: string, app: string) => get<string[]>(layoutNamesPath(owner, app));
export const getLayoutSets = (owner: string, app: string) => get<LayoutSets>(layoutSetsPath(owner, app));
export const getLayoutSetsExtended = (owner: string, app: string) => get<LayoutSetsModel>(layoutSetsPath(owner, app) + '/extended');
export const getOptionList = (owner: string, app: string, optionsListId: string) => get<OptionsList>(optionListPath(owner, app, optionsListId));
export const getOptionLists = (owner: string, app: string) => get<OptionsListsResponse>(optionListsPath(owner, app));
export const getOptionListsReferences = (owner: string, app: string) => get<OptionListsReferences>(optionListReferencesPath(owner, app));
export const getOptionList = (owner: string, app: string, optionsListId: string) => get<OptionList>(optionListPath(owner, app, optionsListId));
export const getOptionLists = (owner: string, app: string) => get<OptionListsResponse>(optionListsPath(owner, app));
export const getOptionListsReferences = (owner: string, app: string) => get<OptionListReferences>(optionListReferencesPath(owner, app));
export const getOptionListIds = (owner: string, app: string) => get<string[]>(optionListIdsPath(owner, app));
export const getOrgList = () => get<OrgList>(orgListUrl());
export const getOrganizations = () => get<Organization[]>(orgsListPath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useUpdateOptionListIdMutation } from './useUpdateOptionListIdMutation';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { QueryKey } from 'app-shared/types/QueryKey';
import type { Option } from 'app-shared/types/Option';
import type { OptionsListsResponse } from 'app-shared/types/api/OptionsLists';
import type { OptionListsResponse } from 'app-shared/types/api/OptionListsResponse';

// Test data:
const optionListId: string = 'optionListId';
Expand Down Expand Up @@ -38,7 +38,7 @@ describe('useUpdateOptionListIdMutation', () => {
const optionListC = 'optionListC';
const optionListZ = 'optionListZ';
const queryClient = createQueryClientMock();
const oldData: OptionsListsResponse = [
const oldData: OptionListsResponse = [
{ title: optionListA, data: optionListMock },
{ title: optionListB, data: optionListMock },
{ title: optionListZ, data: optionListMock },
Expand All @@ -52,7 +52,7 @@ describe('useUpdateOptionListIdMutation', () => {
optionListId: optionListA,
newOptionListId: optionListC,
});
const cacheData: OptionsListsResponse = queryClient.getQueryData([
const cacheData: OptionListsResponse = queryClient.getQueryData([
QueryKey.OptionLists,
org,
app,
Expand All @@ -65,7 +65,7 @@ describe('useUpdateOptionListIdMutation', () => {
test('Invalidates the optionListIds query cache', async () => {
const queryClient = createQueryClientMock();
const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
const oldData: OptionsListsResponse = [
const oldData: OptionListsResponse = [
{ title: 'firstOptionList', data: optionListMock },
{ title: 'optionListId', data: optionListMock },
{ title: 'lastOptionList', data: optionListMock },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { QueryKey } from 'app-shared/types/QueryKey';
import type { OptionsListsResponse } from 'app-shared/types/api/OptionsLists';
import type { OptionListsResponse } from 'app-shared/types/api/OptionListsResponse';
import { useQueryClient, useMutation } from '@tanstack/react-query';
import { useServicesContext } from 'app-shared/contexts/ServicesContext';
import { ArrayUtils } from '@studio/pure-functions';
Expand All @@ -21,7 +21,7 @@ export const useUpdateOptionListIdMutation = (org: string, app: string) => {
}));
},
onSuccess: ({ optionListId, newOptionListId }) => {
const oldData: OptionsListsResponse = queryClient.getQueryData([
const oldData: OptionListsResponse = queryClient.getQueryData([
QueryKey.OptionLists,
org,
app,
Expand All @@ -38,10 +38,10 @@ export const useUpdateOptionListIdMutation = (org: string, app: string) => {
const changeIdAndSortCacheData = (
oldId: string,
newId: string,
oldData: OptionsListsResponse,
): OptionsListsResponse => {
oldData: OptionListsResponse,
): OptionListsResponse => {
const oldOptionList = oldData.find((optionList) => optionList.title === oldId);
const newOptionLists: OptionsListsResponse = ArrayUtils.replaceByPredicate(
const newOptionLists: OptionListsResponse = ArrayUtils.replaceByPredicate(
oldData,
(optionList) => optionList.title === oldId,
{ ...oldOptionList, title: newId },
Expand Down
Loading

0 comments on commit 5dda0fd

Please sign in to comment.