Skip to content

Commit

Permalink
feat: input panel (#330)
Browse files Browse the repository at this point in the history
* feat: panel group container

* feat: enable custom icon

* feat: dynamicly take full width based on baseComponentId prop

* fix test

* Eslint fixes

* feat: possible to add group reference

* Merge

* chore: remove log statements

* chore: remove debug statement

* feat: possible to reference group without supplying children

* test: test for opening and closing panel

* bug: not possible to delte empy index group

* chore: fix double to single quotes ofter merge trouble

* refactor: RORO for util function

* test: cypress test for complex case

* test: remove it.only + unneccessary check

* chore: formatting

* lint

* refactor: code smell

* test: fix broken test

* chore: remove comment

* cypress: specific selector

* Update test/cypress/e2e/integration/app-frontend/group.js

Co-authored-by: Håkon <[email protected]>

* Update src/altinn-app-frontend/src/features/form/containers/PanelGroupContainer.test.tsx

Co-authored-by: Håkon <[email protected]>

* chore: remove unnessecary eslint ignore line

* refactor: init userEvent

* test: use of within query

* feat: set custom icon size from returned value

Co-authored-by: EKEBERG Steffen <[email protected]>
Co-authored-by: Ole Martin Handeland <[email protected]>
Co-authored-by: Håkon <[email protected]>
  • Loading branch information
4 people authored Jul 12, 2022
1 parent 3d88c9f commit 19802d0
Show file tree
Hide file tree
Showing 27 changed files with 1,072 additions and 175 deletions.
3 changes: 3 additions & 0 deletions src/altinn-app-frontend/__mocks__/formDataStateMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export function getFormDataStateMock(customState?: Partial<IFormDataState>) {
'someGroup[1].labelField': 'Label for second',
'someGroup[0].valueField': 'Value for first',
'someGroup[1].valueField': 'Value for second',
'referencedGroup[0].inputField': 'Value from input field [0]',
'referencedGroup[1].inputField': 'Value from input field [1]',
'referencedGroup[2].inputField': 'Value from input field [2]',
},
hasSubmitted: false,
isSaving: false,
Expand Down
21 changes: 21 additions & 0 deletions src/altinn-app-frontend/__mocks__/formLayoutStateMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ export function getFormLayoutStateMock(
const mockFormLayoutState: ILayoutState = {
layouts: {
FormLayout: [
{
id: 'referencedGroup',
type: 'Group',
dataModelBindings: {
group: 'referencedGroup',
},
children: ['referenced-group-child'],
},
{
id: 'referenced-group-child',
type: 'Input',
dataModelBindings: {
simpleBinding: 'referencedGroup.field1',
},
textResourceBindings: {
title: 'Referenced Group Input',
},
readOnly: false,
required: false,
disabled: false,
},
{
id: 'field1',
type: 'Input',
Expand Down
22 changes: 22 additions & 0 deletions src/altinn-app-frontend/__mocks__/initialStateMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ export function getInitialStateMock(
},
],
},
{
id: 'group.input.title',
value: 'The value from group is: {0}',
unparsedValue: 'The value from group is: {0}',
variables: [
{
dataSource: 'dataModel.skjema',
key: 'referencedGroup[{0}].inputField',
},
],
},
{
id: 'group.input.title-2',
value: 'The value from the group is: Value from input field [2]',
unparsedValue: 'The value from group is: {0}',
variables: [
{
dataSource: 'dataModel.skjema',
key: 'referencedGroup[2].inputField',
},
],
},
],
error: null,
language: 'nb',
Expand Down
4 changes: 4 additions & 0 deletions src/altinn-app-frontend/__mocks__/uiConfigStateMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export const getUiConfigStateMock = (
index: 1,
dataModelBinding: 'someGroup',
},
referencedGroup: {
index: 1,
dataModelBinding: 'referencedGroup',
},
},
fileUploadersWithTag: null,
currentView: 'FormLayout',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { makeStyles } from '@material-ui/core';
import React from 'react';

export interface IFulLWidthGroupWrapperProps {
children?: React.ReactNode;
}

const useStyles = makeStyles({
fullWidthGroupWrapper: {
marginLeft: '-24px',
marginRight: '-24px',
'@media (min-width:993px)': {
marginLeft: '-36px',
marginRight: '-36px',
},
},
});

export function FullWidthGroupWrapper({
children,
}: IFulLWidthGroupWrapperProps) {
const classes = useStyles();

return (
<div
className={classes.fullWidthGroupWrapper}
data-testid='fullWidthGroupWrapper'
>
{children}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface IRepeatingGroupAddButton {
textResources: ITextResource[];
onClickAdd: () => void;
onKeypressAdd: (event: React.KeyboardEvent<HTMLDivElement>) => void;
id?: string;
}

const theme = createTheme(altinnAppTheme);
Expand Down Expand Up @@ -62,6 +63,7 @@ export function RepeatingGroupAddButton({
textResources,
onClickAdd,
onKeypressAdd,
id,
}: IRepeatingGroupAddButton): JSX.Element {
const classes = useStyles();

Expand All @@ -83,6 +85,7 @@ export function RepeatingGroupAddButton({
onKeyPress={(event) => onKeypressAdd(event)}
justifyContent='center'
alignItems='center'
id={id}
>
<Grid item={true}>
<i className={`fa fa-exit ${classes.addIcon}`} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function DisplayGroupContainer(props: IDisplayGroupContainer) {
className={classes.groupContainer}
spacing={3}
alignItems='flex-start'
data-testid='display-group-container'
>
<Grid
item={true}
Expand Down
76 changes: 70 additions & 6 deletions src/altinn-app-frontend/src/features/form/containers/Form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { RootState } from 'src/store';
import { renderWithProviders, mockMediaQuery } from 'src/../testUtils';
import type { ILayout, ILayoutComponent } from '../layout';
import { getFormLayoutStateMock } from 'src/../__mocks__/formLayoutStateMock';
import { screen } from '@testing-library/react';
import { screen, within } from '@testing-library/react';

const { setScreenWidth } = mockMediaQuery(992);

Expand Down Expand Up @@ -73,11 +73,75 @@ describe('Form.tsx', () => {
expect(screen.getByText('Third title')).toBeInTheDocument();
});

it('should render components and groups', () => {
renderForm();
expect(screen.getByText('First title')).toBeInTheDocument();
expect(screen.getByText('Second title')).toBeInTheDocument();
expect(screen.getByText('Third title')).toBeInTheDocument();
it('should render DisplayGroupContainer and children if group is non repeating', () => {
const layoutWithNonRepGroup: ILayout = [
...mockComponents,
{
id: 'non-rep-group-id',
type: 'group',
dataModelBindings: {
group: 'Group',
},
children: ['non-rep-child'],
},
{
id: 'non-rep-child',
type: 'Input',
dataModelBindings: {
simpleBinding: 'Group.prop3',
},
textResourceBindings: {
title: 'Title from non repeating child',
},
readOnly: false,
required: false,
disabled: false,
},
];

renderForm(layoutWithNonRepGroup);
const container = screen.getByTestId('display-group-container');
expect(container).toBeInTheDocument();
expect(
within(container).getByText('Title from non repeating child'),
).toBeInTheDocument();
});

it('should render PanelGroupContainer and children if group has panel prop', () => {
const layoutWithPanelGroup: ILayout = [
...mockComponents,
{
id: 'panel-group-id',
type: 'group',
dataModelBindings: {
group: 'Group',
},
children: ['panel-group-child'],
panel: {
variant: 'info',
},
},
{
id: 'panel-group-child',
type: 'Input',
dataModelBindings: {
simpleBinding: 'Group.prop3',
},
textResourceBindings: {
title: 'Title from panel child',
},
readOnly: false,
required: false,
disabled: false,
},
];

renderForm(layoutWithPanelGroup);
const container = screen.getByTestId('panel-group-container');
expect(container).toBeInTheDocument();
expect(
within(container).getByText('Title from panel child'),
).toBeInTheDocument();
});

it('should render navbar', () => {
Expand Down
29 changes: 21 additions & 8 deletions src/altinn-app-frontend/src/features/form/containers/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useAppSelector } from 'src/common/hooks';
import MessageBanner from 'src/features/form/components/MessageBanner';
import { hasRequiredFields } from 'src/utils/formLayout';
import { missingFieldsInLayoutValidations } from 'src/utils/validation';
import { PanelGroupContainer } from './PanelGroupContainer';

export function renderLayoutComponent(
layoutComponent: ILayoutComponent | ILayoutGroup,
Expand Down Expand Up @@ -54,25 +55,37 @@ function RenderLayoutGroup(
}
return layout.find((c) => c.id === childId) as ILayoutComponent;
});

const repeating = layoutGroup.maxCount > 1;
if (!repeating) {
// If not repeating, treat as regular components
if (repeating) {
return (
<DisplayGroupContainer
key={layoutGroup.id}
<GroupContainer
container={layoutGroup}
id={layoutGroup.id}
key={layoutGroup.id}
components={groupComponents}
renderLayoutComponent={renderLayoutComponent}
/>
);
}

const panel = layoutGroup.panel;
if (panel) {
return (
<PanelGroupContainer
components={groupComponents}
container={layoutGroup}
key={layoutGroup.id}
/>
);
}

//treat as regular components
return (
<GroupContainer
container={layoutGroup}
id={layoutGroup.id}
<DisplayGroupContainer
key={layoutGroup.id}
container={layoutGroup}
components={groupComponents}
renderLayoutComponent={renderLayoutComponent}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ export function GroupContainer({
editIndex < 0 &&
repeatingGroupIndex + 1 < container.maxCount && (
<RepeatingGroupAddButton
id={'add-button-' + id}
container={container}
language={language}
onClickAdd={onClickAdd}
Expand Down Expand Up @@ -382,6 +383,7 @@ export function GroupContainer({
container.edit?.addButton !== false &&
repeatingGroupIndex + 1 < container.maxCount && (
<RepeatingGroupAddButton
id={'add-button-' + id}
container={container}
language={language}
onClickAdd={onClickAdd}
Expand Down
Loading

0 comments on commit 19802d0

Please sign in to comment.