Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support configuration for rendering summaries of current and previous tasks #13752

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,7 @@
"ux_editor.component_properties.target": "Mål",
"ux_editor.component_properties.target_description": "Mål for oppsummeringskomponenten",
"ux_editor.component_properties.target_invalid": "Ugyldig mål",
"ux_editor.component_properties.target_taskId": "Oppgave-ID",
"ux_editor.component_properties.target_type": "Type",
"ux_editor.component_properties.taskId": "Oppgave-ID",
"ux_editor.component_properties.timeStamp": "Inkluder tidsstempel i dato (på som standard)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const EditFormComponent = ({
}

return (
<Fieldset className={classes.root} legend=''>
<Fieldset className={classes.root} legend='' size='sm'>
{isPending && (
<StudioSpinner
showSpinnerTitle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { QueryKey } from 'app-shared/types/QueryKey';
import React from 'react';
import { componentMocks } from '../../../../testing/componentMocks';
import { component1IdMock, layout1NameMock, layoutMock } from '../../../../testing/layoutMock';
import { layoutSet1NameMock } from '../../../../testing/layoutSetsMock';
import { layoutSet1NameMock, layoutSetsMock } from '../../../../testing/layoutSetsMock';
import { renderWithProviders } from '../../../../testing/mocks';
import type { IGenericEditComponent } from '../../componentConfig';
import { Summary2Component } from './Summary2Component';
Expand All @@ -25,13 +25,51 @@ describe('Summary2ComponentTargetSelector', () => {
screen.getByRole('heading', { name: textMock('ux_editor.component_properties.target') }),
).toBeInTheDocument();

expect(targetTaskIdSelect()).toBeInTheDocument();

expect(targetTypeSelect()).toBeInTheDocument();

expect(addNewOverrideButton()).toBeInTheDocument();

expect(componentTargetSelect()).toBeInTheDocument();
});

it('should select the task id from the current layout when the task id of the target is not defined', async () => {
render();

const select = targetTaskIdSelect();
expect(select).toHaveValue(layoutSetsMock.sets[0].tasks[0]);
});

it('should select the task id from the target when the task id of the target is defined', async () => {
render({
component: { ...defaultProps.component, target: { taskId: 'Task_2' } },
});

const select = targetTaskIdSelect();
expect(select).toHaveValue(layoutSetsMock.sets[1].tasks[0]);
});

it('should allow selecting a task id', async () => {
const user = userEvent.setup();
render();

await user.selectOptions(targetTaskIdSelect(), 'Task_2');
expect(defaultProps.handleComponentChange).toHaveBeenCalledWith(
expect.objectContaining({ target: { taskId: 'Task_2', type: 'component', id: '' } }),
);
});

it('should remove the task id from the target if the task id is the same as the current layout set', async () => {
const user = userEvent.setup();
render();

await user.selectOptions(targetTaskIdSelect(), 'Task_1');
expect(defaultProps.handleComponentChange).toHaveBeenCalledWith(
expect.objectContaining({ target: { type: 'component', id: '' } }),
);
});

it('should allow selecting page target and defaults to same page', async () => {
const user = userEvent.setup();
render();
Expand Down Expand Up @@ -120,6 +158,11 @@ describe('Summary2ComponentTargetSelector', () => {
});
});

const targetTaskIdSelect = () =>
screen.getByRole('combobox', {
name: textMock('ux_editor.component_properties.target_taskId'),
});

const targetTypeSelect = () =>
screen.getByRole('combobox', {
name: textMock('ux_editor.component_properties.target_type'),
Expand All @@ -146,6 +189,7 @@ const defaultProps = {
};
const render = (props?: Partial<IGenericEditComponent<ComponentType.Summary2>>) => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.LayoutSets, org, app], layoutSetsMock);
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], {
[layout1NameMock]: layoutMock,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { useAppContext, useComponentTypeName } from '../../../../../hooks';
import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery';
import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils';
import { useTargetTypes } from './useTargetTypes';
import { useLayoutSetsQuery } from 'app-shared/hooks/queries/useLayoutSetsQuery';

type Summary2TargetProps = {
target: Summary2TargetConfig;
Expand All @@ -29,7 +30,23 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
const { t } = useTranslation();
const { org, app } = useStudioEnvironmentParams();
const { selectedFormLayoutSetName, selectedFormLayoutName } = useAppContext();
const { data: formLayoutsData } = useFormLayoutsQuery(org, app, selectedFormLayoutSetName);
const { data: layoutSets } = useLayoutSetsQuery(org, app);

const tasks = [
...new Set(
layoutSets.sets.reduce((acc, set) => {
return set.tasks ? acc.concat(set.tasks) : acc;
}, []),
),
];
const currentTaskId = layoutSets?.sets?.find((set) => set.id === selectedFormLayoutSetName)
.tasks?.[0];
const selectedLayoutSetName = target.taskId
? layoutSets?.sets?.find((set) => set.tasks?.[0] === target.taskId).id
: selectedFormLayoutSetName;

const { data: formLayoutsData } = useFormLayoutsQuery(org, app, selectedLayoutSetName);

const targetTypes = useTargetTypes();
const componentTypeName = useComponentTypeName();

Expand All @@ -38,29 +55,43 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
ComponentType.NavigationButtons,
ComponentType.NavigationBar,
];
const components = Object.values(formLayoutsData).flatMap((layout) =>
getAllLayoutComponents(layout, excludedComponents),
);
const components = formLayoutsData
? Object.values(formLayoutsData).flatMap((layout) =>
getAllLayoutComponents(layout, excludedComponents),
)
: [];
const componentOptions = components.map((formComponent: FormComponent) => ({
id: formComponent.id,
description: componentTypeName(formComponent.type),
}));

const pageOptions = Object.keys(formLayoutsData).map((page) => ({
id: page,
description: undefined,
}));
const pageOptions = formLayoutsData
? Object.keys(formLayoutsData).map((page) => ({
id: page,
description: undefined,
}))
: [];

const handleTypeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const newType = event.target.value as SummaryTargetType;
const updatedTarget = { type: newType, id: '' };
const updatedTarget = { ...target, type: newType, id: '' };
// set default value for page
if (newType === 'page' && pageOptions.some((page) => page.id === selectedFormLayoutName)) {
updatedTarget.id = selectedFormLayoutName;
}
onChange(updatedTarget);
};

const handleTaskIdChange = (taskId: string) => {
const updatedTarget = { ...target, id: '' };
if (taskId === currentTaskId) {
delete updatedTarget.taskId;
} else {
updatedTarget.taskId = taskId;
}
onChange(updatedTarget);
};

const handleTargetIdChange = (value: string) => {
const updatedTarget = { ...target };
updatedTarget.id = value;
Expand All @@ -76,6 +107,18 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
{t('ux_editor.component_properties.target_description')}
</StudioParagraph>
<StudioCard.Content>
<StudioNativeSelect
size='sm'
label={t('ux_editor.component_properties.target_taskId')}
value={target.taskId || currentTaskId}
onChange={(e) => handleTaskIdChange(e.target.value)}
>
{tasks.map((taskId) => (
<option key={taskId} value={taskId}>
{taskId}
</option>
))}
</StudioNativeSelect>
<StudioNativeSelect
size='sm'
label={t('ux_editor.component_properties.target_type')}
Expand All @@ -90,6 +133,7 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
</StudioNativeSelect>
{target.type === 'page' && (
<Summmary2ComponentReferenceSelector
key={target.id} // TODO: Remove the key when https://github.com/digdir/designsystemet/issues/2264 is fixed
label={t('general.page')}
value={target.id}
options={pageOptions}
Expand All @@ -98,6 +142,7 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
)}
{target.type === 'component' && (
<Summmary2ComponentReferenceSelector
key={target.id} // TODO: Remove the key when https://github.com/digdir/designsystemet/issues/2264 is fixed
label={t('general.component')}
value={target.id}
options={componentOptions}
Expand All @@ -106,9 +151,10 @@ export const Summary2Target = ({ target, onChange }: Summary2TargetProps) => {
)}
{target.type === 'layoutSet' && (
<StudioTextfield
key={target.id} // TODO: Remove the key when https://github.com/digdir/designsystemet/issues/2264 is fixed
size='sm'
label={t('general.layout_set')}
value={selectedFormLayoutSetName}
value={selectedLayoutSetName}
disabled={true}
/>
)}
Expand Down