Skip to content

Commit

Permalink
fix: errornotice after revert
Browse files Browse the repository at this point in the history
  • Loading branch information
Birkbjo committed Nov 11, 2024
1 parent 41bb602 commit 7d887bd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 58 deletions.
101 changes: 43 additions & 58 deletions src/components/form/DefaultFormErrorNotice.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,44 @@
import i18n from '@dhis2/d2-i18n'
import { NoticeBox } from '@dhis2/ui'
import { FormState } from 'final-form'
import React, { useEffect, useRef } from 'react'
import { useFormState } from 'react-final-form'
import React from 'react'
import css from './DefaultFormErrorNotice.module.css'

const formStateSubscriptions = {
errors: true,
submitError: true,
submitFailed: true,
hasValidationErrors: true,
hasSubmitErrors: true,
dirtySinceLastSubmit: true,
}

type FormStateErrors = Pick<
FormState<unknown>,
keyof typeof formStateSubscriptions
>
import { useFormStateErrors } from './useFormStateErrors'

export function DefaultFormErrorNotice() {
const partialFormState: FormStateErrors = useFormState({
subscription: formStateSubscriptions,
})
// only show after trying to submit
if (
!partialFormState.submitFailed ||
(partialFormState.submitFailed && partialFormState.dirtySinceLastSubmit)
) {
const formStateErrors = useFormStateErrors()

if (!formStateErrors.shouldShowErrors) {
return null
}

if (partialFormState.hasValidationErrors) {
return <ValidationErrors formStateErrors={partialFormState} />
if (formStateErrors.hasValidationErrors) {
return (
<ValidationErrorNotice>
<ErrorList
errors={errorsWithLabels(
formStateErrors.validationErrors || {}
)}
/>
</ValidationErrorNotice>
)
}

if (partialFormState.hasSubmitErrors) {
return <ServerSubmitError formStateErrors={partialFormState} />
if (formStateErrors.hasSubmitErrors) {
return (
<ServerSubmitErrorNotice>
{formStateErrors.submitError}
</ServerSubmitErrorNotice>
)
}
return null
}

const ValidationErrors = ({
formStateErrors,
export const ValidationErrorNotice = ({
children,
}: {
formStateErrors: FormStateErrors
children: React.ReactNode
}) => {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
if (ref.current) {
ref.current.scrollIntoView({ behavior: 'smooth' })
}
}, [])
return (
<div ref={ref}>
<div>
<NoticeBox
className={css.noticeBox}
warning
Expand All @@ -64,17 +49,13 @@ const ValidationErrors = ({
'Some fields have validation errors. Please fix them before saving.'
)}
</p>
{formStateErrors.errors && (
<ErrorList errors={formStateErrors.errors} />
)}
{children}
</NoticeBox>
</div>
)
}

const ErrorList = ({ errors }: { errors: Record<string, string> }) => {
const labels = getFieldLabelsBestEffort()

export const ErrorList = ({ errors }: { errors: Record<string, string> }) => {
return (
<ul style={{ padding: '0 16px' }}>
{Object.entries(errors).map(([key, value]) => {
Expand All @@ -85,7 +66,7 @@ const ErrorList = ({ errors }: { errors: Record<string, string> }) => {
fontWeight: '600',
}}
>
{labels.get(key) || key}:
{key}:
</span>
<span>{JSON.stringify(value)}</span>
</li>
Expand All @@ -95,29 +76,33 @@ const ErrorList = ({ errors }: { errors: Record<string, string> }) => {
)
}

const ServerSubmitError = ({
formStateErrors,
export const ServerSubmitErrorNotice = ({
children,
}: {
formStateErrors: FormStateErrors
children: React.ReactNode
}) => {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
if (ref.current) {
ref.current.scrollIntoView({ behavior: 'smooth' })
}
}, [])
return (
<div ref={ref}>
<div>
<NoticeBox
className={css.noticeBox}
error
title={i18n.t('Something went wrong when submitting the form')}
>
<p>{formStateErrors.submitError}</p>
<p>{children}</p>
</NoticeBox>
</div>
)
}

const errorsWithLabels = (errors: Record<string, string>) => {
const labels = getFieldLabelsBestEffort()
return Object.fromEntries(
Object.entries(errors).map(([key, value]) => {
return [labels.get(key) || key, value]
})
)
}

/**
* We don't have a good way to get the translated labels, so for now
* we get these from the DOM. This is a best-effort approach.
Expand Down
1 change: 1 addition & 0 deletions src/components/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { DefaultEditFormContents } from './DefaultFormContents'
export * from './attributes'
export * from './helpers'
export * from './FormBase'
export * from './useFormStateErrors'
2 changes: 2 additions & 0 deletions src/pages/dataSets/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
SectionedFormLayout,
DefaultSectionedFormFooter,
DefaultSectionedFormSidebar,
SectionedFormErrorNotice,
} from '../../components'
import { SectionedFormProvider, SECTIONS_MAP, useOnSubmitNew } from '../../lib'
import { DataSetFormContents } from './form/DataSetFormContents'
Expand All @@ -29,6 +30,7 @@ export const Component = () => {
>
<form onSubmit={handleSubmit}>
<DataSetFormContents />
<SectionedFormErrorNotice />
</form>
</SectionedFormLayout>
)
Expand Down

0 comments on commit 7d887bd

Please sign in to comment.