diff --git a/packages/rest-api/index.ts b/packages/rest-api/index.ts index 43297107c5..f44a8a0874 100644 --- a/packages/rest-api/index.ts +++ b/packages/rest-api/index.ts @@ -11,6 +11,7 @@ export { default as AbstractRequestApi } from './src/requestApi/AbstractRequestA export { ErrorTypes, errorOfType, getErrorResponseData } from './src/requestApi/error/ErrorTypes'; export type { default as ErrorType } from './src/requestApi/error/errorTsType'; export type { default as Link } from './src/requestApi/LinkTsType'; +export { default as apiPaths } from './src/requestApi/apiPaths'; let isUnitTestModeOn = false; export const switchOnTestMode = () => { diff --git a/packages/rest-api/src/requestApi/apiPaths.ts b/packages/rest-api/src/requestApi/apiPaths.ts new file mode 100644 index 0000000000..72f1804ff8 --- /dev/null +++ b/packages/rest-api/src/requestApi/apiPaths.ts @@ -0,0 +1,5 @@ +const apiPaths = { + notatISak: '/k9/sak/api/notat', +}; + +export default apiPaths; diff --git a/packages/sak-app/src/behandlingsupport/BehandlingSupportIndex.tsx b/packages/sak-app/src/behandlingsupport/BehandlingSupportIndex.tsx index 3763e22b6b..036083822b 100644 --- a/packages/sak-app/src/behandlingsupport/BehandlingSupportIndex.tsx +++ b/packages/sak-app/src/behandlingsupport/BehandlingSupportIndex.tsx @@ -1,5 +1,6 @@ import SupportMenySakIndex, { SupportTabs } from '@fpsak-frontend/sak-support-meny'; -import { httpErrorHandler, useLocalStorage } from '@fpsak-frontend/utils'; +import { httpErrorHandler } from '@fpsak-frontend/utils'; +import { apiPaths } from '@k9-sak-web/rest-api'; import { useRestApiErrorDispatcher } from '@k9-sak-web/rest-api-hooks'; import { ArbeidsgiverOpplysningerWrapper, @@ -7,10 +8,11 @@ import { Fagsak, FeatureToggles, NavAnsatt, + NotatResponse, Personopplysninger, } from '@k9-sak-web/types'; import axios from 'axios'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useQuery } from 'react-query'; import { useNavigate } from 'react-router-dom'; import { getSupportPanelLocationCreator } from '../app/paths'; @@ -83,34 +85,33 @@ const BehandlingSupportIndex = ({ }: OwnProps) => { const { addErrorMessage } = useRestApiErrorDispatcher(); const [antallUlesteNotater, setAntallUlesteNotater] = useState(0); - const [lesteNotater] = useLocalStorage('lesteNotater', []); - const getNotater = (signal: AbortSignal) => { + const getNotater = (signal: AbortSignal) => axios - .get(`/k9/sak/api/notat`, { + .get(apiPaths.notatISak, { signal, params: { saksnummer: fagsak.saksnummer, }, }) - .then(response => { - const ulesteNotater = response.data.filter( - notat => lesteNotater.findIndex(lestNotatId => lestNotatId === notat.notatId) === -1, - ); - setAntallUlesteNotater(ulesteNotater.length); - }) + .then(({ data }) => data) .catch(error => { httpErrorHandler(error?.response?.status, addErrorMessage, error?.response?.headers?.location); }); - }; + const notaterQueryKey = ['notater', fagsak?.saksnummer]; - useQuery({ + const { data: notater } = useQuery({ queryKey: notaterQueryKey, queryFn: ({ signal }) => getNotater(signal), enabled: featureToggles?.NOTAT_I_SAK && !!fagsak, refetchOnWindowFocus: false, }); + useEffect(() => { + const ulesteNotater = (notater || []).filter(notat => !notat.skjult); + setAntallUlesteNotater(ulesteNotater?.length); + }, [notater]); + const { selected: valgtSupportPanel, location } = useTrackRouteParam({ paramName: 'stotte', isQueryParam: true, @@ -193,13 +194,7 @@ const BehandlingSupportIndex = ({ /> )} {aktivtSupportPanel === SupportTabs.NOTATER && featureToggles?.NOTAT_I_SAK && ( - + )} diff --git a/packages/sak-app/src/behandlingsupport/notater/NotaterIndex.tsx b/packages/sak-app/src/behandlingsupport/notater/NotaterIndex.tsx index 40cb781337..6891de4bc7 100644 --- a/packages/sak-app/src/behandlingsupport/notater/NotaterIndex.tsx +++ b/packages/sak-app/src/behandlingsupport/notater/NotaterIndex.tsx @@ -1,25 +1,31 @@ import { LoadingPanel, requireProps } from '@fpsak-frontend/shared-components'; import Notater from '@k9-sak-web/sak-notat'; -import { FagsakPerson, NavAnsatt } from '@k9-sak-web/types'; +import { Fagsak, NavAnsatt } from '@k9-sak-web/types'; import React from 'react'; +import ErrorBoundary from '@k9-sak-web/sak-app/src/app/ErrorBoundary'; +import { useRestApiErrorDispatcher } from '@k9-sak-web/rest-api-hooks'; interface OwnProps { - saksnummer: string; - behandlingId?: number; - behandlingVersjon?: number; - fagsakPerson?: FagsakPerson; navAnsatt: NavAnsatt; + fagsak: Fagsak; } -const EMPTY_ARRAY = []; - /** * NotaterIndex * * Container komponent. Har ansvar for å vise notater i saken. */ -export const NotaterIndex = ({ saksnummer, navAnsatt }: OwnProps) => ( - -); +export const NotaterIndex = ({ fagsak, navAnsatt }: OwnProps) => { + const { addErrorMessage } = useRestApiErrorDispatcher(); -export default requireProps(['saksnummer'], )(NotaterIndex); + return ( + + + + ); +}; +export default requireProps(['fagsak'], )(NotaterIndex); diff --git a/packages/sak-notat/i18n/nb_NO.json b/packages/sak-notat/i18n/nb_NO.json index 917d29864b..76fd439fba 100644 --- a/packages/sak-notat/i18n/nb_NO.json +++ b/packages/sak-notat/i18n/nb_NO.json @@ -2,6 +2,7 @@ "NotatISakIndex.VisNotatTilknyttetPleietrengende": "Vis notat i alle saker tilknyttet pleietrengende", "NotatISakIndex.LeggTilNotatButton": "Legg til notat", "NotatISakIndex.IngenNotaterAlert": "Ingen notater er publisert i saken", + "NotatISakIndex.IngenAktiveNotaterAlert": "Ingen aktive notater i saken", "NotatISakIndex.NotaterISak": "Notater i sak", "NotatISakIndex.VisSkjulteNotater": "Vis skjulte notater", "NotatISakIndex.SkrivNyttNotat": "Skriv et nytt notat", diff --git a/packages/sak-notat/package.json b/packages/sak-notat/package.json index c7c5222a71..f167ecda03 100644 --- a/packages/sak-notat/package.json +++ b/packages/sak-notat/package.json @@ -6,6 +6,7 @@ "private": true, "dependencies": { "@fpsak-frontend/utils": "1.0.0", + "@k9-sak-web/rest-api": "1.0.0", "@k9-sak-web/types": "1.0.0", "@navikt/aksel-icons": "5.8.0", "@navikt/ds-react": "5.8.0", diff --git a/packages/sak-notat/src/Notater.tsx b/packages/sak-notat/src/Notater.tsx index e0f304746a..a0a90e6df7 100644 --- a/packages/sak-notat/src/Notater.tsx +++ b/packages/sak-notat/src/Notater.tsx @@ -1,4 +1,4 @@ -import { NavAnsatt } from '@k9-sak-web/types'; +import { NavAnsatt, NotatResponse } from '@k9-sak-web/types'; import { Alert, Button, Heading, Loader, Switch } from '@navikt/ds-react'; import { CheckboxField, Form, TextAreaField } from '@navikt/ft-form-hooks'; import React, { useState } from 'react'; @@ -6,7 +6,6 @@ import { UseFormReturn } from 'react-hook-form'; import { FormattedMessage, RawIntlProvider, createIntl, createIntlCache } from 'react-intl'; import messages from '../i18n/nb_NO.json'; import ChatComponent from './components/ChatComponent'; -import { NotatResponse } from './types/NotatResponse'; import styles from './notater.module.css'; const cache = createIntlCache(); @@ -41,6 +40,7 @@ interface NotaterProps { notater: NotatResponse[]; postNotatMutationError: boolean; formMethods: UseFormReturn; + fagsakHarPleietrengende: boolean; } const Notater: React.FunctionComponent = ({ @@ -53,6 +53,7 @@ const Notater: React.FunctionComponent = ({ postNotatMutationError, submitSkjulNotat, formMethods, + fagsakHarPleietrengende, }) => { const [visSkjulteNotater, setVisSkjulteNotater] = useState(false); @@ -62,6 +63,8 @@ const Notater: React.FunctionComponent = ({ const submit = (data: Inputs) => submitNotat(data); + const alleNotaterErSkjulte = notater?.every(notat => notat.skjult); + return ( {isLoading ? ( @@ -76,11 +79,35 @@ const Notater: React.FunctionComponent = ({ + formMethods={formMethods} onSubmit={submit}> +
+ } + /> +
+ {fagsakHarPleietrengende && ( + } + /> + )} + + {!hasGetNotaterError && notater?.length === 0 && ( )} + {alleNotaterErSkjulte && !visSkjulteNotater && notater?.length > 0 && ( + + + + )} {hasGetNotaterError && ( @@ -107,23 +134,6 @@ const Notater: React.FunctionComponent = ({ ))} )} - formMethods={formMethods} onSubmit={submit}> -
- } - /> -
- } - /> - - )}
diff --git a/packages/sak-notat/src/NotaterIndex.tsx b/packages/sak-notat/src/NotaterIndex.tsx index fb11c051ad..5fbd78844f 100644 --- a/packages/sak-notat/src/NotaterIndex.tsx +++ b/packages/sak-notat/src/NotaterIndex.tsx @@ -1,16 +1,14 @@ -import { useLocalStorage } from '@fpsak-frontend/utils'; import { NavAnsatt } from '@k9-sak-web/types'; -import axios from 'axios'; import React from 'react'; import { useForm } from 'react-hook-form'; import { useMutation, useQuery, useQueryClient } from 'react-query'; import Notater, { Inputs, skjulNotatMutationVariables } from './Notater'; -import { NotatGjelderType } from './types/NotatGjelderType'; -import { NotatResponse } from './types/NotatResponse'; +import { getNotater, postNotat, skjulNotat } from './notatApi'; interface NotaterIndexProps { fagsakId: string; navAnsatt: NavAnsatt; + fagsakHarPleietrengende: boolean; } interface postNotatMutationVariables { @@ -20,8 +18,7 @@ interface postNotatMutationVariables { versjon?: number; } -const NotaterIndex: React.FC = ({ fagsakId, navAnsatt }) => { - const [lesteNotater, setLesteNotater] = useLocalStorage('lesteNotater', []); +const NotaterIndex: React.FC = ({ fagsakId, navAnsatt, fagsakHarPleietrengende }) => { const queryClient = useQueryClient(); const notaterQueryKey = ['notater', fagsakId]; @@ -33,48 +30,19 @@ const NotaterIndex: React.FC = ({ fagsakId, navAnsatt }) => { }, }); - const getNotater = (signal: AbortSignal) => - axios - .get(`/k9/sak/api/notat`, { - signal, - params: { - saksnummer: fagsakId, - }, - }) - .then(({ data }) => { - const sorterteNotater = [...data].sort( - (notatA, notatB) => +new Date(notatA.opprettetTidspunkt) - +new Date(notatB.opprettetTidspunkt), - ); - setLesteNotater([ - ...new Set([...lesteNotater, ...data.filter(notat => !notat.skjult).map(notat => notat.notatId)]), - ]); - return sorterteNotater; - }); - const { isLoading: getNotaterLoading, isError: hasGetNotaterError, data: notater, - } = useQuery({ queryKey: notaterQueryKey, queryFn: ({ signal }) => getNotater(signal), enabled: !!fagsakId }); - - const postNotat = (data: Inputs, id?: number, fagsakIdFraRedigertNotat?: string, versjon?: number) => { - let notatGjelderType; - if (!id) { - notatGjelderType = data.visNotatIAlleSaker ? NotatGjelderType.pleietrengende : NotatGjelderType.fagsak; - } - const postUrl = id ? '/k9/sak/api/notat/endre' : '/k9/sak/api/notat'; - return axios.post(postUrl, { - notatTekst: data.notatTekst, - saksnummer: fagsakIdFraRedigertNotat || fagsakId, - notatGjelderType, - versjon: versjon || 0, - notatId: id, - }); - }; + } = useQuery({ + queryKey: notaterQueryKey, + queryFn: ({ signal }) => getNotater(signal, fagsakId), + enabled: !!fagsakId, + }); const postNotatMutation = useMutation( ({ data, id, fagsakIdFraRedigertNotat, versjon }: postNotatMutationVariables) => - postNotat(data, id, fagsakIdFraRedigertNotat, versjon), + postNotat(data, fagsakId, id, fagsakIdFraRedigertNotat, versjon), { onSuccess: () => { formMethods.reset(); @@ -83,14 +51,6 @@ const NotaterIndex: React.FC = ({ fagsakId, navAnsatt }) => { }, ); - const skjulNotat = (skjul: boolean, id: number, saksnummer: string, versjon: number) => - axios.post('/k9/sak/api/notat/skjul', { - notatId: id, - skjul, - saksnummer, - versjon, - }); - const skjulNotatMutation = useMutation( ({ skjul, id, saksnummer, versjon }: skjulNotatMutationVariables) => skjulNotat(skjul, id, saksnummer, versjon), { @@ -118,6 +78,7 @@ const NotaterIndex: React.FC = ({ fagsakId, navAnsatt }) => { postNotatMutationError={postNotatMutation.isError} submitSkjulNotat={submitSkjulNotat} formMethods={formMethods} + fagsakHarPleietrengende={fagsakHarPleietrengende} /> ); }; diff --git a/packages/sak-notat/src/components/ChatComponent.tsx b/packages/sak-notat/src/components/ChatComponent.tsx index 8629421282..7bf33e98ec 100644 --- a/packages/sak-notat/src/components/ChatComponent.tsx +++ b/packages/sak-notat/src/components/ChatComponent.tsx @@ -1,4 +1,4 @@ -import { NavAnsatt } from '@k9-sak-web/types'; +import { NavAnsatt, NotatResponse } from '@k9-sak-web/types'; import { EyeSlashIcon, EyeWithPupilIcon, PencilIcon } from '@navikt/aksel-icons'; import { BodyLong, Button, Chat, Label, Tag } from '@navikt/ds-react'; import { Form, TextAreaField } from '@navikt/ft-form-hooks'; @@ -7,7 +7,6 @@ import { format } from 'date-fns'; import React, { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FormattedMessage } from 'react-intl'; -import { NotatResponse } from '../types/NotatResponse'; import styles from './chatComponent.module.css'; export enum ChatPosition { @@ -56,7 +55,6 @@ const ChatComponent: React.FunctionComponent = ({ fagsakId, }) => { const { - endretAv, endretTidspunkt, gjelderType, notatId, @@ -65,10 +63,9 @@ const ChatComponent: React.FunctionComponent = ({ opprettetTidspunkt, versjon, skjult, + kanRedigere, } = notat; - const erSistEndretAvGjeldendeBruker = - endretAv === navAnsatt.brukernavn || (!endretAv && opprettetAv === navAnsatt.brukernavn); - const position = erSistEndretAvGjeldendeBruker ? ChatPosition.Right : ChatPosition.Left; + const position = opprettetAv === navAnsatt.brukernavn ? ChatPosition.Right : ChatPosition.Left; const minLength3 = minLength(3); const maxLength2000 = maxLength(1500); @@ -100,8 +97,16 @@ const ChatComponent: React.FunctionComponent = ({ skjulNotat({ skjul: !skjult, id: notatId, saksnummer: fagsakId, versjon }); }; - const name = erSistEndretAvGjeldendeBruker ? 'Deg' : endretAv || opprettetAv; - const timestamp = format(new Date(endretTidspunkt || opprettetTidspunkt), 'dd.MM.yyyy H:mm'); + const navnPåOppretter = opprettetAv === navAnsatt.brukernavn ? 'Deg' : opprettetAv; + + const tidspunktStreng = () => { + const formatertOpprettetTidspunkt = format(new Date(opprettetTidspunkt), 'dd.MM.yy H:mm'); + const formatertEndretTidspunkt = endretTidspunkt ? format(new Date(endretTidspunkt), 'dd.MM.yy H:mm') : undefined; + if (endretTidspunkt) { + return `(Endret: ${formatertEndretTidspunkt}) ${formatertOpprettetTidspunkt}`; + } + return formatertOpprettetTidspunkt; + }; return ( @@ -110,8 +115,8 @@ const ChatComponent: React.FunctionComponent = ({ className={position === ChatPosition.Right ? styles.chatRight : styles.chatLeft} > @@ -148,15 +153,17 @@ const ChatComponent: React.FunctionComponent = ({ {readOnly && (
- + {kanRedigere && ( + + )}