diff --git a/src/altinn-app-frontend/src/features/form/containers/GroupContainer.test.tsx b/src/altinn-app-frontend/src/features/form/containers/GroupContainer.test.tsx index f5747af391..8fbe1e34b1 100644 --- a/src/altinn-app-frontend/src/features/form/containers/GroupContainer.test.tsx +++ b/src/altinn-app-frontend/src/features/form/containers/GroupContainer.test.tsx @@ -195,7 +195,9 @@ describe('GroupContainer', () => { const user = userEvent.setup(); const store = render({ container: mockContainerInEditModeWithTrigger }); - const editButton = screen.getAllByText('Rediger')[0].closest('button'); + const editButton = screen.getAllByRole('button', { + name: /Lagre og lukk/i, + })[0]; await user.click(editButton); const mockDispatchedAction = { @@ -219,7 +221,9 @@ describe('GroupContainer', () => { const store = render({ container: mockContainerInEditMode }); const user = userEvent.setup(); - const editButton = screen.getAllByText('Rediger')[0].closest('button'); + const editButton = screen.getAllByRole('button', { + name: /Lagre og lukk/i, + })[0]; await user.click(editButton); const mockDispatchedAction = { @@ -244,9 +248,9 @@ describe('GroupContainer', () => { const store = render({ container: mockContainerInEditModeWithTrigger }); const user = userEvent.setup(); - const editButton = screen.getByRole('button', { + const editButton = screen.getAllByRole('button', { name: /Lagre og lukk/i, - }); + })[1]; await user.click(editButton); const mockDispatchedAction = { @@ -270,9 +274,9 @@ describe('GroupContainer', () => { const store = render({ container: mockContainerInEditMode }); const user = userEvent.setup(); - const editButton = screen.getByRole('button', { + const editButton = screen.getAllByRole('button', { name: /Lagre og lukk/i, - }); + })[1]; await user.click(editButton); const mockDispatchedAction = { diff --git a/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx b/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx index d620840ac1..aec7f487ae 100644 --- a/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx +++ b/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx @@ -239,10 +239,11 @@ export function GroupContainer({ ); }; - const setEditIndex = (index: number) => { + const setEditIndex = (index: number, forceValidation?: boolean) => { // if edit button has been clicked while edit container is open, we trigger validations if present in triggers const validate: boolean = - index === -1 && !!container.triggers?.includes(Triggers.Validation); + (index === -1 || forceValidation) && + !!container.triggers?.includes(Triggers.Validation); dispatch( FormLayoutActions.updateRepeatingGroupsEditIndex({ group: id, @@ -340,6 +341,8 @@ export function GroupContainer({ )} {container.edit?.mode === 'showAll' && @@ -368,6 +372,7 @@ export function GroupContainer({ void; + setEditIndex: (index: number, forceValidation?: boolean) => void; onClickRemove: (groupIndex: number) => void; setMultiPageIndex?: (index: number) => void; multiPageIndex?: number; @@ -210,7 +210,9 @@ function getEditButtonText( ); } - return getLanguageFromKey('general.edit_alt', language); + return isEditing + ? getLanguageFromKey('general.save_and_close', language) + : getLanguageFromKey('general.edit_alt', language); } export function RepeatingGroupTable({ @@ -347,6 +349,8 @@ export function RepeatingGroupTable({ className={classes.editContainerInTable} container={container} editIndex={editIndex} + setEditIndex={setEditIndex} + repeatingGroupIndex={repeatingGroupIndex} id={id} language={language} textResources={textResources} @@ -356,6 +360,7 @@ export function RepeatingGroupTable({ hideSaveButton={container.edit?.saveButton === false} multiPageIndex={multiPageIndex} setMultiPageIndex={setMultiPageIndex} + showSaveAndNextButton={container.edit?.saveAndNextButton === true} /> ) ); @@ -384,7 +389,9 @@ export function RepeatingGroupTable({ {getTextResource(title, textResources)} ))} - + {getLanguageFromKey('general.edit', language)} @@ -463,8 +470,12 @@ export function RepeatingGroupTable({ ); })} { delete: 'Delete', edit_alt: 'Edit', save_and_close: 'Save and close', + save_and_next: 'Save and open next', }, }; const textResources: ITextResource[] = [ @@ -115,6 +116,19 @@ describe('RepeatingGroupsEditContainer', () => { expect(setMultiPageIndex).toHaveBeenCalledTimes(1); }); + it('calls setEditIndex when save and open next is pressed when edit.saveAndNextButton is true', async () => { + const setEditIndex = jest.fn(); + const setMultiPageIndex = jest.fn(); + const onClickSave = jest.fn(); + multiPageGroup.edit.saveAndNextButton = true; + render({ setEditIndex, setMultiPageIndex, onClickSave, editIndex: 0 }); + await user.click( + screen.getByRole('button', { name: /save and open next/i }), + ); + expect(onClickSave).not.toHaveBeenCalled(); + expect(setEditIndex).toHaveBeenCalledWith(1, true); + }); + const render = (props: Partial = {}) => { const allProps: IRepeatingGroupsEditContainer = { id: 'multipageGroup', @@ -124,9 +138,11 @@ describe('RepeatingGroupsEditContainer', () => { textResources: textResources, layout: layout, editIndex: 1, + repeatingGroupIndex: repeatingGroupIndex, onClickSave: jest.fn(), onClickRemove: jest.fn(), hideDeleteButton: false, + showSaveAndNextButton: multiPageGroup.edit?.saveAndNextButton === true, ...props, }; diff --git a/src/altinn-app-frontend/src/features/form/containers/RepeatingGroupsEditContainer.tsx b/src/altinn-app-frontend/src/features/form/containers/RepeatingGroupsEditContainer.tsx index 821d3a0234..95610ffd36 100644 --- a/src/altinn-app-frontend/src/features/form/containers/RepeatingGroupsEditContainer.tsx +++ b/src/altinn-app-frontend/src/features/form/containers/RepeatingGroupsEditContainer.tsx @@ -27,12 +27,15 @@ export interface IRepeatingGroupsEditContainer { layout: ILayout; deleting?: boolean; editIndex: number; + setEditIndex?: (index: number, forceValidation?: boolean) => void; + repeatingGroupIndex: number; onClickRemove?: (groupIndex: number) => void; onClickSave: () => void; hideSaveButton?: boolean; hideDeleteButton?: boolean; multiPageIndex?: number; setMultiPageIndex?: (index: number) => void; + showSaveAndNextButton?: boolean; } const theme = createTheme(altinnAppTheme); @@ -99,12 +102,15 @@ export function RepeatingGroupsEditContainer({ layout, deleting, editIndex, + setEditIndex, + repeatingGroupIndex, onClickRemove, onClickSave, hideSaveButton, hideDeleteButton, multiPageIndex, setMultiPageIndex, + showSaveAndNextButton, }: IRepeatingGroupsEditContainer): JSX.Element { const classes = useStyles(); @@ -115,6 +121,13 @@ export function RepeatingGroupsEditContainer({ } }; + const nextClicked = () => { + setEditIndex(editIndex + 1, true); + if (container.edit?.multiPage) { + setMultiPageIndex(0); + } + }; + const removeClicked = () => { onClickRemove(editIndex); if (container.edit?.multiPage) { @@ -208,20 +221,46 @@ export function RepeatingGroupsEditContainer({ )} )} - {!hideSaveButton && ( - - )} + + {!hideSaveButton && + showSaveAndNextButton && + editIndex < repeatingGroupIndex && ( + + + + )} + {!hideSaveButton && ( + + + + )} + diff --git a/src/altinn-app-frontend/src/features/form/layout/index.ts b/src/altinn-app-frontend/src/features/form/layout/index.ts index 8b9c5c9208..050501fee8 100644 --- a/src/altinn-app-frontend/src/features/form/layout/index.ts +++ b/src/altinn-app-frontend/src/features/form/layout/index.ts @@ -326,6 +326,7 @@ export interface IGroupEditProperties { deleteButton?: boolean; multiPage?: boolean; openByDefault?: boolean | 'first' | 'last'; + saveAndNextButton?: boolean; } export interface IGroupFilter { diff --git a/src/shared/src/components/molecules/AltinnMobileTableItem.tsx b/src/shared/src/components/molecules/AltinnMobileTableItem.tsx index 62d6f146d1..a323a65942 100644 --- a/src/shared/src/components/molecules/AltinnMobileTableItem.tsx +++ b/src/shared/src/components/molecules/AltinnMobileTableItem.tsx @@ -134,7 +134,7 @@ const useStyles = makeStyles({ }, }, editButtonCell: { - width: '120px', + width: '140px', padding: '0 !important', '@media (max-width: 768px)': { width: '50px', diff --git a/src/shared/src/language/texts/en.ts b/src/shared/src/language/texts/en.ts index 1e30b4322b..e705b62911 100644 --- a/src/shared/src/language/texts/en.ts +++ b/src/shared/src/language/texts/en.ts @@ -133,6 +133,7 @@ export function en() { required: 'Required', save: 'Save', save_and_close: 'Save and close', + save_and_next: 'Save and open next', search: 'Search', select_field: 'Select field', service_description_header: 'Description', diff --git a/src/shared/src/language/texts/nb.ts b/src/shared/src/language/texts/nb.ts index 047c7bffa4..486d24083e 100644 --- a/src/shared/src/language/texts/nb.ts +++ b/src/shared/src/language/texts/nb.ts @@ -133,6 +133,7 @@ export function nb() { required: 'Obligatorisk', save: 'Lagre', save_and_close: 'Lagre og lukk', + save_and_next: 'Lagre og åpne neste', search: 'Søk', select_field: 'Velg felt', service_description_header: 'Beskrivelse', diff --git a/src/shared/src/language/texts/nn.ts b/src/shared/src/language/texts/nn.ts index 3e1bf21704..be8b6cdf0d 100644 --- a/src/shared/src/language/texts/nn.ts +++ b/src/shared/src/language/texts/nn.ts @@ -131,6 +131,7 @@ export function nn() { required: 'Obligatorisk', save: 'Lagre', save_and_close: 'Lagre og lukk', + save_and_next: 'Lagre og opne neste', search: 'Søk', select_field: 'Vel felt', service_description_header: 'Beskriving',