Skip to content

Rebuilding hideEmptyFields in Summary2 #3336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f7c01ff
Making it possible for each component to decide if they are 'empty' o…
Apr 29, 2025
19da195
I forgot to invert this value
May 5, 2025
a370533
A much better empty-check will read the raw data and also consider ro…
May 5, 2025
291ca02
The empty-check in RepeatingGroup did not account for hidden rows, wh…
May 6, 2025
95df940
Using a context that registers which components are empty and which a…
May 6, 2025
d2f5368
Removing dash from Grid summary, as RepeatingGroup doesn't have it
May 6, 2025
65291ce
Whoops
May 6, 2025
c783647
Fixing missing node error that appeared after a while
May 6, 2025
b3caffd
Refactoring the system to register/unregister empty/non-empty rendere…
May 9, 2025
c0dac6b
This seems to fix the problems I had earlier, by always rendering the…
May 12, 2025
3a48d52
This looks like a better approach. Moving the summary flex component …
May 12, 2025
166a472
Respecting overrides from devTools, making things more robust (the se…
May 12, 2025
2dab05f
Minor fixes, type refinement
May 13, 2025
3573d27
Showing regular components as greyed-out as well when hidden in Summa…
May 13, 2025
5be51c0
Memoizing to avoid flashing the entire subform summary when opening d…
May 13, 2025
b2d67fc
Removing the useIsEmpty() hook and passing this as a prop to SummaryF…
May 13, 2025
7450090
Removing TODO (it wasn't all that feasible to implement in practice),…
May 13, 2025
b74f570
Making sure components hidden by expressions are also properly marked…
May 13, 2025
24f7816
Removing uneeded keys, no-rows-fallback that was never needed, props …
May 14, 2025
613bc02
Moving HideWhenAllChildrenEmpty, make sure it doesn't report itself
May 14, 2025
0ddaa5e
I tried adding a class that hides a Flex, but it didn't work because …
May 14, 2025
5226362
Missing check for false
May 14, 2025
27472a4
Whitespace fix after merge from main
May 14, 2025
be45bc1
Fix after signing was merged (this file was moved)
May 14, 2025
c8ccf87
Reverting this newline to reduce the diff with main
May 14, 2025
222418a
Renaming for clarity
May 14, 2025
2555ba0
Adding support for hiding a Group when all children are empty
May 14, 2025
d68710d
Clarification, adding jsdoc, renaming
May 14, 2025
766a98b
Rewriting to useReducer(), only actually re-rendering when the boolea…
May 14, 2025
6b1e4f3
Introducing an enum instead of boolean, setting content types such th…
May 14, 2025
5c46402
Making tabs a simple container summary
May 14, 2025
cb304df
Adding flex components for Signing components
May 14, 2025
f4158d5
The initalRender state did not make sense here, because the result wi…
May 15, 2025
8639250
Using useLayoutEffect() to prevent flickering
May 15, 2025
757edc1
Grid no longer prints '-' in empty cells
May 16, 2025
47e52fb
Maintaining mocks is fun! /s
May 16, 2025
3bbd9d5
Grouping pages in Summary2 and hiding entire pages if all components …
May 16, 2025
1ed49eb
Describing the concept more in comments.
May 19, 2025
6458c85
Implementing page-level hidden-overrides + some debugging output to e…
May 19, 2025
4f7fb4b
Fixing forceShow and using it for Group/container components so that …
May 19, 2025
fb419ba
Merge branch 'main' into bug/summary2-groups-hidden
May 19, 2025
a336b63
Adding a type for snapshot viewports. I planned on implementing more …
May 20, 2025
f79f6f5
The automatic reporting got in the way of the empty render reporting …
May 20, 2025
05fbb61
Implementing a test case that renders Summary2 for this app with hide…
May 20, 2025
9fbec45
Updating snapshot name
May 20, 2025
c124bed
Snapshotting Summary2 with hideEmptyFields for all process steps in t…
May 21, 2025
9c2866a
Merge branch 'main' into bug/summary2-groups-hidden
May 21, 2025
bd0ce0f
Fixing test
May 22, 2025
6496f3d
Merge branch 'main' into bug/summary2-groups-hidden
May 22, 2025
e1210ad
Moving the required check out from Summary2 as well. Having this buil…
May 23, 2025
c23070b
Mocked test broke again
May 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/app-components/Flex/Flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,13 @@ export const Flex = forwardRef<HTMLDivElement, Props>(

const styles: CSSProperties | undefined = container
? {
display: 'flex',
flexDirection: direction,
flexWrap,
justifyContent,
alignItems,
...style,
}
: {
display: 'block',
...style,
};
: style;

return (
<Tag
Expand Down
2 changes: 1 addition & 1 deletion src/features/form/layout/LayoutsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function useLayoutSetId() {
return layoutSetId ?? currentProcessLayoutSetId;
}

export function useDataTypeFromLayoutSet(layoutSetName: string) {
export function useDataTypeFromLayoutSet(layoutSetName: string | undefined) {
const layoutSets = useLayoutSets();
return layoutSets.find((set) => set.id === layoutSetName)?.dataType;
}
Expand Down
2 changes: 1 addition & 1 deletion src/features/pdf/PdfView2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function PdfForNode({ nodeId }: { nodeId: string }) {

const betaEnabled = getFeature('betaPDFenabled');
if (betaEnabled.value) {
return <ComponentSummary componentNode={node} />;
return <ComponentSummary target={node} />;
}

return (
Expand Down
2 changes: 1 addition & 1 deletion src/layout/AddToList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class AddToList extends AddToListDef {
return <AddToListFeatureFlagLayoutValidator {...props} />;
}
renderSummary(_: SummaryRendererProps<'AddToList'>): JSX.Element | null {
return <div>summary</div>;
return <div>summary</div>; // TODO: Implment?
}
render = forwardRef<HTMLElement, PropsFromGenericComponent<'AddToList'>>(
function LayoutComponentAddToListRender(props, _): JSX.Element | null {
Expand Down
157 changes: 86 additions & 71 deletions src/layout/Address/AddressSummary/AddressSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { ComponentValidations } from 'src/features/validation/ComponentValidatio
import { useBindingValidationsForNode } from 'src/features/validation/selectors/bindingValidationsForNode';
import classes from 'src/layout/Address/AddressSummary/AddressSummary.module.css';
import { SingleValueSummary } from 'src/layout/Summary2/CommonSummaryComponents/SingleValueSummary';
import { useHasNoDataInBindings } from 'src/layout/Summary2/isEmpty/isEmptyComponent';
import { SummaryContains, SummaryFlex } from 'src/layout/Summary2/SummaryComponent2/ComponentSummary';
import { useSummaryOverrides, useSummaryProp } from 'src/layout/Summary2/summaryStoreContext';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { LayoutNode } from 'src/utils/layout/LayoutNode';
Expand All @@ -15,124 +17,137 @@ interface AddressSummaryProps {
}

export function AddressSummary({ componentNode }: AddressSummaryProps) {
const { textResourceBindings, dataModelBindings, simplified } = useNodeItem(componentNode, (i) => ({
const { textResourceBindings, dataModelBindings, simplified, required } = useNodeItem(componentNode, (i) => ({
textResourceBindings: i.textResourceBindings,
dataModelBindings: i.dataModelBindings,
simplified: i.simplified,
required: i.required,
}));
const { title, careOfTitle, zipCodeTitle, postPlaceTitle, houseNumberTitle } = textResourceBindings ?? {};
const { formData } = useDataModelBindings(dataModelBindings);
const { address, postPlace, zipCode, careOf, houseNumber } = formData;
const emptyFieldText = useSummaryOverrides(componentNode)?.emptyFieldText;
const isCompact = useSummaryProp('isCompact');
const isEmpty = useHasNoDataInBindings(componentNode);

const bindingValidations = useBindingValidationsForNode(componentNode);

return (
<div className={classes.addressSummaryComponent}>
<div>
<SingleValueSummary
title={
<Lang
id={title || 'address_component.address'}
node={componentNode}
/>
}
displayData={address}
componentNode={componentNode}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.address}
node={componentNode}
/>
</div>

{!simplified && (
<SummaryFlex
target={componentNode}
content={
isEmpty
? required
? SummaryContains.EmptyValueRequired
: SummaryContains.EmptyValueNotRequired
: SummaryContains.SomeUserContent
}
>
<div className={classes.addressSummaryComponent}>
<div>
<SingleValueSummary
title={
<Lang
id={careOfTitle || 'address_component.care_of'}
id={title || 'address_component.address'}
node={componentNode}
/>
}
displayData={careOf}
displayData={address}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.careOf}
validations={bindingValidations?.address}
node={componentNode}
/>
</div>
)}

<div className={classes.addressSummaryComponentZipCode}>
<div className={classes.addressComponentZipCode}>
<SingleValueSummary
title={
<Lang
id={zipCodeTitle || 'address_component.zip_code'}
node={componentNode}
/>
}
displayData={zipCode}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.zipCode}
node={componentNode}
/>
</div>

<div className={classes.addressSummaryComponentPostplace}>
<SingleValueSummary
title={
<Lang
id={postPlaceTitle || 'address_component.post_place'}
node={componentNode}
/>
}
displayData={postPlace}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.postPlace}
node={componentNode}
/>
</div>
{!simplified && (
<div>
<SingleValueSummary
title={
<Lang
id={houseNumberTitle || 'address_component.house_number'}
id={careOfTitle || 'address_component.care_of'}
node={componentNode}
/>
}
displayData={houseNumber}
displayData={careOf}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.houseNumber}
validations={bindingValidations?.careOf}
node={componentNode}
/>
</div>
)}

<div className={classes.addressSummaryComponentZipCode}>
<div className={classes.addressComponentZipCode}>
<SingleValueSummary
title={
<Lang
id={zipCodeTitle || 'address_component.zip_code'}
node={componentNode}
/>
}
displayData={zipCode}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.zipCode}
node={componentNode}
/>
</div>

<div className={classes.addressSummaryComponentPostplace}>
<SingleValueSummary
title={
<Lang
id={postPlaceTitle || 'address_component.post_place'}
node={componentNode}
/>
}
displayData={postPlace}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.postPlace}
node={componentNode}
/>
</div>
{!simplified && (
<div>
<SingleValueSummary
title={
<Lang
id={houseNumberTitle || 'address_component.house_number'}
node={componentNode}
/>
}
displayData={houseNumber}
componentNode={componentNode}
hideEditButton={true}
isCompact={isCompact}
emptyFieldText={emptyFieldText}
/>
<ComponentValidations
validations={bindingValidations?.houseNumber}
node={componentNode}
/>
</div>
)}
</div>
</div>
</div>
</SummaryFlex>
);
}
42 changes: 30 additions & 12 deletions src/layout/Checkboxes/CheckboxesSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import React from 'react';

import { useDisplayData } from 'src/features/displayData/useDisplayData';
import { Lang } from 'src/features/language/Lang';
import { MultipleValueSummary } from 'src/layout/Summary2/CommonSummaryComponents/MultipleValueSummary';
import {
MultipleValueSummary,
useMultipleValuesForSummary,
} from 'src/layout/Summary2/CommonSummaryComponents/MultipleValueSummary';
import { SummaryContains, SummaryFlex } from 'src/layout/Summary2/SummaryComponent2/ComponentSummary';
import { useSummaryOverrides, useSummaryProp } from 'src/layout/Summary2/summaryStoreContext';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { Summary2Props } from 'src/layout/Summary2/SummaryComponent2/types';
Expand All @@ -18,19 +22,33 @@ export function CheckboxesSummary({ target }: Summary2Props<'Checkboxes'>) {
summaryOverride?.displayType === 'list' ||
(!summaryOverride?.displayType && displayData?.length >= maxStringLength);
const title = useNodeItem(componentNode, (i) => i.textResourceBindings?.title);
const required = useNodeItem(componentNode, (i) => i.required);
const displayValues = useMultipleValuesForSummary(target);

return (
<MultipleValueSummary
title={
<Lang
id={title}
node={componentNode}
/>
<SummaryFlex
target={target}
content={
displayValues.length === 0
? required
? SummaryContains.EmptyValueRequired
: SummaryContains.EmptyValueNotRequired
: SummaryContains.SomeUserContent
}
componentNode={componentNode}
isCompact={isCompact}
showAsList={showAsList}
emptyFieldText={emptyFieldText}
/>
>
<MultipleValueSummary
title={
<Lang
id={title}
node={componentNode}
/>
}
componentNode={componentNode}
displayValues={displayValues}
isCompact={isCompact}
showAsList={showAsList}
emptyFieldText={emptyFieldText}
/>
</SummaryFlex>
);
}
29 changes: 22 additions & 7 deletions src/layout/Custom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { useDisplayData } from 'src/features/displayData/useDisplayData';
import { CustomDef } from 'src/layout/Custom/config.def.generated';
import { CustomWebComponent } from 'src/layout/Custom/CustomWebComponent';
import { SummaryItemSimple } from 'src/layout/Summary/SummaryItemSimple';
import { useNodeFormData, useNodeFormDataWhenType } from 'src/utils/layout/useNodeItem';
import { useHasBindingsAndNoData } from 'src/layout/Summary2/isEmpty/isEmptyComponent';
import { SummaryContains, SummaryFlex } from 'src/layout/Summary2/SummaryComponent2/ComponentSummary';
import { useNodeFormData, useNodeFormDataWhenType, useNodeItem } from 'src/utils/layout/useNodeItem';
import type { PropsFromGenericComponent } from 'src/layout';
import type { SummaryRendererProps } from 'src/layout/LayoutComponent';
import type { Summary2Props } from 'src/layout/Summary2/SummaryComponent2/types';
Expand All @@ -29,13 +31,26 @@ export class Custom extends CustomDef {

renderSummary2(props: Summary2Props<'Custom'>): JSX.Element | null {
const formData = useNodeFormData(props.target);
const isEmpty = useHasBindingsAndNoData(props.target);
const required = useNodeItem(props.target, (i) => i.required);
return (
<CustomWebComponent
summaryMode={true}
formData={formData}
node={props.target}
containerDivRef={React.createRef()}
/>
<SummaryFlex
target={props.target}
content={
isEmpty
? required
? SummaryContains.EmptyValueRequired
: SummaryContains.EmptyValueNotRequired
: SummaryContains.SomeUserContent
}
>
<CustomWebComponent
summaryMode={true}
formData={formData}
node={props.target}
containerDivRef={React.createRef()}
/>
</SummaryFlex>
);
}

Expand Down
Loading