From 402665f9e5b27ef61a4adf6d5ff2b00d89edb984 Mon Sep 17 00:00:00 2001 From: ramziabuqassim Date: Tue, 3 Oct 2023 12:15:10 +0200 Subject: [PATCH] autosaver brevtekst for tilbakekreving --- src/lib/hooks.ts | 55 ++++++++++++++++++- .../BrevForTilbakekreving.module.less | 7 +++ .../BrevForTilbakekreving.tsx | 30 +++++++++- 3 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/lib/hooks.ts b/src/lib/hooks.ts index 48df6b47e..5e50eb25b 100644 --- a/src/lib/hooks.ts +++ b/src/lib/hooks.ts @@ -1,6 +1,6 @@ import * as RemoteData from '@devexperts/remote-data-ts'; import { AsyncThunk } from '@reduxjs/toolkit'; -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { ApiClientResult, ApiError } from '~src/api/apiClient'; @@ -135,3 +135,56 @@ export const useExclusiveCombine = (...args: Array !RemoteData.isInitial(a)) ?? args[0]; }, [args]); }; + +/** + * useAutosave er for bruk dersom du vil kalle på en funksjon etter X sekunder, der endringer i dependencies resetter timeren. + * + * @param callback - funksjonen som skal kjøres for hver delay + * @param delay - tiden i millisekunder autosaven skal kjøres + * @param deps - Et set med dependencies som resetter timeren for hver endring + */ +export const useAutosave = (callback: () => void, delay = 5000, deps: unknown[] = []) => { + React.useEffect(() => { + if (delay) { + const interval = setInterval(callback, delay); + + return () => clearInterval(interval); + } + + return; + }, [delay, ...deps]); +}; + +/** + * useAutosaveOnChange er for bruk dersom du vil kalle på en funksjon hvert X sekund, & dersom data har endret på seg + * + * @param data - dataen som sjekkes på om ting har endret seg + * @param callback - funksjonen som skal kjøres + * @param delay - tiden i millisekunder autosaven skal kjøres + */ +export const useAutosaveOnChange = (data: T, callback: () => void, delay = 5000) => { + const [isSaving, setIsSaving] = React.useState(false); + const initialRender = React.useRef(true); + const prev = React.useRef(data); + const live = React.useRef(data); + + useAutosave(() => { + if (prev.current !== live.current) { + prev.current = live.current; + callback(); + } else { + setIsSaving(false); + } + }, delay); + + useEffect(() => { + if (initialRender.current) { + initialRender.current = false; + } else { + setIsSaving(true); + } + live.current = data; + }, [data]); + + return { isSaving }; +}; diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less index 969dc0975..ec0268170 100644 --- a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less +++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less @@ -8,6 +8,13 @@ } } +.textareaLabel { + //ganske så statisk verdi som setter loading ikonet på enden av textarea. Må sikkert endres dersom textarea endres + width: 400px; + display: flex; + justify-content: space-between; +} + .seBrevButton { width: @knappBredde; } diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx index 2ec982d94..b0b3af228 100644 --- a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx +++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx @@ -1,16 +1,17 @@ import * as RemoteData from '@devexperts/remote-data-ts'; import { yupResolver } from '@hookform/resolvers/yup'; -import { Button, Textarea } from '@navikt/ds-react'; +import { Button, Loader, Textarea } from '@navikt/ds-react'; import React from 'react'; import { Controller, UseFormTrigger, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; +import { ErrorIcon, SuccessIcon } from '~src/assets/Icons'; import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert'; import Feiloppsummering from '~src/components/feiloppsummering/Feiloppsummering'; import Navigasjonsknapper from '~src/components/navigasjonsknapper/Navigasjonsknapper'; import ToKolonner from '~src/components/toKolonner/ToKolonner'; import { brevtekstTilbakekrevingsbehandling } from '~src/features/TilbakekrevingActions'; -import { useAsyncActionCreator } from '~src/lib/hooks'; +import { useAsyncActionCreator, useAutosaveOnChange } from '~src/lib/hooks'; import { useI18n } from '~src/lib/i18n'; import * as routes from '~src/lib/routes'; import { hookFormErrorsTilFeiloppsummering } from '~src/lib/validering'; @@ -30,6 +31,7 @@ const BrevForTilbakekreving = (props: { const navigate = useNavigate(); const { formatMessage } = useI18n({ messages }); const [brevStatus, lagreBrev] = useAsyncActionCreator(brevtekstTilbakekrevingsbehandling); + const [autosaveStatus, autosave] = useAsyncActionCreator(brevtekstTilbakekrevingsbehandling); const form = useForm({ resolver: yupResolver(brevForTilbakekrevingSchema), @@ -71,6 +73,15 @@ const BrevForTilbakekreving = (props: { console.log('onSeBrevClick'); }; + const { isSaving } = useAutosaveOnChange(form.watch('brevtekst'), () => + autosave({ + sakId: props.sakId, + saksversjon: props.saksversjon, + behandlingId: props.tilbakekreving.id, + brevtekst: form.watch('brevtekst') ?? '', + }), + ); + return ( {{ @@ -84,7 +95,20 @@ const BrevForTilbakekreving = (props: {