Skip to content

Commit

Permalink
Merge branch 'bug/14620-sist-endret-field-is-misleading-for-resource-…
Browse files Browse the repository at this point in the history
…not-checked-in-to-gitea' of https://github.com/Altinn/altinn-studio into bug/14620-sist-endret-field-is-misleading-for-resource-not-checked-in-to-gitea
  • Loading branch information
mgunnerud committed Feb 10, 2025
2 parents 11f540a + 6fea6af commit e76b1b3
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
codeListDataList,
} from '../../../../test-data/codeListDataList';
import { ArrayUtils } from '@studio/pure-functions';
import { label1ResourceNb, textResources } from '../../../../test-data/textResources';
import type { TextResourceWithLanguage } from '../../../../types/TextResourceWithLanguage';

const onDeleteCodeList = jest.fn();
const onUpdateCodeListId = jest.fn();
Expand Down Expand Up @@ -155,6 +157,31 @@ describe('CodeListPage', () => {
expect(onUploadCodeList).toHaveBeenCalledTimes(1);
expect(onUploadCodeList).toHaveBeenCalledWith(expect.any(Object));
});

it('Renders with text resources in the input fields when given', async () => {
const user = userEvent.setup();
renderCodeListPage({ textResources, codeListsData: codeListDataList });
const labelField = await openAndGetFirstLabelField(user, codeList1Data.title);
expect(labelField).toHaveValue(label1ResourceNb.value);
});

it('Calls onUpdateTextResource with the new text resource and the default language when a text resource is changed', async () => {
const user = userEvent.setup();
const onUpdateTextResource = jest.fn();
const newLabel = 'Ny ledetekst';

renderCodeListPage({ textResources, codeListsData: codeListDataList, onUpdateTextResource });
const labelField = await openAndGetFirstLabelField(user, codeList1Data.title);
await user.type(labelField, newLabel);

const expectedLanguage = 'nb';
const expectedObject: TextResourceWithLanguage = {
language: expectedLanguage,
textResource: { ...label1ResourceNb, value: newLabel },
};
expect(onUpdateTextResource).toHaveBeenCalledTimes(newLabel.length);
expect(onUpdateTextResource).toHaveBeenLastCalledWith(expectedObject);
});
});

const uploadCodeList = async (user: UserEvent, fileName: string): Promise<void> => {
Expand All @@ -165,6 +192,16 @@ const uploadCodeList = async (user: UserEvent, fileName: string): Promise<void>
await user.upload(fileUploaderButton, file);
};

const openAndGetFirstLabelField = async (
user: UserEvent,
codeListTitle: string,
): Promise<HTMLElement> => {
await user.click(getCodeListHeading(codeListTitle));
const accordion = getCodeListAccordion(codeListTitle);
const labelFieldLabel = textMock('code_list_editor.text_resource.label.value', { number: 1 });
return within(accordion).getByRole('textbox', { name: labelFieldLabel });
};

const getCodeListAccordion = (codeListTitle: string): HTMLElement =>
// The following code accesses a node directly with parentElement. This is not recommended, hence the Eslint rule, but there is no other way to access the accordion element.
// Todo: When we upgrade The Design System, we should use the new `Details` component with `getByRole('group')` instead. https://github.com/Altinn/altinn-studio/issues/14577
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import classes from './CodeListPage.module.css';
import { ArrayUtils, FileNameUtils } from '@studio/pure-functions';
import type { CodeListReference } from './types/CodeListReference';
import { filterCodeLists } from './utils/codeListPageUtils';
import type { TextResourceWithLanguage } from '../../../../types/TextResourceWithLanguage';
import type { TextResources } from '../../../../types/TextResources';

export type CodeListWithMetadata = {
codeList: CodeList;
Expand All @@ -26,17 +28,21 @@ export type CodeListPageProps = {
onDeleteCodeList: (codeListId: string) => void;
onUpdateCodeListId: (codeListId: string, newCodeListId: string) => void;
onUpdateCodeList: (updatedCodeList: CodeListWithMetadata) => void;
onUpdateTextResource?: (textResource: TextResourceWithLanguage) => void;
onUploadCodeList: (uploadedCodeList: File) => void;
codeListsUsages: CodeListReference[];
textResources?: TextResources;
};

export function CodeListPage({
codeListsData,
onDeleteCodeList,
onUpdateCodeListId,
onUpdateCodeList,
onUpdateTextResource,
onUploadCodeList,
codeListsUsages,
textResources,
}: CodeListPageProps): React.ReactElement {
const { t } = useTranslation();
const [searchString, setSearchString] = useState<string>('');
Expand Down Expand Up @@ -74,9 +80,11 @@ export function CodeListPage({
onDeleteCodeList={onDeleteCodeList}
onUpdateCodeListId={handleUpdateCodeListId}
onUpdateCodeList={onUpdateCodeList}
onUpdateTextResource={onUpdateTextResource}
codeListInEditMode={codeListInEditMode}
codeListNames={codeListTitles}
codeListsUsages={codeListsUsages}
textResources={textResources}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ import { Trans, useTranslation } from 'react-i18next';
import type { CodeListIdSource, CodeListReference } from '../types/CodeListReference';
import classes from './CodeLists.module.css';
import { getCodeListSourcesById, getCodeListUsageCount } from '../utils/codeListPageUtils';
import type { TextResourceWithLanguage } from '../../../../../types/TextResourceWithLanguage';
import type { TextResources } from '../../../../../types/TextResources';

export type CodeListsProps = {
codeListsData: CodeListData[];
onDeleteCodeList: (codeListId: string) => void;
onUpdateCodeListId: (codeListId: string, newCodeListId: string) => void;
onUpdateCodeList: (updatedCodeList: CodeListWithMetadata) => void;
onUpdateTextResource?: (textResource: TextResourceWithLanguage) => void;
codeListInEditMode: string | undefined;
codeListNames: string[];
codeListsUsages: CodeListReference[];
textResources?: TextResources;
};

export function CodeLists({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
StudioCodeListEditor,
StudioToggleableTextfield,
} from '@studio/components';
import React from 'react';
import React, { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import type { CodeListWithMetadata } from '../../CodeListPage';
import { useCodeListEditorTexts } from '../../hooks/useCodeListEditorTexts';
Expand All @@ -16,28 +16,43 @@ import { useInputCodeListNameErrorMessage } from '../../hooks/useInputCodeListNa
import classes from './EditCodeList.module.css';
import type { CodeListIdSource } from '../../types/CodeListReference';
import { CodeListUsages } from './CodeListUsages/CodeListUsages';
import type { TextResources } from '../../../../../../types/TextResources';
import type { TextResource } from '../../../../../../types/TextResource';
import type { TextResourceWithLanguage } from '../../../../../../types/TextResourceWithLanguage';
import { createTextResourceWithLanguage, getTextResourcesForLanguage } from './utils';

export type EditCodeListProps = {
codeList: CodeList;
codeListTitle: string;
onDeleteCodeList: (codeListId: string) => void;
onUpdateCodeListId: (codeListId: string, newCodeListId: string) => void;
onUpdateCodeList: (updatedCodeList: CodeListWithMetadata) => void;
onUpdateTextResource?: (textResource: TextResourceWithLanguage) => void;
codeListNames: string[];
codeListSources: CodeListIdSource[];
textResources?: TextResources;
};

const language: string = 'nb'; // Todo: Let the user choose the language: https://github.com/Altinn/altinn-studio/issues/14572

export function EditCodeList({
codeList,
codeListTitle,
onDeleteCodeList,
onUpdateCodeListId,
onUpdateCodeList,
onUpdateTextResource,
codeListNames,
codeListSources,
textResources,
}: EditCodeListProps): React.ReactElement {
const editorTexts: CodeListEditorTexts = useCodeListEditorTexts();

const textResourcesForLanguage = useMemo(
() => getTextResourcesForLanguage(language, textResources),
[textResources],
);

const handleCodeListChange = (updatedCodeList: CodeList): void => {
const updatedCodeListWithMetadata = updateCodeListWithMetadata(
{ title: codeListTitle, codeList: codeList },
Expand All @@ -48,6 +63,14 @@ export function EditCodeList({

const handleDeleteCodeList = (): void => onDeleteCodeList(codeListTitle);

const handleChangeTextResource = useCallback(
(textResource: TextResource) => {
const updatedTextResource = createTextResourceWithLanguage(language, textResource);
onUpdateTextResource?.(updatedTextResource);
},
[onUpdateTextResource],
);

const codeListHasUsages = codeListSources.length > 0;
const isCodeListEditable = codeListSources.length === 0;

Expand All @@ -63,7 +86,9 @@ export function EditCodeList({
codeList={codeList}
onAddOrDeleteItem={handleCodeListChange}
onBlurAny={handleCodeListChange}
onChangeTextResource={handleChangeTextResource}
texts={editorTexts}
textResources={textResourcesForLanguage}
/>
<CodeListButtons
codeListHasUsages={codeListHasUsages}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
label1ResourceNb,
textResources,
textResourcesNb,
} from '../../../../../../test-data/textResources';
import { createTextResourceWithLanguage, getTextResourcesForLanguage } from './utils';
import type { TextResourceWithLanguage } from '../../../../../../types/TextResourceWithLanguage';

describe('utils', () => {
describe('getTextResourcesForLanguage', () => {
it('Returns the list of text resources for the given language', () => {
expect(getTextResourcesForLanguage('nb', textResources)).toEqual(textResourcesNb);
});

it('Returns undefined when the language does not exist', () => {
expect(getTextResourcesForLanguage('eo', textResources)).toBeUndefined();
});

it('Returns undefined when the textResources parameter is undefined', () => {
expect(getTextResourcesForLanguage('nb', undefined)).toBeUndefined();
});
});

describe('createTextResourceWithLanguage', () => {
it('Creates a TextResourceWithLanguage object from the parameters', () => {
const language = 'nb';
const textResource = label1ResourceNb;
const expectedResult: TextResourceWithLanguage = { language, textResource };
expect(createTextResourceWithLanguage(language, textResource)).toEqual(expectedResult);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { TextResource } from '../../../../../../types/TextResource';
import type { TextResources } from '../../../../../../types/TextResources';
import type { TextResourceWithLanguage } from '../../../../../../types/TextResourceWithLanguage';

export const getTextResourcesForLanguage = (
language: string,
textResources?: TextResources,
): TextResource[] | undefined => textResources?.[language];

export const createTextResourceWithLanguage = (
language: string,
textResource: TextResource,
): TextResourceWithLanguage => ({ language, textResource });
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { TextResource } from './TextResource';

export type TextResourceWithLanguage = {
language: string;
textResource: TextResource;
};

0 comments on commit e76b1b3

Please sign in to comment.