Skip to content

Commit

Permalink
Merge pull request #1014 from navikt/ErrorSummaryStart
Browse files Browse the repository at this point in the history
Error summary start
  • Loading branch information
JeremiahUy authored Nov 15, 2024
2 parents 9660407 + f127909 commit 208343e
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Alert, BodyShort, Button, Checkbox, Label, Modal } from '@navikt/ds-react'
import { Form, Formik, FormikProps, validateYupSchema, yupToFormErrors } from 'formik'
import { Alert, BodyShort, Button, Checkbox, ErrorSummary, Label, Modal } from '@navikt/ds-react'
import { Form, Formik, FormikErrors, FormikProps, validateYupSchema, yupToFormErrors } from 'formik'
import _ from 'lodash'
import moment from 'moment'
import React, { useEffect, useState } from 'react'
Expand All @@ -16,6 +16,7 @@ import {
ERelationType,
IDocumentRelation,
IEtterlevelse,
ISuksesskriterieBegrunnelse,
TEtterlevelseDokumentasjonQL,
TKravQL,
} from '../../../constants'
Expand All @@ -24,6 +25,7 @@ import { DateField } from '../../common/Inputs'
import { syncEtterlevelseKriterieBegrunnelseWithKrav } from '../../etterlevelseDokumentasjonTema/common/utils'
import EtterlevelseCard from '../EtterlevelseCard'
import { SuksesskriterierBegrunnelseEdit } from './SuksesskriterieBegrunnelseEdit'
import SuksesskriterieErrorFields from './SuksesskriterieErrorFields'
import { etterlevelseSchema } from './etterlevelseSchema'

type TEditProps = {
Expand Down Expand Up @@ -68,6 +70,9 @@ export const EtterlevelseEditFields = ({
const [morDokumentRelasjon, setMorDokumentRelasjon] = useState<IDocumentRelation>()
const [morEtterlevelse, setMorEtterlevelse] = useState<IEtterlevelse>()

const errorSummaryRef = React.useRef<HTMLDivElement>(null)
const [validateOnBlur, setValidateOnBlur] = useState(false)

const navigate = useNavigate()
useEffect(() => {
if (navigatePath) {
Expand Down Expand Up @@ -137,7 +142,7 @@ export const EtterlevelseEditFields = ({
}}
innerRef={formRef}
validateOnChange={false}
validateOnBlur={false}
validateOnBlur={validateOnBlur}
>
{({
values,
Expand Down Expand Up @@ -174,14 +179,6 @@ export const EtterlevelseEditFields = ({
forGjenbruk={etterlevelseDokumentasjon?.forGjenbruk}
morEtterlevelse={morEtterlevelse}
/>

<div className="w-full my-6">
{Object.keys(errors).length > 0 && (
<Alert fullWidth variant="error">
Du må fylle ut alle obligatoriske felter
</Alert>
)}
</div>
</div>
</Form>

Expand All @@ -199,7 +196,7 @@ export const EtterlevelseEditFields = ({
</Checkbox>

{isOppfylesSenere && (
<div className="w-full">
<div className="w-full" id="fristForFerdigstillelse">
<div className="w-full max-w-[10.625rem]">
<DateField name="fristForFerdigstillelse" />
</div>
Expand All @@ -213,12 +210,35 @@ export const EtterlevelseEditFields = ({
</div>
)}

<div className="w-full justify-end">
{!_.isEmpty(errors) && (
<ErrorSummary
ref={errorSummaryRef}
heading="Du må rette disse feilene før du kan fortsette"
onClick={() => console.debug(errors)}
>
{errors.suksesskriterieBegrunnelser && (
<SuksesskriterieErrorFields
errors={
errors.suksesskriterieBegrunnelser as FormikErrors<ISuksesskriterieBegrunnelse>[]
}
/>
)}

{errors.fristForFerdigstillelse && (
<ErrorSummary.Item href={'#fristForFerdigstillelse'}>
{errors.fristForFerdigstillelse}
</ErrorSummary.Item>
)}
</ErrorSummary>
)}

<div className="w-full justify-end mt-5">
<div className="flex w-full pb-3 flex-row-reverse">
<Button
disabled={disableEdit || isOppfylesSenere}
type="button"
onClick={() => {
setValidateOnBlur(true)
values.status = EEtterlevelseStatus.FERDIG_DOKUMENTERT
values.suksesskriterieBegrunnelser.forEach((skb, index) => {
if (skb.begrunnelse === '' || skb.begrunnelse === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ const KriterieBegrunnelse = ({
<div className="w-full mt-5">
<div className="min-w-fit">
<RadioGroup
id={'suksesskriterieStatus_' + index}
value={suksessKriterieStatus}
legend="Oppgi status på suksesskriteriet"
onChange={(val) => setSuksessKriterieStatus(val as ESuksesskriterieStatus)}
Expand Down Expand Up @@ -452,7 +453,7 @@ const KriterieBegrunnelse = ({
</RadioGroup>
</div>
{!disableEdit && suksesskriterie.behovForBegrunnelse && suksessKriterieStatus && (
<div className="w-full mt-8">
<div id={'begrunnelse_' + index} className="w-full mt-8">
<div className="flex w-full justify-between items-center mb-1">
<Label>{getLabelForSuksessKriterie(suksessKriterieStatus)}</Label>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ErrorSummary } from '@navikt/ds-react'
import { FormikErrors } from 'formik'
import _ from 'lodash'
import React from 'react'
import { ISuksesskriterieBegrunnelse } from '../../../constants'

interface IProps {
errors: FormikErrors<ISuksesskriterieBegrunnelse>[]
}

export const SuksesskriterieErrorFields = (props: IProps) => {
const { errors } = props

return (
<>
{errors.map((error, index) => {
if (!_.isEmpty(error)) {
return (
<React.Fragment key={'suksesskrietier_error_' + index}>
{error.begrunnelse && (
<ErrorSummary.Item href={'#begrunnelse_' + index}>
{error.begrunnelse}
</ErrorSummary.Item>
)}
{error.suksesskriterieStatus && (
<ErrorSummary.Item href={'#suksesskriterieStatus_' + index}>
{error.suksesskriterieStatus}
</ErrorSummary.Item>
)}
</React.Fragment>
)
}
})}
</>
)
}
export default SuksesskriterieErrorFields
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import {
Button,
Checkbox,
CheckboxGroup,
ErrorSummary,
Heading,
Label,
ReadMore,
TextField,
} from '@navikt/ds-react'
import { Field, FieldArray, FieldArrayRenderProps, FieldProps, Form, Formik } from 'formik'
import React from 'react'
import { ChangeEvent, useEffect, useState } from 'react'
import { NavigateFunction, useNavigate } from 'react-router-dom'
import AsyncSelect from 'react-select/async'
Expand Down Expand Up @@ -41,7 +43,6 @@ import {
} from '../../../services/Codelist'
import { user } from '../../../services/User'
import { isDev } from '../../../util/config'
import { ScrollToFieldError } from '../../../util/formikUtils'
import { BoolField, FieldWrapper, OptionList, TextAreaField } from '../../common/Inputs'
import LabelWithTooltip, { LabelWithDescription } from '../../common/LabelWithTooltip'
import { Markdown } from '../../common/Markdown'
Expand Down Expand Up @@ -77,6 +78,9 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas

const isForRedigering: boolean = window.location.pathname.includes('/edit')

const errorSummaryRef = React.useRef<HTMLDivElement>(null)
const [validateOnBlur, setValidateOnBlur] = useState(false)

const labelNavngiDokument: string = isForRedigering
? 'Navngi dokumentet ditt'
: 'Navngi det nye dokumentet ditt'
Expand Down Expand Up @@ -166,7 +170,7 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas
onSubmit={submit}
validationSchema={etterlevelseDokumentasjonSchema()}
validateOnChange={false}
validateOnBlur={false}
validateOnBlur={validateOnBlur}
>
{({ values, submitForm, setFieldValue, errors }) => (
<Form>
Expand Down Expand Up @@ -393,7 +397,7 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas
</FieldArray>
<div className="flex-1" />
</div>
<div className="flex flex-col lg:flex-row gap-5 mb-5">
<div id="resourcesData" className="flex flex-col lg:flex-row gap-5 mb-5">
<FieldArray name="resourcesData">
{(fieldArrayRenderProps: FieldArrayRenderProps) => (
<div className="flex-1">
Expand Down Expand Up @@ -594,6 +598,21 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas
</div>
)}

{Object.values(errors).some(Boolean) && (
<ErrorSummary
ref={errorSummaryRef}
heading="Du må rette disse feilene før du kan fortsette"
>
{Object.entries(errors)
.filter(([, error]) => error)
.map(([key, error]) => (
<ErrorSummary.Item href={`#${key}`} key={key}>
{error as string}
</ErrorSummary.Item>
))}
</ErrorSummary>
)}

<div className="button_container flex flex-col mt-5 py-4 px-4 sticky bottom-0 border-t-2 z-2 bg-bg-default">
<div className="flex flex-row-reverse">
<Button
Expand All @@ -604,6 +623,8 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas
tekst: 'Opprett etterlevelsesdokument',
})
}
errorSummaryRef.current?.focus()
setValidateOnBlur(true)
submitForm()
}}
className="ml-2.5"
Expand All @@ -624,8 +645,6 @@ export const EtterlevelseDokumentasjonForm = (props: TEditEtterlevelseDokumentas
</Button>
</div>
</div>

<ScrollToFieldError />
</Form>
)}
</Formik>
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/src/components/krav/Edit/KravCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { createKrav, kravMapToFormVal } from '../../../api/KravApi'
import { EKravStatus, IKrav, TKravQL } from '../../../constants'
import { kravBreadCrumbPath } from '../../../pages/util/BreadCrumbPath'
import { CodelistService, EListName, ICode, TLovCode } from '../../../services/Codelist'
import { ScrollToFieldError } from '../../../util/formikUtils'
import ErrorModal from '../../ErrorModal'
import { TextAreaField } from '../../common/Inputs'
import { PageLayout } from '../../scaffold/Page'
Expand Down Expand Up @@ -119,7 +118,6 @@ export const KravCreatePage = () => {
errorMessage={errorModalMessage}
submit={setShowErrorModal}
/>
<ScrollToFieldError />
</Form>
)}
</Formik>
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/src/components/krav/Edit/KravEditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
import { kravBreadCrumbPath } from '../../../pages/util/BreadCrumbPath'
import { CodelistService, EListName, ICode, TLovCode } from '../../../services/Codelist'
import { user } from '../../../services/User'
import { ScrollToFieldError } from '../../../util/formikUtils'
import ErrorModal from '../../ErrorModal'
import { TextAreaField } from '../../common/Inputs'
import { PageLayout } from '../../scaffold/Page'
Expand Down Expand Up @@ -340,7 +339,6 @@ export const KravEditPage = () => {
errorMessage={errorModalMessage}
submit={setShowErrorModal}
/>
<ScrollToFieldError />
</Form>
)}
</Formik>
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/src/components/krav/Edit/KravNyVersjonPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { GetKravData, IKravDataProps, TKravById } from '../../../api/KravEditApi
import { EKravStatus, IKrav, TKravQL } from '../../../constants'
import { kravBreadCrumbPath } from '../../../pages/util/BreadCrumbPath'
import { CodelistService, EListName, ICode, TLovCode } from '../../../services/Codelist'
import { ScrollToFieldError } from '../../../util/formikUtils'
import { TextAreaField } from '../../common/Inputs'
import { FormError } from '../../common/ModalSchema'
import { PageLayout } from '../../scaffold/Page'
Expand Down Expand Up @@ -152,7 +151,6 @@ export const KravNyVersjonPage = () => {
/>
</div>
</div>
<ScrollToFieldError />
</Form>
)}
</Formik>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const checkIfVersjonEndringIsEmpty = (versjonEndringer: string, kravVersjon: num

const hensiktCheck = yup.string().test({
name: 'hensiktCheck',
message: EYupErrorMessage.PAAKREVD,
message: 'Du må oppgi et hensikt til kravet',
test: function (hensikt) {
const { parent } = this
return activeStatusValueValidation(parent.status, checkIfHensiktHasValue(hensikt as string))
Expand All @@ -73,7 +73,7 @@ const suksesskriterierCheck = yup.array().test({

const regelverkCheck = yup.array().test({
name: 'regelverkCheck',
message: EYupErrorMessage.PAAKREVD,
message: 'Kravet må være knyttet til et regelverk',
test: function (regelverk) {
const { parent } = this
return activeStatusValueValidation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const KriterieList = ({
{newKrav && <AddSuksessKriterieButton />}

{!newKrav &&
(fieldArrayRenderProps.form.values.status !== EKravStatus.AKTIV || newVersion) && (
(fieldArrayRenderProps.form.initialValues.status !== EKravStatus.AKTIV || newVersion) && (
<AddSuksessKriterieButton />
)}
</div>
Expand Down Expand Up @@ -162,7 +162,8 @@ const Kriterie = ({
<Box padding="4" className="mb-4" background="surface-subtle" borderColor="border-on-inverted">
<div className="relative pt-1">
<div className="flex items-center absolute right-0 top-0">
{(fieldArrayRenderProps.form.values.status !== EKravStatus.AKTIV || newVersion) && (
{(fieldArrayRenderProps.form.initialValues.status !== EKravStatus.AKTIV ||
newVersion) && (
<Tooltip content="Fjern suksesskriterium">
<Button
variant="secondary"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Alert, Checkbox, CheckboxGroup, Heading } from '@navikt/ds-react'
import { Checkbox, CheckboxGroup, ErrorSummary, Heading } from '@navikt/ds-react'
import { FormikErrors } from 'formik/dist/types'
import { useRef } from 'react'
import { TKravQL } from '../../../../constants'
import { EListName } from '../../../../services/Codelist'
import { InputField, TextAreaField } from '../../../common/Inputs'
Expand Down Expand Up @@ -32,6 +33,7 @@ export const KravFormFields = (props: IProps) => {
setVarselMeldingActive,
isEditingUtgaattKrav,
} = props
const errorSummaryRef = useRef<HTMLDivElement>(null)
return (
<>
<div className="mt-5 mb-10">
Expand Down Expand Up @@ -135,14 +137,20 @@ export const KravFormFields = (props: IProps) => {
<FormError fieldName="varslingsadresserQl" akselStyling />

<div className="w-full">
{Object.keys(errors).length > 0 && !errors.dokumentasjon && (
<div className="flex w-full my-12">
<div className="w-full bg-red-300">
<Alert variant="warning" role="status">
Du må fylle ut alle obligatoriske felter
</Alert>
</div>
</div>
{Object.values(errors).some(Boolean) && (
<ErrorSummary
ref={errorSummaryRef}
heading="Du må rette disse feilene før du kan fortsette"
className="mt-5"
>
{Object.entries(errors)
.filter(([, error]) => error)
.map(([key, error]) => (
<ErrorSummary.Item href={`#${key}`} key={key}>
{error as string}
</ErrorSummary.Item>
))}
</ErrorSummary>
)}
</div>
</div>
Expand Down

0 comments on commit 208343e

Please sign in to comment.