Skip to content

Commit bc7fb7f

Browse files
authored
Merge pull request #2225 from navikt/flere-nivaer-i-mellomsteg
Legger til ekstra steg i mellomsteg og forenkler typingen noe
2 parents 54501a8 + 11c5042 commit bc7fb7f

File tree

5 files changed

+200
-154
lines changed

5 files changed

+200
-154
lines changed

packages/nextjs/src/components/pages/form-intermediate-step-page/FormIntermediateStepLink.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { LinkPanel } from '@navikt/ds-react';
33
import { InfoBox } from 'components/_common/infoBox/InfoBox';
44
import { LenkeBase } from 'components/_common/lenke/lenkeBase/LenkeBase';
5-
import { FormIntermediateStep_StepLinkData } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPageState';
5+
import { FormIntermediateStep_StepLinkData } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPage';
66
import { EditorHelp } from 'components/_editor-only/editor-help/EditorHelp';
77

88
type Props = FormIntermediateStep_StepLinkData &
@@ -14,6 +14,8 @@ export const FormIntermediateStepLink = ({
1414
languageDisclaimer,
1515
href,
1616
isStepNavigation,
17+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
18+
nextStep,
1719
...rest
1820
}: Props) => {
1921
if (!href) {

packages/nextjs/src/components/pages/form-intermediate-step-page/FormIntermediateStepPage.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ThemedPageHeader } from 'components/_common/headers/themedPageHeader/Th
55
import { FormIntermediateStepPageProps } from 'types/content-props/form-intermediate-step';
66
import { ParsedHtml } from 'components/_common/parsedHtml/ParsedHtml';
77
import { LenkeBase } from 'components/_common/lenke/lenkeBase/LenkeBase';
8-
import { useFormIntermediateStepPageState } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPageState';
8+
import { useFormIntermediateStepPage } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPage';
99
import { FormIntermediateStepLink } from 'components/pages/form-intermediate-step-page/FormIntermediateStepLink';
1010

1111
import style from './FormIntermediateStepPage.module.scss';
@@ -14,7 +14,7 @@ export const FormIntermediateStepPage = (props: FormIntermediateStepPageProps) =
1414
const { language, type, displayName, modifiedTime, data } = props;
1515
const { title, illustration } = data;
1616

17-
const { currentStepData, backUrl } = useFormIntermediateStepPageState(props);
17+
const { currentStepData, backUrl, previousStepTitle } = useFormIntermediateStepPage(props);
1818

1919
const getTranslations = translator('form', language);
2020

@@ -37,6 +37,7 @@ export const FormIntermediateStepPage = (props: FormIntermediateStepPageProps) =
3737
<div className={style.content}>
3838
<div className={style.stepOptionsWrapper}>
3939
<ParsedHtml htmlProps={currentStepData.editorial} />
40+
{previousStepTitle && <div>Forrige steg: {previousStepTitle}</div>}
4041
{currentStepData.stepsHeadline && (
4142
<Heading level={'2'} size={'medium'} spacing>
4243
{currentStepData.stepsHeadline}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { useEffect, useState } from 'react';
2+
import { useRouter } from 'next/compat/router';
3+
import {
4+
FormIntermediateStepPageProps,
5+
SelectableStep,
6+
StepBase,
7+
} from 'types/content-props/form-intermediate-step';
8+
import { stripXpPathPrefix } from 'utils/urls';
9+
10+
const STEP_PARAM = 'stegvalg';
11+
12+
export type FormIntermediateStep_StepLinkData = SelectableStep & {
13+
href?: string;
14+
isStepNavigation?: boolean;
15+
};
16+
17+
type StepPath = number[];
18+
const buildStepUrl = (basePath: string, stepPath: StepPath) =>
19+
`${basePath}?${STEP_PARAM}=${stepPath.join(',')}`;
20+
21+
const resolveStepUrl = ({
22+
step,
23+
nextStepPath,
24+
basePath,
25+
}: {
26+
step: SelectableStep;
27+
nextStepPath: StepPath;
28+
basePath: string;
29+
}): FormIntermediateStep_StepLinkData => {
30+
switch (step.nextStep?._selected) {
31+
case 'external': {
32+
return {
33+
...step,
34+
href: step.nextStep.external?.externalUrl,
35+
};
36+
}
37+
case 'internal': {
38+
return {
39+
...step,
40+
href: stripXpPathPrefix(step.nextStep.internal?.internalContent._path),
41+
};
42+
}
43+
default: {
44+
return {
45+
...step,
46+
href: buildStepUrl(basePath, nextStepPath),
47+
isStepNavigation: true,
48+
};
49+
}
50+
}
51+
};
52+
53+
const getStepData = (data: FormIntermediateStepPageProps['data'], stepPath: StepPath): StepBase => {
54+
// No steps selected (meaning the user is on first step)
55+
if (stepPath.length === 0) {
56+
return {
57+
editorial: data.editorial,
58+
stepsHeadline: data.stepsHeadline,
59+
steps: data.steps,
60+
};
61+
}
62+
63+
let tmp: any = data;
64+
65+
stepPath.forEach((index) => {
66+
const foundStep = tmp.steps[index];
67+
if (foundStep) {
68+
tmp = foundStep.nextStep?.next;
69+
}
70+
});
71+
72+
const stepDetails = tmp.nextStep;
73+
if (stepDetails?._selected === 'next') {
74+
return stepDetails.next;
75+
}
76+
77+
return {
78+
editorial: tmp.editorial,
79+
stepsHeadline: tmp.stepsHeadline,
80+
steps: tmp.steps,
81+
};
82+
};
83+
84+
const buildCurrentStepData = (
85+
allData: FormIntermediateStepPageProps['data'],
86+
basePath: string,
87+
stepPath: StepPath
88+
): StepBase => {
89+
const stepData = getStepData(allData, stepPath);
90+
91+
return {
92+
...stepData,
93+
steps: stepData.steps.map((step, index) =>
94+
resolveStepUrl({ step, nextStepPath: [...stepPath, index], basePath })
95+
),
96+
};
97+
};
98+
99+
const buildBackUrl = (basePath: string, stepPath: StepPath): string | null => {
100+
if (stepPath.length === 0) {
101+
return null; // No back URL if on the first step
102+
}
103+
104+
if (stepPath.length === 1) {
105+
return basePath; // Back to the first step
106+
}
107+
return buildStepUrl(basePath, stepPath.slice(0, -1));
108+
};
109+
110+
const getStepPathFromParam = (url: string): StepPath => {
111+
const stepQuery = new URL(url, window.location.origin).searchParams.get(STEP_PARAM);
112+
const stepPath = stepQuery ? stepQuery.split(',').map(Number) : [];
113+
if (stepPath.some(isNaN)) {
114+
return [];
115+
}
116+
return stepPath;
117+
};
118+
119+
const getPreviousStepTitle = (
120+
stepPath: StepPath,
121+
allData: FormIntermediateStepPageProps['data']
122+
) => {
123+
if (stepPath.length === 0) {
124+
return null; // No previous step title if on the first step
125+
}
126+
127+
const previousStepPath = stepPath.slice(0, -1);
128+
129+
// Previous step was the first page, so just get the
130+
// headline from the data root.
131+
if (previousStepPath.length === 0) {
132+
return allData.stepsHeadline;
133+
}
134+
135+
// Traverse the tree to find the previous step.
136+
let step: StepBase = allData;
137+
previousStepPath.forEach((index) => {
138+
const foundStep = step.steps[index];
139+
if (foundStep) {
140+
step = foundStep.nextStep?.next;
141+
}
142+
});
143+
144+
return step.stepsHeadline;
145+
};
146+
147+
export const useFormIntermediateStepPage = (props: FormIntermediateStepPageProps) => {
148+
const [stepPath, setStepPath] = useState<StepPath>([]);
149+
const router = useRouter();
150+
151+
const pagePath = stripXpPathPrefix(props._path);
152+
const currentStepData = buildCurrentStepData(props.data, pagePath, stepPath);
153+
154+
const backUrl = buildBackUrl(pagePath, stepPath);
155+
const previousStepTitle = getPreviousStepTitle(stepPath, props.data);
156+
157+
useEffect(() => {
158+
if (!router) {
159+
return;
160+
}
161+
162+
const handleRouteChange = (url: string) => {
163+
setStepPath(getStepPathFromParam(url));
164+
};
165+
166+
handleRouteChange(router.asPath);
167+
168+
router.events.on('routeChangeComplete', handleRouteChange);
169+
return () => {
170+
router.events.off('routeChangeComplete', handleRouteChange);
171+
};
172+
}, [router]);
173+
174+
return {
175+
currentStepData,
176+
backUrl,
177+
previousStepTitle,
178+
};
179+
};

packages/nextjs/src/components/pages/form-intermediate-step-page/useFormIntermediateStepPageState.tsx

-119
This file was deleted.

0 commit comments

Comments
 (0)