Skip to content

Commit 3958771

Browse files
authored
feat: summary2 filter override components (#14470)
1 parent ffdd96b commit 3958771

File tree

10 files changed

+86
-30
lines changed

10 files changed

+86
-30
lines changed

frontend/language/src/nb.json

+1
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,7 @@
15081508
"ux_editor.component_properties.tagName": "Tag-navn",
15091509
"ux_editor.component_properties.target": "Hva vil du vise i oppsummeringen?",
15101510
"ux_editor.component_properties.target_description": "Her kan du velge hva som skal vises på oppsummeringssiden. Du kan for eksempel vise hele sidegrupper, utvalgte sider eller utvalgte komponenter",
1511+
"ux_editor.component_properties.target_empty": "Ingen gyldige mål",
15111512
"ux_editor.component_properties.target_invalid": "Ugyldig mål",
15121513
"ux_editor.component_properties.target_layoutSet_id": "1. Oppsummer fra denne sidegruppen",
15131514
"ux_editor.component_properties.target_type": "2. Vis sidegruppe, side eller komponent",

frontend/packages/shared/src/types/api/dto/LayoutSetModel.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export type LayoutSetModel = {
44
id: string;
55
dataType: string;
66
type: string;
7-
task: TaskModel;
7+
task?: TaskModel;
88
};

frontend/packages/ux-editor/src/components/Properties/PropertiesHeader/ComponentMainConfig.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const ComponentMainConfig = ({
3434
const handleTargetChange = (updatedTarget: Summary2TargetConfig): void => {
3535
const updatedComponent = { ...component } as FormItem<ComponentType.Summary2>;
3636
updatedComponent.target = updatedTarget;
37+
updatedComponent.overrides = [];
3738
handleComponentChange(updatedComponent);
3839
};
3940

@@ -61,6 +62,7 @@ export const ComponentMainConfig = ({
6162
</Accordion.Header>
6263
<Accordion.Content>
6364
<Summary2Override
65+
target={component.target}
6466
overrides={component.overrides}
6567
onChange={handleOverridesChange}
6668
/>

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Override/Summary2Override.test.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
layoutMock,
1313
} from '../../../../../testing/layoutMock';
1414
import { textMock } from '@studio/testing/mocks/i18nMock';
15-
import { layoutSet1NameMock } from '../../../../../testing/layoutSetsMock';
15+
import { layoutSet1NameMock, layoutSetsExtendedMock } from '../../../../../testing/layoutSetsMock';
1616
import { renderWithProviders } from '../../../../../testing/mocks';
1717

1818
describe('Summary2Override', () => {
@@ -75,7 +75,7 @@ describe('Summary2Override', () => {
7575

7676
it('should be able to change override componentId', async () => {
7777
const user = userEvent.setup();
78-
render({ overrides: [{ componentId: '1' }] });
78+
render({ overrides: [{ componentId: '2' }], target: { type: 'layoutSet' } });
7979
const componentId = component1IdMock;
8080
await userEvent.click(overrideCollapsedButton(1));
8181
await user.click(overrideComponentSelect());
@@ -395,15 +395,17 @@ const overrideComponentSelect = () =>
395395
name: textMock('ux_editor.component_properties.summary.override.choose_component'),
396396
});
397397

398-
const defaultProps = {
398+
const defaultProps: Summary2OverrideProps = {
399399
overrides: [],
400+
target: {},
400401
onChange: jest.fn(),
401402
};
402403
const render = (props?: Partial<Summary2OverrideProps>) => {
403404
const queryClient = createQueryClientMock();
404405
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], {
405406
[layout1NameMock]: layoutMock,
406407
});
408+
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock);
407409
renderWithProviders(<Summary2Override {...defaultProps} {...props} />, {
408410
queryClient,
409411
appContextProps: {

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Override/Summary2Override.tsx

+41-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
import { StudioButton } from '@studio/components';
2-
import type { Summary2OverrideConfig } from 'app-shared/types/ComponentSpecificConfig';
2+
import type {
3+
Summary2OverrideConfig,
4+
Summary2TargetConfig,
5+
} from 'app-shared/types/ComponentSpecificConfig';
36
import React from 'react';
47
import { useTranslation } from 'react-i18next';
58
import { Summary2OverrideEntry } from './Summary2OverrideEntry';
69
import { PlusIcon } from '@studio/icons';
10+
import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery';
11+
import { useAppContext, useComponentTitle } from '../../../../../hooks';
12+
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
13+
import { useLayoutSetsExtendedQuery } from 'app-shared/hooks/queries/useLayoutSetsExtendedQuery';
14+
import { getComponentOptions, getTargetLayoutSetName } from '../Summary2Target/targetUtils';
715

816
export type Summary2OverrideProps = {
917
overrides: Summary2OverrideConfig[];
18+
target: Summary2TargetConfig;
1019
onChange: (overrides: Summary2OverrideConfig[]) => void;
1120
};
1221

13-
export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps) => {
22+
export const Summary2Override = ({ overrides, target, onChange }: Summary2OverrideProps) => {
1423
const { t } = useTranslation();
1524
const [openOverrides, setOpenOverrides] = React.useState([]);
1625

26+
const componentOptions = useTargetComponentOptions(target);
27+
1728
const addOverride = (): void => {
1829
const updatedOverrides = [...(overrides || [])];
1930
setOpenOverrides([...openOverrides, updatedOverrides.length]);
@@ -53,6 +64,7 @@ export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps)
5364
? setOpenOverrides([...openOverrides, index])
5465
: setOpenOverrides(openOverrides.filter((i) => i !== index))
5566
}
67+
componentOptions={componentOptions}
5668
key={`${index}${override.componentId}`}
5769
override={override}
5870
onChange={onChangeOverride(index)}
@@ -67,3 +79,30 @@ export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps)
6779
</>
6880
);
6981
};
82+
83+
const useTargetComponentOptions = (target: Summary2TargetConfig): any[] => {
84+
const { org, app } = useStudioEnvironmentParams();
85+
const { data: layoutSets } = useLayoutSetsExtendedQuery(org, app);
86+
const layoutSetName = getTargetLayoutSetName({
87+
target,
88+
layoutSets,
89+
selectedFormLayoutSetName: useAppContext().selectedFormLayoutSetName,
90+
});
91+
const { data: formLayoutsData } = useFormLayoutsQuery(org, app, layoutSetName);
92+
const getComponentTitle = useComponentTitle();
93+
94+
if (!formLayoutsData) return [];
95+
if (target?.type === 'page' && target.id) {
96+
const formPage = formLayoutsData[target.id];
97+
if (!formPage) return [];
98+
return getComponentOptions({
99+
formLayoutsData: [formPage],
100+
getComponentTitle,
101+
});
102+
}
103+
const components = getComponentOptions({ formLayoutsData, getComponentTitle });
104+
if (target?.type === 'component') {
105+
return components.filter(({ id }) => id === target.id);
106+
}
107+
return components;
108+
};

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Override/Summary2OverrideEntry.tsx

+4-16
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,20 @@ import {
1010
import type { Summary2OverrideConfig } from 'app-shared/types/ComponentSpecificConfig';
1111
import classes from './Summary2OverrideEntry.module.css';
1212
import { useTranslation } from 'react-i18next';
13-
import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils';
14-
import { useAppContext, useComponentTitle } from '@altinn/ux-editor/hooks';
15-
import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery';
16-
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
1713
import { Summary2ComponentReferenceSelector } from '../Summary2ComponentReferenceSelector';
1814
import { Summary2OverrideDisplayType } from './OverrideFields/Summary2OverrideDisplayType';
1915
import { ShowEmptyFieldSwitch } from './OverrideFields/ShowEmptyFieldsSwitch';
2016
import { OverrideShowComponentSwitch } from './OverrideFields/ForceShowSwitch';
2117
import { EmptyTextField } from './OverrideFields/EmptyTextField';
2218
import { CompactViewSwitch } from './OverrideFields/CompactViewSwitch';
2319
import { CheckmarkIcon } from '@studio/icons';
20+
import { type TargetProps } from '../Summary2Target/targetUtils';
2421

2522
type Summary2OverrideEntryProps = {
2623
index: number;
2724
open: boolean;
2825
setOpen: (open: boolean) => void;
26+
componentOptions: TargetProps[];
2927
override: Summary2OverrideConfig;
3028
onChange: (override: Summary2OverrideConfig) => void;
3129
onDelete: () => void;
@@ -35,24 +33,14 @@ export const Summary2OverrideEntry = ({
3533
index,
3634
open,
3735
setOpen,
36+
componentOptions,
3837
override,
3938
onChange,
4039
onDelete,
4140
}: Summary2OverrideEntryProps) => {
4241
const { t } = useTranslation();
43-
const { org, app } = useStudioEnvironmentParams();
44-
const { selectedFormLayoutSetName } = useAppContext();
45-
const { data: formLayoutsData } = useFormLayoutsQuery(org, app, selectedFormLayoutSetName);
46-
const getComponentTitle = useComponentTitle();
4742

48-
const components = Object.values(formLayoutsData).flatMap((layout) =>
49-
getAllLayoutComponents(layout),
50-
);
51-
52-
const componentOptions = components.map((e) => ({
53-
id: e.id,
54-
description: getComponentTitle(e),
55-
}));
43+
if (!componentOptions) return null;
5644

5745
if (!open) {
5846
const componentNameType = componentOptions.find(

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Summary2Component.test.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { component1IdMock, layout1NameMock, layoutMock } from '../../../../testi
1010
import {
1111
layoutSet1NameMock,
1212
layoutSet2NameMock,
13+
layoutSetsExtendedMock,
1314
layoutSetsMock,
1415
} from '../../../../testing/layoutSetsMock';
1516
import { renderWithProviders } from '../../../../testing/mocks';
@@ -191,6 +192,7 @@ const defaultProps = {
191192
const render = (props?: Partial<IGenericEditComponent<ComponentType.Summary2>>) => {
192193
const queryClient = createQueryClientMock();
193194
queryClient.setQueryData([QueryKey.LayoutSets, org, app], layoutSetsMock);
195+
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock);
194196
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], {
195197
[layout1NameMock]: layoutMock,
196198
});

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Summary2Component.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const Summary2Component = ({
3030
return (
3131
<>
3232
<Summary2Target target={target} onChange={handleTargetChange} />
33-
<Summary2Override overrides={overrides} onChange={handleOverridesChange} />
33+
<Summary2Override overrides={overrides} target={target} onChange={handleOverridesChange} />
3434
</>
3535
);
3636
};

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Summary2ComponentReferenceSelector.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ export const Summary2ComponentReferenceSelector = ({
3030
error={errorMessage}
3131
multiple={false}
3232
>
33+
<StudioCombobox.Empty>
34+
{t('ux_editor.component_properties.target_empty')}
35+
</StudioCombobox.Empty>
3336
{options.map((option) => (
3437
<StudioCombobox.Option value={option.id} key={option.id} description={option.description}>
3538
{option.id}

frontend/packages/ux-editor/src/components/config/componentSpecificContent/Summary2/Summary2Target/targetUtils.ts

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import type { IFormLayouts } from '@altinn/ux-editor/types/global';
1+
import type { IFormLayouts, IInternalLayout } from '@altinn/ux-editor/types/global';
22
import type { FormComponent } from '@altinn/ux-editor/types/FormComponent';
33
import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils';
44
import { ComponentType } from 'app-shared/types/ComponentType';
55
import type { LayoutSet, LayoutSets } from 'app-shared/types/api/LayoutSetsResponse';
6+
import type { Summary2TargetConfig } from 'app-shared/types/ComponentSpecificConfig';
7+
import type { LayoutSetsModel } from 'app-shared/types/api/dto/LayoutSetsModel';
68

79
const excludedComponents = [
810
ComponentType.ActionButton,
@@ -27,16 +29,33 @@ const excludedComponents = [
2729
ComponentType.Summary2,
2830
];
2931

30-
type GetComponentOptionsProps = {
31-
formLayoutsData: IFormLayouts;
32-
getComponentTitle: (formComponent: FormComponent) => string;
33-
};
34-
35-
type TargetProps = {
32+
export type TargetProps = {
3633
id: string;
3734
description: string;
3835
};
3936

37+
type getTargetLayoutSetNameProps = {
38+
target: Summary2TargetConfig;
39+
layoutSets: LayoutSetsModel;
40+
selectedFormLayoutSetName: string;
41+
};
42+
43+
export const getTargetLayoutSetName = ({
44+
target,
45+
layoutSets,
46+
selectedFormLayoutSetName,
47+
}: getTargetLayoutSetNameProps): string => {
48+
const layoutSetName = target?.taskId
49+
? layoutSets.sets.find((layoutSet) => layoutSet.task?.id === target.taskId).id
50+
: selectedFormLayoutSetName;
51+
return layoutSetName;
52+
};
53+
54+
type GetComponentOptionsProps = {
55+
formLayoutsData: IFormLayouts | IInternalLayout[];
56+
getComponentTitle: (formComponent: FormComponent) => string;
57+
};
58+
4059
export const getComponentOptions = ({
4160
formLayoutsData,
4261
getComponentTitle,

0 commit comments

Comments
 (0)