From 2b4ad09f85fd69f9fe83eb260bd500547643d2d4 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 20 Oct 2022 15:57:21 +0200 Subject: [PATCH] Fixed openByDefault to use filter --- .../form/containers/GroupContainer.tsx | 32 +++++------- .../layout/update/updateFormLayoutSagas.ts | 14 +++-- .../src/utils/formLayout.ts | 51 +++++++++++++++++++ 3 files changed, 74 insertions(+), 23 deletions(-) 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 a40128720e..a910d693a6 100644 --- a/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx +++ b/src/altinn-app-frontend/src/features/form/containers/GroupContainer.tsx @@ -11,7 +11,10 @@ import { RepeatingGroupTable } from 'src/features/form/containers/RepeatingGroup import { FormLayoutActions } from 'src/features/form/layout/formLayoutSlice'; import { makeGetHidden } from 'src/selectors/getLayoutData'; import { Triggers } from 'src/types'; -import { createRepeatingGroupComponents } from 'src/utils/formLayout'; +import { + createRepeatingGroupComponents, + getRepeatingGroupFilteredIndices, +} from 'src/utils/formLayout'; import { getHiddenFieldsForGroup } from 'src/utils/layout'; import { renderValidationMessagesForComponent } from 'src/utils/render'; import { repeatingGroupHasValidations } from 'src/utils/validation'; @@ -152,26 +155,15 @@ export function GroupContainer({ ); React.useEffect(() => { - if (container.edit?.filter && container.edit.filter.length > 0) { - container.edit.filter.forEach((rule) => { - const formDataKeys: string[] = Object.keys(formData).filter((key) => { - const keyWithoutIndex = key.replaceAll(/\[\d*\]/g, ''); - return keyWithoutIndex === rule.key && formData[key] === rule.value; - }); - if (formDataKeys && formDataKeys.length > 0) { - const filtered = formDataKeys.map((key) => { - const match = key.match(/\[(\d*)\]/g); - const currentIndex = match[match.length - 1]; - return parseInt( - currentIndex.substring(1, currentIndex.indexOf(']')), - 10, - ); - }); - setFilteredIndexList(filtered); - } - }); + const filteredIndexList = getRepeatingGroupFilteredIndices( + repeatingGroupIndex, + formData, + container.edit?.filter, + ); + if (filteredIndexList) { + setFilteredIndexList(filteredIndexList); } - }, [formData, container]); + }, [repeatingGroupIndex, formData, container]); const onClickAdd = useCallback(() => { dispatch(FormLayoutActions.updateRepeatingGroups({ layoutElementId: id })); diff --git a/src/altinn-app-frontend/src/features/form/layout/update/updateFormLayoutSagas.ts b/src/altinn-app-frontend/src/features/form/layout/update/updateFormLayoutSagas.ts index 659348664b..60aa5e76b0 100644 --- a/src/altinn-app-frontend/src/features/form/layout/update/updateFormLayoutSagas.ts +++ b/src/altinn-app-frontend/src/features/form/layout/update/updateFormLayoutSagas.ts @@ -38,6 +38,7 @@ import { } from 'src/utils/databindings'; import { findChildren, + getRepeatingGroupFilteredIndices, getRepeatingGroups, mapFileUploadersWithTag, removeRepeatingGroupFromUIConfig, @@ -675,12 +676,19 @@ export function* initRepeatingGroupsSaga(): SagaIterator { const container = groupContainers.find( (element) => element.id === key, ) as ILayoutGroup; - if (container && group.index >= 0) { + const filteredIndexList = getRepeatingGroupFilteredIndices( + group.index, + formDataState.formData, + container.edit?.filter, + ); + if (container.edit?.openByDefault === 'first') { - group.editIndex = 0; + group.editIndex = filteredIndexList ? filteredIndexList[0] : 0; } else if (container.edit?.openByDefault === 'last') { - group.editIndex = group.index; + group.editIndex = filteredIndexList + ? filteredIndexList.at(-1) + : group.index; } } }); diff --git a/src/altinn-app-frontend/src/utils/formLayout.ts b/src/altinn-app-frontend/src/utils/formLayout.ts index 30c7c7a9d4..d208a0cdd4 100644 --- a/src/altinn-app-frontend/src/utils/formLayout.ts +++ b/src/altinn-app-frontend/src/utils/formLayout.ts @@ -1,7 +1,9 @@ import { INDEX_KEY_INDICATOR_REGEX } from 'src/utils/databindings'; +import type { IFormData } from 'src/features/form/data'; import type { ComponentTypes, IGroupEditProperties, + IGroupFilter, ILayout, ILayoutComponent, ILayoutGroup, @@ -555,3 +557,52 @@ export function behavesLikeDataTask( ): boolean { return layoutSets?.sets.some((set) => set.tasks?.includes(task)); } + +/** + * Returns a list of remaining repeating group element indices after all filters are applied. Returns undefined if no filters are present. + * @param repeatingGroupIndex IRepeatingGroup.index for the repeating group. + * @param formData IFormData + * @param filter IGroupEditProperties.filter or undefined. + * @returns a list of indices for repeating group elements after applying filters, or null if no filters are provided. + */ +export function getRepeatingGroupFilteredIndices( + repeatingGroupIndex: number, + formData: IFormData, + filter?: IGroupFilter[], +): number[] | null { + if (filter && filter.length > 0) { + let filteredIndicies = Array.from(Array(repeatingGroupIndex + 1).keys()); + + filter.forEach((rule) => { + const formDataKeys: string[] = Object.keys(formData); + + if (formDataKeys && formDataKeys.length > 0) { + const matchingSet = new Set(); + + formDataKeys + .filter((key) => { + const keyWithoutIndex = key.replaceAll(/\[\d*\]/g, ''); + return keyWithoutIndex === rule.key && formData[key] === rule.value; + }) + .forEach((key) => { + const match = key.match(/\[(\d*)\]/g); + const currentIndex = match[match.length - 1]; + const matchingIndex = parseInt( + currentIndex.substring(1, currentIndex.indexOf(']')), + 10, + ); + matchingSet.add(matchingIndex); + }); + + filteredIndicies = filteredIndicies.filter((index) => + matchingSet.has(index), + ); + return Array.from(matchingSet); + } + }); + + return filteredIndicies; + } + + return null; +}