From 6cae5a1a9be90357ffc7ceeb063187398f6406a2 Mon Sep 17 00:00:00 2001 From: Daniel Eriksson Date: Wed, 19 Mar 2025 08:49:12 +0100 Subject: [PATCH 1/3] Update dependencies --- frontend/bun.lockb | Bin 135254 -> 135601 bytes frontend/package.json | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 388dd06c29795ac835be3813d2f4b60c49e0e86a..80ce987148e1991a43e21058d756449c5b12b149 100755 GIT binary patch delta 1498 zcmY*Z3s4hh5WWp4Bp66UkN}3DJQN~cE|0rV(O{**pcSe>R0J<10Y!=k_^5UOOIrm; z+g$Zpd5EIcwkSx7Cq;}3q0>OutnM+EEB-Px9mBCmh>Q z$Mfc~cpQQh+WqXg@Yl5n!ey;A*BtJ0l;`a25hyI0vZ#%+d8`2e1)jl_#?#rn)l=Y2 zE%upe2h;^r050}drerR~mAOz8{1sHR%=#}O8WW73&08@m*nzoF@uh&e?v0wGqa1^% zHgqQUd$zWctqoMXH_m;|qVQ3~QRbR2Wj^Hzfz>Hy+pu>cVIN?AoyqX{|8r9ti}Exf zyNYaG8tuw5ZF}AtELE6Nv%KS3VoX5f@+&hO+u!b=J?mhVV(nDfwfFR`k_2^Yks(rxc9wY;ZZMO1_*?EzYlX0%X{2n6;VqPyA*%o?>#MXxmH9 z&&S2}5d-Lv5=}bx)& z**UIprm57j>theC(}gL5nC;7IYi>9BnFkI@pdhiN-K_y>VgHqZphT%=ja)a#6TwAANI1=*p`T&yNl2 ziVsh99eQT-uU6b|qRdAQ7jiV&rmR@^^c20xD|h%tobcwk$3cBQJH-5Z-9dRL-PMMa z_b#7yel@=Jk#x2CaF17Kd;G=omo_Kcn6rr6oPj3Xob}xWPtC>mJ2te;3e&vEt*Z*^ zij`$;>xj%jyFG%>_TJ^KSa!8E$CA7tyWv)XW34v(tCyQv@+ynO(d;0#Cl6TMV~WiA zXSE7y`Jq_KYlu&^55__gB^pWstvP2X)rS&zPGGF#;cz5vbpRRfM1uW7B1mx(y=5_k zGmVR(4Y)}o&Na#OjzlPdNsK57oM4O}dyU0RpcdvkaFa(U0R}rI2ojln%OKNvvOOI; zrHDO)mfgkn-0apGM)>vRbch~8=r}!KAfrFhLjhp4g8|AxPFEQ~cy-`rFvllit2{eD`Dy$ilENc9;=qE5vhe0^qw-9 zOW!YpLSEe)r%1@GDu-TH1hcdfJ`sn=XP`PYhRew`otnT1gHdI`^*BM2YE*_PQB0@D z2%IG4DvaheLnVET%aPC>)i9R6+zgU`)b%%mGq8ztc$!R|MiQigNJ9yOLZ>!hauU;_ zxI(Wp$P9A1UZulHf}VX6r1U}y2-zSdf$Is3#0)YchLJd_HyRacR3|4CB&Lull}b#m zl9L2MKd``5rrrX-+e;~wM%u h&HyzLFsAqhe66H=_#8L7x)}oL(^ha|Lftr_@Hb416B_^k delta 1317 zcmYjP2~ZPf6y6tthR6|gj1cAUXo{e5v)SDwiW)(b3RRdw63=v#&B{z_i>U)BctEK| zEfQVr;uw#%*g&K@vU`@4J7!d77blNxb&->r|zW2TN9|yjc zT-z;ism4y*^WpB_DQ=*lrLD7WYtzEdh9&I3+K0)9N9k{V7c2KRMu?DrnKzl@L`69V ziuOwf2VyCLtnoS#Bt-C!oxYSoUMbr>G@rejoWQzWi;1fykOM*_*wu8oLPp1-MJb=0%}CbDCHgObC5|r4-r_Ug$dUO(g1Z z`V=2@NP`1Y#`z)(kG|frt)@@NDzBX)Ehz|5aehUbQm) z#_UbAXVvU9n7^6Qd*xx~OND=Wo@c`N+VhP^qwW7{H^W`KJmrkiKj3@xMsmlIs$(6O<|VJXAgb@% zwl-}{^2euY>y|8=UbW`uftOqNrk`F{7m`NKyjHyM*yb!>t|uN=SF~S8mCBBvPNFHE z&#T+4GOu=1@{IF%8bZbO_SWpnFH70@TeR8t1NMX8ND$cx1WF8Xl zqo=ID({WEx;ViBbE3*$TZVdNVv6dG4azW|{vg)_q82K-|DsL|u?eI14Ju5ftqCB-^ z&w_3{f3f5%;~Z~LP+#X%;#T&ugtYtdseO;Hb!^45ClwqBK3wwDbT{vlXG;~Ge&l|5 zT-(#0JxSs}eOG@p ztnz@au(IfWu4_A|vO^-bzz!-vxeaz$4Qg%>18xFCkS2i{E_`jro*7%yJ1gWO(5lp0 zm4LJgh)h71OfDJTSRM&)5dJ0uF#rVLvlxsKfN|M{5G^=IA-oers8F6Sgymzv%VoGB zTJ+e-F>c6|wr}sB=6yF;?}q7sa4+3ZDs{R0(+v^)`W@g8$gbE0Yhx3!37Af!CpB6| zqr(XeN!duP7T4Nng2L5yMq_2H7===(Ue6^qz)sF06UB4>8W_MmYJm7xb3`5o2?#Pf@Vlc%P=|(fvXupk7=!eyv~lQ^?JMBM(8=qF&M{vbOIuUBDD^q^%QPH?K(`0 zQ#6fIxYerB(KgbC>9jU0PNP;GMR0Hu68K9epgYh?gOY@eAnj@rwb>a|Afp6f(@=Jl h(&7OzQZF2YCIeL?c-bjnhk=@}X#)?zua$|C;9td{;FSOX diff --git a/frontend/package.json b/frontend/package.json index 36f8dd80..a02b74cb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,12 +14,12 @@ }, "devDependencies": { "@types/bun": "1.2.5", - "@types/react": "19.0.10", + "@types/react": "19.0.11", "@types/react-dom": "19.0.4", "@types/react-redux": "7.1.34", "@vitejs/plugin-react": "4.3.4", "typescript": "5.8.2", - "vite": "6.2.1", + "vite": "6.2.2", "vite-tsconfig-paths": "5.1.4" }, "dependencies": { @@ -27,9 +27,9 @@ "@grafana/faro-react": "1.14.1", "@grafana/faro-web-sdk": "1.14.1", "@grafana/faro-web-tracing": "1.14.1", - "@navikt/aksel-icons": "7.17.2", - "@navikt/ds-css": "7.17.2", - "@navikt/ds-react": "7.17.2", + "@navikt/aksel-icons": "7.17.3", + "@navikt/ds-css": "7.17.3", + "@navikt/ds-react": "7.17.3", "@navikt/fnrvalidator": "2.1.5", "@navikt/nav-dekoratoren-moduler": "3.2.2", "@reduxjs/toolkit": "2.6.1", @@ -40,6 +40,6 @@ "react-redux": "9.2.0", "react-router": "7.3.0", "react-router-dom": "7.3.0", - "styled-components": "6.1.15" + "styled-components": "6.1.16" } } From aaf950640a66f83e0146e394630855e0c0652137 Mon Sep 17 00:00:00 2001 From: Daniel Eriksson Date: Wed, 19 Mar 2025 08:50:21 +0100 Subject: [PATCH 2/3] Remove option to override internal saksnummer --- .../src/components/case/common/saksnummer.tsx | 74 +++++++++---------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/frontend/src/components/case/common/saksnummer.tsx b/frontend/src/components/case/common/saksnummer.tsx index 00fde3fb..2751b32b 100644 --- a/frontend/src/components/case/common/saksnummer.tsx +++ b/frontend/src/components/case/common/saksnummer.tsx @@ -1,18 +1,19 @@ import { FormFieldsIds } from '@app/components/case/common/form-fields-ids'; import { useTranslation } from '@app/language/use-translation'; -import { PencilIcon } from '@navikt/aksel-icons'; -import { BodyShort, Button, Label, TextField } from '@navikt/ds-react'; -import { useEffect, useRef, useState } from 'react'; -import { styled } from 'styled-components'; +import { BodyShort, Heading, TextField } from '@navikt/ds-react'; +import { useEffect, useState } from 'react'; -interface Props { +interface UserSaksnummerProps { value: string | null; - internalSaksnummer?: string | null; onChange: (saksnummer: string | null) => void; error: string | undefined; } -export const DebouncedSaksnummer = ({ value, onChange, ...props }: Props) => { +interface Props extends UserSaksnummerProps { + internalSaksnummer: string | null; +} + +const DebouncedUserSaksnummer = ({ value, onChange, error }: UserSaksnummerProps) => { const [localValue, setLocalValue] = useState(value); useEffect(() => { @@ -25,14 +26,26 @@ export const DebouncedSaksnummer = ({ value, onChange, ...props }: Props) => { return () => clearTimeout(timeout); }, [onChange, value, localValue]); - return ; + return ; }; -export const Saksnummer = ({ value, internalSaksnummer, onChange, error }: Props) => { - const inputRef = useRef(null); +const InternalSaksnummer = ({ internalSaksnummer }: { internalSaksnummer: string }) => { const { skjema } = useTranslation(); - const usersaksnummer = ( + if (typeof internalSaksnummer === 'string' && internalSaksnummer.length !== 0) { + return ( +
+ {skjema.begrunnelse.saksnummer.internalTitle} + {internalSaksnummer} +
+ ); + } +}; + +const UserSaksnummer = ({ value, onChange, error }: UserSaksnummerProps) => { + const { skjema } = useTranslation(); + + return ( onChange(target.value)} htmlSize={24} error={error} - ref={inputRef} /> ); +}; - if (value !== null) { - return usersaksnummer; +export const Saksnummer = ({ value, internalSaksnummer, onChange, error }: Props) => { + if (typeof internalSaksnummer === 'string' && internalSaksnummer.length !== 0) { + return ; } + return ; +}; + +export const DebouncedSaksnummer = ({ value, internalSaksnummer, onChange, error }: Props) => { if (typeof internalSaksnummer === 'string' && internalSaksnummer.length !== 0) { - return ( -
- - - {internalSaksnummer} -
- ); + return ; } - return usersaksnummer; + return ; }; - -const Row = styled.div` - display: flex; - flex-direction: row; - align-items: center; - column-gap: 8px; -`; From 861af08747cf239beafed9e640c24a35c5dcc34c Mon Sep 17 00:00:00 2001 From: Daniel Eriksson Date: Fri, 21 Mar 2025 09:16:17 +0100 Subject: [PATCH 3/3] Support new deep link props + organize all deep link props together --- .../begrunnelse/begrunnelse-page.tsx | 4 +- .../case/uinnlogget/session-loader.tsx | 13 ++++- .../src/components/case/uinnlogget/types.ts | 6 +-- frontend/src/hooks/use-session-klage.ts | 15 ++---- frontend/src/logging/action.ts | 2 +- frontend/src/redux-api/case/api.ts | 4 +- frontend/src/redux-api/case/params.ts | 26 ++-------- frontend/src/redux-api/case/types.ts | 41 +++++++++------ frontend/src/redux/session/klage/helpers.ts | 18 +++---- frontend/src/redux/session/klage/reducers.ts | 30 ++++++----- frontend/src/redux/session/klage/types.ts | 6 +-- frontend/src/routes/create-case/handlers.ts | 51 ++++++++---------- frontend/src/routes/create-case/use-case.ts | 52 ++++++------------- 13 files changed, 118 insertions(+), 150 deletions(-) diff --git a/frontend/src/components/case/innlogget/begrunnelse/begrunnelse-page.tsx b/frontend/src/components/case/innlogget/begrunnelse/begrunnelse-page.tsx index 8658da1a..6601b5cf 100644 --- a/frontend/src/components/case/innlogget/begrunnelse/begrunnelse-page.tsx +++ b/frontend/src/components/case/innlogget/begrunnelse/begrunnelse-page.tsx @@ -14,7 +14,7 @@ import { useTranslation } from '@app/language/use-translation'; import { AppEventEnum } from '@app/logging/action'; import { appEvent } from '@app/logging/logger'; import { useDeleteAttachmentMutation, useDeleteCaseMutation, useUpdateCaseMutation } from '@app/redux-api/case/api'; -import { type Case, CaseStatus, CaseType, type CaseUpdatable } from '@app/redux-api/case/types'; +import { type Case, CaseStatus, CaseType, type UpdateCaseFields } from '@app/redux-api/case/types'; import { API_PATH } from '@app/redux-api/common'; import { CenteredContainer } from '@app/styled-components/common'; import { BodyLong, Button, GuidePanel } from '@navikt/ds-react'; @@ -89,7 +89,7 @@ const RenderCasebegrunnelsePage = ({ data }: Props) => { const isEttersendelseKlage = data.type === CaseType.ETTERSENDELSE_KLAGE; const onChange = useCallback( - async (key: T, value: CaseUpdatable[T]) => { + async (key: T, value: UpdateCaseFields[T]) => { await updateCase({ key, value, id: data.id }); }, [data.id, updateCase], diff --git a/frontend/src/components/case/uinnlogget/session-loader.tsx b/frontend/src/components/case/uinnlogget/session-loader.tsx index d0948345..a3ee08e0 100644 --- a/frontend/src/components/case/uinnlogget/session-loader.tsx +++ b/frontend/src/components/case/uinnlogget/session-loader.tsx @@ -4,7 +4,8 @@ import { useIsAuthenticated } from '@app/hooks/use-user'; import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; import { useLanguage } from '@app/language/use-language'; import { useTranslation } from '@app/language/use-translation'; -import { CASE_TYPE_PATH_SEGMENTS, type CaseType } from '@app/redux-api/case/types'; +import { CASE_TYPE_PATH_SEGMENTS, type CaseType, type DeepLinkParams } from '@app/redux-api/case/types'; +import { useMemo } from 'react'; import { Navigate, useSearchParams } from 'react-router-dom'; import { LoadingPage } from '../../loading-page/loading-page'; import type { ISessionCase } from './types'; @@ -19,8 +20,16 @@ export const KlageSessionLoader = ({ Component, innsendingsytelse, type }: Props const { isAuthenticated, isLoadingAuth } = useIsAuthenticated(); const [query] = useSearchParams(); const internalSaksnummer = getQueryValue(query.get('saksnummer')); + const sakSakstype = getQueryValue(query.get('sakstype')); + const sakFagsaksystem = getQueryValue(query.get('fagsystem')); const caseIsAtKA = getBooleanQueryValue(query.get('ka')) ? true : null; - const [data, isLoading] = useSessionCase(type, innsendingsytelse, internalSaksnummer, caseIsAtKA); + + const deepLinkParams: DeepLinkParams = useMemo( + () => ({ internalSaksnummer, sakSakstype, sakFagsaksystem, caseIsAtKA }), + [internalSaksnummer, sakSakstype, sakFagsaksystem, caseIsAtKA], + ); + + const [data, isLoading] = useSessionCase(type, innsendingsytelse, deepLinkParams); const { case_loader: klage_loader, user_loader } = useTranslation(); const language = useLanguage(); diff --git a/frontend/src/components/case/uinnlogget/types.ts b/frontend/src/components/case/uinnlogget/types.ts index 52b94ae7..85ea25b4 100644 --- a/frontend/src/components/case/uinnlogget/types.ts +++ b/frontend/src/components/case/uinnlogget/types.ts @@ -1,18 +1,16 @@ import type { ISODate } from '@app/domain/date/date'; import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; -import type { CaseType, Reason } from '@app/redux-api/case/types'; +import type { CaseType, DeepLinkParams, Reason } from '@app/redux-api/case/types'; import type { IName } from '@app/redux-api/user/types'; -export interface ISessionCase { +export interface ISessionCase extends DeepLinkParams { readonly id: string; readonly type: CaseType; readonly checkboxesSelected: Reason[]; readonly foedselsnummer: string; readonly navn: IName; - readonly caseIsAtKA: boolean | null; readonly fritekst: string; readonly userSaksnummer: string | null; - readonly internalSaksnummer: string | null; readonly vedtakDate: ISODate | null; readonly innsendingsytelse: Innsendingsytelse; readonly hasVedlegg: boolean; diff --git a/frontend/src/hooks/use-session-klage.ts b/frontend/src/hooks/use-session-klage.ts index e9b91f61..40f52b22 100644 --- a/frontend/src/hooks/use-session-klage.ts +++ b/frontend/src/hooks/use-session-klage.ts @@ -1,6 +1,6 @@ import type { ISessionCase } from '@app/components/case/uinnlogget/types'; import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; -import type { CaseType } from '@app/redux-api/case/types'; +import type { CaseType, DeepLinkParams } from '@app/redux-api/case/types'; import { useAppDispatch, useAppSelector } from '@app/redux/configure-store'; import { getSessionCaseKey } from '@app/redux/session/klage/helpers'; import { loadOrCreateSessionCase } from '@app/redux/session/session'; @@ -9,8 +9,7 @@ import { useEffect, useMemo } from 'react'; export const useSessionCase = ( type: CaseType, innsendingsytelse: Innsendingsytelse, - internalSaksnummer: string | null, - caseIsAtKA: true | null, + deepLinkParams: DeepLinkParams, ): [ISessionCase, false] | [undefined, true] => { const dispatch = useAppDispatch(); const sessionCaseMap = useAppSelector((state) => state.session); @@ -22,15 +21,9 @@ export const useSessionCase = ( useEffect(() => { if (data === undefined) { - dispatch( - loadOrCreateSessionCase({ - type, - innsendingsytelse, - data: { innsendingsytelse, internalSaksnummer, caseIsAtKA }, - }), - ); + dispatch(loadOrCreateSessionCase({ type, innsendingsytelse, deepLinkParams })); } - }, [dispatch, innsendingsytelse, internalSaksnummer, data, type, caseIsAtKA]); + }, [data, dispatch, deepLinkParams, innsendingsytelse, type]); if (data === undefined) { return [undefined, true]; diff --git a/frontend/src/logging/action.ts b/frontend/src/logging/action.ts index 1f4de7ca..e73d6beb 100644 --- a/frontend/src/logging/action.ts +++ b/frontend/src/logging/action.ts @@ -11,7 +11,7 @@ export enum AppEventEnum { CASE_INVALID = 'Invalid case data', CASE_JOURNALFØRT = 'Case journalført', CASE_RESUME_SESSION = 'Resume session case', - CASE_RESUME_SESSION_WITH_SAKSNUMMER = 'Resume session case with internal saksnummer', + CASE_RESUME_SESSION_WITH_CHANGED_DEEP_LINK = 'Resume session case changed deep link', CASE_SUBMIT = 'Click submit button', CASE_VALID = 'Valid case data', CLEAR_ERRORS = 'Clear errors', diff --git a/frontend/src/redux-api/case/api.ts b/frontend/src/redux-api/case/api.ts index ddc41aa2..c382f006 100644 --- a/frontend/src/redux-api/case/api.ts +++ b/frontend/src/redux-api/case/api.ts @@ -1,7 +1,6 @@ import { AppEventEnum } from '@app/logging/action'; import { appEvent } from '@app/logging/logger'; import type { - CreateCaseParams, DeleteAttachmentParams, ResumeCaseParams, UpdateCaseParams, @@ -11,6 +10,7 @@ import { type Attachment, type BaseCase, type Case, CaseStatus, type FinalizedCa import { API_BASE_QUERY, API_PATH } from '@app/redux-api/common'; import { ServerSentEventManager, ServerSentEventType } from '@app/redux-api/server-sent-events'; import { createApi } from '@reduxjs/toolkit/query/react'; +import type { CreateCaseFields } from './types'; type BaseUpdateResponse = Pick; @@ -59,7 +59,7 @@ export const caseApi = createApi({ dispatch(caseApi.util.updateQueryData('getCase', data.id, () => data)); }, }), - createCase: builder.mutation({ + createCase: builder.mutation({ query: (body) => ({ method: 'POST', url: '/klanker', diff --git a/frontend/src/redux-api/case/params.ts b/frontend/src/redux-api/case/params.ts index b5375f81..54121321 100644 --- a/frontend/src/redux-api/case/params.ts +++ b/frontend/src/redux-api/case/params.ts @@ -1,27 +1,13 @@ import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; -import type { BaseCase, CaseType, CaseUpdatable } from '@app/redux-api/case/types'; +import type { BaseCase, CaseType, DeepLinkParams, UpdateCaseFields } from '@app/redux-api/case/types'; -export type CreateCaseParams = Pick< - BaseCase, - | 'innsendingsytelse' - | 'userSaksnummer' - | 'vedtakDate' - | 'internalSaksnummer' - | 'fritekst' - | 'hasVedlegg' - | 'type' - | 'caseIsAtKA' - | 'checkboxesSelected' - | 'language' ->; - -interface CaseUpdate { +interface CaseUpdate { readonly id: BaseCase['id']; readonly key: T; - readonly value: CaseUpdatable[T]; + readonly value: UpdateCaseFields[T]; } -export type UpdateCaseParams = CaseUpdate; +export type UpdateCaseParams = CaseUpdate; export interface UploadAttachmentParams { file: File; @@ -33,9 +19,7 @@ export interface DeleteAttachmentParams { attachmentId: number; } -export interface ResumeCaseParams { +export interface ResumeCaseParams extends DeepLinkParams { readonly type: CaseType; readonly innsendingsytelse: Innsendingsytelse; - readonly internalSaksnummer: string | null; - readonly caseIsAtKA: true | null; } diff --git a/frontend/src/redux-api/case/types.ts b/frontend/src/redux-api/case/types.ts index 13390cdf..79847645 100644 --- a/frontend/src/redux-api/case/types.ts +++ b/frontend/src/redux-api/case/types.ts @@ -15,29 +15,37 @@ export interface FinalizedCase { readonly modifiedByUser: ISODateTime; } -export interface BaseCase { +export interface DeepLinkParams { + readonly caseIsAtKA: boolean | null; + readonly internalSaksnummer: string | null; + readonly sakFagsaksystem: string | null; + readonly sakSakstype: string | null; +} + +interface ReadOnlyFields { readonly id: string; - readonly fritekst: string; - readonly status: CaseStatus; + readonly finalizedDate: ISODate | null; + readonly journalpostId: string | null; readonly modifiedByUser: ISODateTime; + readonly status: CaseStatus; readonly vedlegg: Attachment[]; - readonly journalpostId: string | null; - readonly finalizedDate: ISODate | null; - readonly vedtakDate: ISODate | null; - readonly userSaksnummer: string | null; - readonly internalSaksnummer: string | null; - readonly language: Languages; - readonly innsendingsytelse: Innsendingsytelse; +} + +export interface UpdateCaseFields extends DeepLinkParams { + readonly checkboxesSelected: Reason[]; + readonly fritekst: string; readonly hasVedlegg: boolean; + readonly userSaksnummer: string | null; + readonly vedtakDate: ISODate | null; +} + +export interface CreateCaseFields extends UpdateCaseFields { readonly type: CaseType; - readonly checkboxesSelected: Reason[]; - readonly caseIsAtKA: boolean | null; + readonly innsendingsytelse: Innsendingsytelse; + readonly language: Languages; } -export type CaseUpdatable = Pick< - BaseCase, - 'vedtakDate' | 'checkboxesSelected' | 'userSaksnummer' | 'hasVedlegg' | 'fritekst' | 'caseIsAtKA' ->; +export type BaseCase = ReadOnlyFields & CreateCaseFields; export interface Klage extends BaseCase { readonly type: CaseType.KLAGE; @@ -52,7 +60,6 @@ export interface Anke extends BaseCase { export interface EttersendelseKlage extends BaseCase { readonly type: CaseType.ETTERSENDELSE_KLAGE; - readonly caseIsAtKA: boolean | null; } export interface EttersendelseAnke extends BaseCase { diff --git a/frontend/src/redux/session/klage/helpers.ts b/frontend/src/redux/session/klage/helpers.ts index e1b3d5a0..195011d9 100644 --- a/frontend/src/redux/session/klage/helpers.ts +++ b/frontend/src/redux/session/klage/helpers.ts @@ -1,17 +1,18 @@ import type { ISessionCase } from '@app/components/case/uinnlogget/types'; import { getUniqueId } from '@app/functions/uuid'; import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; -import type { CaseType } from '@app/redux-api/case/types'; +import type { CaseType, DeepLinkParams } from '@app/redux-api/case/types'; export const getSessionCaseKey = (type: CaseType, ytelse: Innsendingsytelse): string => `klang-${type}-${ytelse}`.toLowerCase(); -export const createSessionCase = ( - type: CaseType, - innsendingsytelse: Innsendingsytelse, - internalSaksnummer: string | null, - caseIsAtKA: true | null, -): ISessionCase => ({ +interface Params { + type: CaseType; + innsendingsytelse: Innsendingsytelse; + deepLinkParams: DeepLinkParams; +} + +export const createSessionCase = ({ type, innsendingsytelse, deepLinkParams }: Params): ISessionCase => ({ id: getUniqueId(), type, innsendingsytelse, @@ -21,11 +22,10 @@ export const createSessionCase = ( etternavn: '', }, fritekst: '', - internalSaksnummer, userSaksnummer: null, vedtakDate: null, checkboxesSelected: [], hasVedlegg: false, modifiedByUser: new Date().toISOString(), - caseIsAtKA, + ...deepLinkParams, }); diff --git a/frontend/src/redux/session/klage/reducers.ts b/frontend/src/redux/session/klage/reducers.ts index 731be1cb..75255abc 100644 --- a/frontend/src/redux/session/klage/reducers.ts +++ b/frontend/src/redux/session/klage/reducers.ts @@ -1,6 +1,7 @@ import type { ISessionCase } from '@app/components/case/uinnlogget/types'; import { sessionEvent } from '@app/logging/logger'; import { SessionAction } from '@app/logging/types'; +import type { DeepLinkParams } from '@app/redux-api/case/types'; import type { State } from '@app/redux/session/type'; import type { CaseReducer, PayloadAction } from '@reduxjs/toolkit'; import { createSessionCase, getSessionCaseKey } from './helpers'; @@ -54,7 +55,7 @@ const loadSessionCase: CaseReducer> = (sta lastUpdated = 0; sessionEvent(SessionAction.LOAD); - const { innsendingsytelse, type, data } = payload; + const { innsendingsytelse, type, deepLinkParams } = payload; const sessionKey = getSessionCaseKey(type, innsendingsytelse); const savedCase = readSessionCase(sessionKey); @@ -63,24 +64,20 @@ const loadSessionCase: CaseReducer> = (sta return state; } - return setState(state, sessionKey, { - ...savedCase, - internalSaksnummer: data.internalSaksnummer, - caseIsAtKA: data.caseIsAtKA === null ? savedCase.caseIsAtKA : data.caseIsAtKA, - }); + return setState(state, sessionKey, mergeCaseAndDeepLinkParams(savedCase, deepLinkParams)); }; // Read from session storage if it exists, otherwise save to session storage. const loadOrCreateSessionCase: CaseReducer> = (state, { payload }) => { lastUpdated = 0; - const { innsendingsytelse, data, type } = payload; + const { innsendingsytelse, deepLinkParams, type } = payload; const sessionKey = getSessionCaseKey(type, innsendingsytelse); const savedCase = readSessionCase(sessionKey); if (savedCase === undefined) { - const newCase = createSessionCase(type, data.innsendingsytelse, data.internalSaksnummer, data.caseIsAtKA); + const newCase = createSessionCase({ type, innsendingsytelse, deepLinkParams }); const key = saveSessionCase(innsendingsytelse, newCase); @@ -93,11 +90,10 @@ const loadOrCreateSessionCase: CaseReducer { @@ -124,6 +120,14 @@ const deleteSessionCase: CaseReducer> = return state; }; +const mergeCaseAndDeepLinkParams = (oldCase: ISessionCase, deepLinkParams: DeepLinkParams): ISessionCase => ({ + ...oldCase, + internalSaksnummer: deepLinkParams.internalSaksnummer ?? oldCase.internalSaksnummer, + sakSakstype: deepLinkParams.sakSakstype ?? oldCase.sakSakstype, + sakFagsaksystem: deepLinkParams.sakFagsaksystem ?? oldCase.sakFagsaksystem, + caseIsAtKA: deepLinkParams.caseIsAtKA ?? oldCase.caseIsAtKA, +}); + export const caseReducers = { setSessionCase, updateSessionCase, diff --git a/frontend/src/redux/session/klage/types.ts b/frontend/src/redux/session/klage/types.ts index 459d79d7..51057b29 100644 --- a/frontend/src/redux/session/klage/types.ts +++ b/frontend/src/redux/session/klage/types.ts @@ -1,6 +1,6 @@ import type { ISessionCase } from '@app/components/case/uinnlogget/types'; import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytelser'; -import type { CaseType } from '@app/redux-api/case/types'; +import type { CaseType, DeepLinkParams } from '@app/redux-api/case/types'; interface Base { type: CaseType; @@ -8,11 +8,11 @@ interface Base { } export interface SessionCaseLoad extends Base { - data: { innsendingsytelse: Innsendingsytelse; internalSaksnummer: string | null; caseIsAtKA: true | null }; + deepLinkParams: DeepLinkParams; } export interface SessionCaseCreate extends Base { - data: { innsendingsytelse: Innsendingsytelse; internalSaksnummer: string | null; caseIsAtKA: true | null }; + deepLinkParams: DeepLinkParams; } export interface SessionCasePayload extends Base { diff --git a/frontend/src/routes/create-case/handlers.ts b/frontend/src/routes/create-case/handlers.ts index 90453fd0..209cb852 100644 --- a/frontend/src/routes/create-case/handlers.ts +++ b/frontend/src/routes/create-case/handlers.ts @@ -4,8 +4,8 @@ import type { Languages } from '@app/language/types'; import { AppEventEnum } from '@app/logging/action'; import { appEvent } from '@app/logging/logger'; import type { useCreateCaseMutation, useResumeOrCreateCaseMutation } from '@app/redux-api/case/api'; -import type { CreateCaseParams } from '@app/redux-api/case/params'; -import { CASE_TYPE_PATH_SEGMENTS, type CaseType } from '@app/redux-api/case/types'; +import type { CreateCaseFields } from '@app/redux-api/case/types'; +import { CASE_TYPE_PATH_SEGMENTS, type CaseType, type DeepLinkParams } from '@app/redux-api/case/types'; import type { AppDispatch } from '@app/redux/configure-store'; import { createSessionCase } from '@app/redux/session/klage/helpers'; import { deleteSessionCase, setSessionCase, updateSessionCase } from '@app/redux/session/session'; @@ -13,10 +13,9 @@ import type { NavigateFunction } from 'react-router-dom'; interface IHandler { language: Languages; - internalSaksnummer: string | null; - caseIsAtKA: true | null; navigate: NavigateFunction; innsendingsytelse: Innsendingsytelse; + deepLinkParams: DeepLinkParams; } interface IHandleSession extends IHandler { @@ -25,28 +24,29 @@ interface IHandleSession extends IHandler { type: CaseType; } +const changedDeepLink = (oldCase: ISessionCase, deepLinkParams: DeepLinkParams): boolean => + (deepLinkParams.internalSaksnummer !== null && deepLinkParams.internalSaksnummer !== oldCase.internalSaksnummer) || + (deepLinkParams.sakSakstype !== null && deepLinkParams.sakSakstype !== oldCase.sakSakstype) || + (deepLinkParams.sakFagsaksystem !== null && deepLinkParams.sakFagsaksystem !== oldCase.sakFagsaksystem) || + (deepLinkParams.caseIsAtKA === true && deepLinkParams.caseIsAtKA !== oldCase.caseIsAtKA); + export const handleSessionCase = ({ - type, + dispatch, sessionCase, + type, innsendingsytelse, + deepLinkParams, language, - internalSaksnummer, - caseIsAtKA, navigate, - dispatch, }: IHandleSession) => { if (sessionCase === null) { appEvent(AppEventEnum.CASE_CREATE_SESSION); dispatch( - setSessionCase({ - type, - innsendingsytelse, - data: createSessionCase(type, innsendingsytelse, internalSaksnummer, caseIsAtKA), - }), + setSessionCase({ type, innsendingsytelse, data: createSessionCase({ type, innsendingsytelse, deepLinkParams }) }), ); - } else if (internalSaksnummer !== null && internalSaksnummer !== sessionCase.internalSaksnummer) { - appEvent(AppEventEnum.CASE_RESUME_SESSION_WITH_SAKSNUMMER); - dispatch(updateSessionCase({ type, innsendingsytelse: innsendingsytelse, data: { internalSaksnummer } })); + } else if (changedDeepLink(sessionCase, deepLinkParams)) { + appEvent(AppEventEnum.CASE_RESUME_SESSION_WITH_CHANGED_DEEP_LINK); + dispatch(updateSessionCase({ type, innsendingsytelse: innsendingsytelse, data: deepLinkParams })); } else { appEvent(AppEventEnum.CASE_RESUME_SESSION); } @@ -64,8 +64,6 @@ interface IHandleCreate extends IHandler { export const handleCreateCase = ({ sessionCase, - internalSaksnummer, - caseIsAtKA, innsendingsytelse, language, createCase, @@ -73,7 +71,7 @@ export const handleCreateCase = ({ navigate, }: IHandleCreate) => { appEvent(AppEventEnum.CASE_CREATE_FROM_SESSION_STORAGE); - createCase(getCreatePayload(sessionCase, language, internalSaksnummer, caseIsAtKA)) + createCase(getCreatePayload(sessionCase, language)) .unwrap() .then(({ id }) => { dispatch(deleteSessionCase({ type: sessionCase.type, innsendingsytelse })); @@ -90,25 +88,18 @@ interface IHandleResumeOrCreate extends IHandler { export const handleResumeOrCreateCase = ({ type, innsendingsytelse, - internalSaksnummer, - caseIsAtKA, + deepLinkParams, language, navigate, resumeOrCreateCase, }: IHandleResumeOrCreate) => { appEvent(AppEventEnum.CASE_CREATE_OR_RESUME); - resumeOrCreateCase({ innsendingsytelse, internalSaksnummer, caseIsAtKA, type }) + resumeOrCreateCase({ innsendingsytelse, type, ...deepLinkParams }) .unwrap() .then(({ id }) => navigate(`/${language}/sak/${id}/begrunnelse`, { replace: true })); }; const getCreatePayload = ( - { type, ...data }: ISessionCase, + { type, id, navn, modifiedByUser, ...rest }: ISessionCase, language: Languages, - internalSaksnummer: string | null, - caseIsAtKA: true | null, -): CreateCaseParams => { - const { id, navn, modifiedByUser, ...rest } = data; - - return { type, ...rest, internalSaksnummer, caseIsAtKA, language }; -}; +): CreateCaseFields => ({ type, ...rest, language }); diff --git a/frontend/src/routes/create-case/use-case.ts b/frontend/src/routes/create-case/use-case.ts index bad2bbe3..37b83717 100644 --- a/frontend/src/routes/create-case/use-case.ts +++ b/frontend/src/routes/create-case/use-case.ts @@ -4,10 +4,10 @@ import type { Innsendingsytelse } from '@app/innsendingsytelser/innsendingsytels import { useLanguage } from '@app/language/use-language'; import { useTranslation } from '@app/language/use-translation'; import { useCreateCaseMutation, useResumeOrCreateCaseMutation } from '@app/redux-api/case/api'; -import type { CaseType } from '@app/redux-api/case/types'; +import type { CaseType, DeepLinkParams } from '@app/redux-api/case/types'; import { useGetUserQuery } from '@app/redux-api/user/api'; import { useAppDispatch } from '@app/redux/configure-store'; -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { handleCreateCase, handleResumeOrCreateCase, handleSessionCase } from './handlers'; @@ -24,15 +24,22 @@ export const useCase = (type: CaseType, innsendingsytelse: Innsendingsytelse): I const { data: user, isLoading: isLoadingUser, isSuccess } = useGetUserQuery(); const internalSaksnummer = getQueryValue(query.get('saksnummer')); + const sakSakstype = getQueryValue(query.get('sakstype')); + const sakFagsaksystem = getQueryValue(query.get('fagsystem')); const caseIsAtKA = getBooleanQueryValue(query.get('ka')) ? true : null; + const deepLinkParams: DeepLinkParams = useMemo( + () => ({ internalSaksnummer, sakSakstype, sakFagsaksystem, caseIsAtKA }), + [internalSaksnummer, sakSakstype, sakFagsaksystem, caseIsAtKA], + ); + const [createCase, { isLoading: createIsLoading, isError: createHasFailed, isSuccess: createIsSuccess }] = useCreateCaseMutation(); const [resumeOrCreateCase, { isLoading: resumeIsLoading, isError: resumeHasFailed, isSuccess: resumeIsSuccess }] = useResumeOrCreateCaseMutation(); - const [sessionCase, sessionCaseIsLoading] = useSessionCase(type, innsendingsytelse, internalSaksnummer, caseIsAtKA); + const [sessionCase, sessionCaseIsLoading] = useSessionCase(type, innsendingsytelse, deepLinkParams); const dispatch = useAppDispatch(); const isLoading = isLoadingUser || createIsLoading || resumeIsLoading; @@ -43,51 +50,26 @@ export const useCase = (type: CaseType, innsendingsytelse: Innsendingsytelse): I return; } + const common = { deepLinkParams, innsendingsytelse, language, navigate }; + if (user === undefined) { - handleSessionCase({ - type, - dispatch, - internalSaksnummer, - caseIsAtKA, - innsendingsytelse, - language, - navigate, - sessionCase, - }); + handleSessionCase({ type, dispatch, sessionCase, ...common }); return; } - if (sessionCase !== null && sessionCase.foedselsnummer === user.folkeregisteridentifikator?.identifikasjonsnummer) { - handleCreateCase({ - createCase, - dispatch, - internalSaksnummer, - caseIsAtKA, - innsendingsytelse, - language, - navigate, - sessionCase, - }); + if (sessionCase.foedselsnummer === user.folkeregisteridentifikator?.identifikasjonsnummer) { + handleCreateCase({ createCase, dispatch, sessionCase, ...common }); return; } - handleResumeOrCreateCase({ - type, - internalSaksnummer, - caseIsAtKA, - innsendingsytelse, - language, - navigate, - resumeOrCreateCase, - }); + handleResumeOrCreateCase({ type, resumeOrCreateCase, ...common }); }, [ createCase, dispatch, innsendingsytelse, - internalSaksnummer, - caseIsAtKA, + deepLinkParams, isDone, isLoading, isSuccess,