Skip to content

Commit

Permalink
Add filtering to override component select
Browse files Browse the repository at this point in the history
Filters by applicable components
I.e. If target is a layoutset, show only components from that layoutset
  • Loading branch information
Jondyr committed Jan 27, 2025
1 parent ded0d41 commit a27a6e4
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 30 deletions.
1 change: 1 addition & 0 deletions frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,7 @@
"ux_editor.component_properties.tagName": "Tag-navn",
"ux_editor.component_properties.target": "Hva vil du vise i oppsummeringen?",
"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",
"ux_editor.component_properties.target_empty": "Ingen gyldige mål",
"ux_editor.component_properties.target_invalid": "Ugyldig mål",
"ux_editor.component_properties.target_layoutSet_id": "1. Oppsummer fra denne sidegruppen",
"ux_editor.component_properties.target_type": "2. Vis sidegruppe, side eller komponent",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export type LayoutSetModel = {
id: string;
dataType: string;
type: string;
task: TaskModel;
task?: TaskModel;
};
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const ComponentMainConfig = ({
<Accordion.Content>
<Summary2Override
overrides={component.overrides}
target={component.target}
onChange={handleOverridesChange}
/>
</Accordion.Content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
layoutMock,
} from '../../../../../testing/layoutMock';
import { textMock } from '@studio/testing/mocks/i18nMock';
import { layoutSet1NameMock } from '../../../../../testing/layoutSetsMock';
import { layoutSet1NameMock, layoutSetsExtendedMock } from '../../../../../testing/layoutSetsMock';
import { renderWithProviders } from '../../../../../testing/mocks';

describe('Summary2Override', () => {
Expand Down Expand Up @@ -75,7 +75,7 @@ describe('Summary2Override', () => {

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

const defaultProps = {
const defaultProps: Summary2OverrideProps = {
overrides: [],
target: {},
onChange: jest.fn(),
};
const render = (props?: Partial<Summary2OverrideProps>) => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], {
[layout1NameMock]: layoutMock,
});
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock);
renderWithProviders(<Summary2Override {...defaultProps} {...props} />, {
queryClient,
appContextProps: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { StudioButton } from '@studio/components';
import type { Summary2OverrideConfig } from 'app-shared/types/ComponentSpecificConfig';
import type {
Summary2OverrideConfig,
Summary2TargetConfig,
} from 'app-shared/types/ComponentSpecificConfig';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Summary2OverrideEntry } from './Summary2OverrideEntry';
import { PlusIcon } from '@studio/icons';
import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery';
import { useAppContext, useComponentTitle } from '../../../../../hooks';
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
import { useLayoutSetsExtendedQuery } from 'app-shared/hooks/queries/useLayoutSetsExtendedQuery';
import { getComponentOptions, getTargetLayoutSetName } from '../Summary2Target/targetUtils';

export type Summary2OverrideProps = {
overrides: Summary2OverrideConfig[];
target: Summary2TargetConfig;
onChange: (overrides: Summary2OverrideConfig[]) => void;
};

export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps) => {
export const Summary2Override = ({ overrides, target, onChange }: Summary2OverrideProps) => {
const { t } = useTranslation();
const [openOverrides, setOpenOverrides] = React.useState([]);

const componentOptions = useTargetComponentOptions(target);

const addOverride = (): void => {
const updatedOverrides = [...(overrides || [])];
setOpenOverrides([...openOverrides, updatedOverrides.length]);
Expand Down Expand Up @@ -53,6 +64,7 @@ export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps)
? setOpenOverrides([...openOverrides, index])
: setOpenOverrides(openOverrides.filter((i) => i !== index))
}
componentOptions={componentOptions}
key={`${index}${override.componentId}`}
override={override}
onChange={onChangeOverride(index)}
Expand All @@ -67,3 +79,30 @@ export const Summary2Override = ({ overrides, onChange }: Summary2OverrideProps)
</>
);
};

const useTargetComponentOptions = (target: Summary2TargetConfig): any[] => {
const { org, app } = useStudioEnvironmentParams();
const { data: layoutSets } = useLayoutSetsExtendedQuery(org, app);
const layoutSetName = getTargetLayoutSetName({
target,
layoutSets,
selectedFormLayoutSetName: useAppContext().selectedFormLayoutSetName,
});
const { data: formLayoutsData } = useFormLayoutsQuery(org, app, layoutSetName);
const getComponentTitle = useComponentTitle();

if (!formLayoutsData) return [];
if (target?.type === 'page' && target.id) {
const formPage = formLayoutsData[target.id];
if (!formPage) return [];
return getComponentOptions({
formLayoutsData: [formPage],
getComponentTitle,
});
}
const components = getComponentOptions({ formLayoutsData, getComponentTitle });
if (target?.type === 'component') {
return components.filter(({ id }) => id === target.id);
}
return components;
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,20 @@ import {
import type { Summary2OverrideConfig } from 'app-shared/types/ComponentSpecificConfig';
import classes from './Summary2OverrideEntry.module.css';
import { useTranslation } from 'react-i18next';
import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils';
import { useAppContext, useComponentTitle } from '@altinn/ux-editor/hooks';
import { useFormLayoutsQuery } from '../../../../../hooks/queries/useFormLayoutsQuery';
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
import { Summary2ComponentReferenceSelector } from '../Summary2ComponentReferenceSelector';
import { Summary2OverrideDisplayType } from './OverrideFields/Summary2OverrideDisplayType';
import { ShowEmptyFieldSwitch } from './OverrideFields/ShowEmptyFieldsSwitch';
import { OverrideShowComponentSwitch } from './OverrideFields/ForceShowSwitch';
import { EmptyTextField } from './OverrideFields/EmptyTextField';
import { CompactViewSwitch } from './OverrideFields/CompactViewSwitch';
import { CheckmarkIcon } from '@studio/icons';
import { type TargetProps } from '../Summary2Target/targetUtils';

type Summary2OverrideEntryProps = {
index: number;
open: boolean;
setOpen: (open: boolean) => void;
componentOptions: TargetProps[];
override: Summary2OverrideConfig;
onChange: (override: Summary2OverrideConfig) => void;
onDelete: () => void;
Expand All @@ -35,24 +33,14 @@ export const Summary2OverrideEntry = ({
index,
open,
setOpen,
componentOptions,
override,
onChange,
onDelete,
}: Summary2OverrideEntryProps) => {
const { t } = useTranslation();
const { org, app } = useStudioEnvironmentParams();
const { selectedFormLayoutSetName } = useAppContext();
const { data: formLayoutsData } = useFormLayoutsQuery(org, app, selectedFormLayoutSetName);
const getComponentTitle = useComponentTitle();

const components = Object.values(formLayoutsData).flatMap((layout) =>
getAllLayoutComponents(layout),
);

const componentOptions = components.map((e) => ({
id: e.id,
description: getComponentTitle(e),
}));
if (!componentOptions) return null;

if (!open) {
const componentNameType = componentOptions.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { component1IdMock, layout1NameMock, layoutMock } from '../../../../testi
import {
layoutSet1NameMock,
layoutSet2NameMock,
layoutSetsExtendedMock,
layoutSetsMock,
} from '../../../../testing/layoutSetsMock';
import { renderWithProviders } from '../../../../testing/mocks';
Expand Down Expand Up @@ -191,6 +192,7 @@ const defaultProps = {
const render = (props?: Partial<IGenericEditComponent<ComponentType.Summary2>>) => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.LayoutSets, org, app], layoutSetsMock);
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock);
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], {
[layout1NameMock]: layoutMock,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Summary2Component = ({
return (
<>
<Summary2Target target={target} onChange={handleTargetChange} />
<Summary2Override overrides={overrides} onChange={handleOverridesChange} />
<Summary2Override overrides={overrides} target={target} onChange={handleOverridesChange} />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export const Summary2ComponentReferenceSelector = ({
error={errorMessage}
multiple={false}
>
<StudioCombobox.Empty>
{t('ux_editor.component_properties.target_empty')}
</StudioCombobox.Empty>
{options.map((option) => (
<StudioCombobox.Option value={option.id} key={option.id} description={option.description}>
{option.id}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { IFormLayouts } from '@altinn/ux-editor/types/global';
import type { IFormLayouts, IInternalLayout } from '@altinn/ux-editor/types/global';
import type { FormComponent } from '@altinn/ux-editor/types/FormComponent';
import { getAllLayoutComponents } from '../../../../../utils/formLayoutUtils';
import { ComponentType } from 'app-shared/types/ComponentType';
import type { LayoutSet, LayoutSets } from 'app-shared/types/api/LayoutSetsResponse';
import type { Summary2TargetConfig } from 'app-shared/types/ComponentSpecificConfig';
import type { LayoutSetsModel } from 'app-shared/types/api/dto/LayoutSetsModel';

const excludedComponents = [
ComponentType.ActionButton,
Expand All @@ -27,16 +29,33 @@ const excludedComponents = [
ComponentType.Summary2,
];

type GetComponentOptionsProps = {
formLayoutsData: IFormLayouts;
getComponentTitle: (formComponent: FormComponent) => string;
};

type TargetProps = {
export type TargetProps = {
id: string;
description: string;
};

type getTargetLayoutSetNameProps = {
target: Summary2TargetConfig;
layoutSets: LayoutSetsModel;
selectedFormLayoutSetName: string;
};

export const getTargetLayoutSetName = ({
target,
layoutSets,
selectedFormLayoutSetName,
}: getTargetLayoutSetNameProps): string => {
const layoutSetName = target?.taskId
? layoutSets.sets.find((layoutSet) => layoutSet.task?.id === target.taskId).id
: selectedFormLayoutSetName;
return layoutSetName;
};

type GetComponentOptionsProps = {
formLayoutsData: IFormLayouts | IInternalLayout[];
getComponentTitle: (formComponent: FormComponent) => string;
};

export const getComponentOptions = ({
formLayoutsData,
getComponentTitle,
Expand Down

0 comments on commit a27a6e4

Please sign in to comment.