Skip to content

Commit

Permalink
Add inline notification
Browse files Browse the repository at this point in the history
  • Loading branch information
jwnasambu committed Aug 8, 2024
1 parent c6f17f9 commit 6db0fb2
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 203 deletions.
105 changes: 47 additions & 58 deletions src/results/result-form-field.component.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,19 @@
import React from "react";
import styles from "./result-form.scss";
import { TextInput, Select, SelectItem } from "@carbon/react";
import { TFunction, useTranslation } from "react-i18next";
import {
TextInput,
Select,
SelectItem,
InlineNotification,
} from "@carbon/react";
import { useTranslation } from "react-i18next";
import { ConceptReference } from "./result-form.resource";
import { Controller, UseFormRegister } from "react-hook-form";
import { ZodSchema, z } from "zod";

const isNumeric = (concept: ConceptReference): boolean =>
concept.datatype.display === "Numeric";

const createResultFormFieldSchema = (
concepts: ConceptReference[],
t: TFunction
): ZodSchema => {
const fields = concepts.reduce((acc, concept) => {
const fieldValidation = isNumeric(concept)
? z.coerce
.number()
.min(0, { message: t("enterValidNumber", "Enter a valid number") })
.optional()
: z
.string()
.min(1, { message: t("fieldRequired", "This field is required") })
.optional();

return { ...acc, [concept.uuid]: fieldValidation };
}, {} as Record<string, z.ZodString | z.ZodNumber>);

const schema = z.object(fields).refine(
(data) => {
return Object.values(data).some(
(value) => value !== undefined && value !== null && value !== ""
);
},
{
message: t("atLeastOneField", "At least one field must be filled out"),
}
);

return schema;
};
import { Controller } from "react-hook-form";

interface ResultFormFieldProps {
register: UseFormRegister<{ testResult: string }>;
concept: ConceptReference;
control: any;
register: any;
errors: any;
}

Expand All @@ -54,6 +23,7 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
errors,
}) => {
const { t } = useTranslation();

const isTextOrNumeric = (concept) =>
concept.datatype?.display === "Text" ||
concept.datatype?.display === "Numeric";
Expand All @@ -63,16 +33,16 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
const printValueRange = (concept: ConceptReference) => {
if (concept?.datatype?.display === "Numeric") {
const maxVal = Math.max(
concept?.hiAbsolute ?? 0,
concept?.hiCritical ?? 0,
concept?.hiNormal ?? 0
concept?.hiAbsolute,
concept?.hiCritical,
concept?.hiNormal
);
const minVal = Math.min(
concept?.lowAbsolute ?? 0,
concept?.lowCritical ?? 0,
concept?.lowNormal ?? 0
concept?.lowAbsolute,
concept?.lowCritical,
concept?.lowNormal
);
return ` (${minVal} - ${maxVal > 0 ? maxVal : "--"} ${
return ` (${minVal ?? 0} - ${maxVal > 0 ? maxVal : "--"} ${
concept?.units ?? ""
})`;
}
Expand All @@ -81,9 +51,23 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({

return (
<>
{Object.keys(errors).length > 0 && (
<InlineNotification
className={styles.emptyFormError}
lowContrast
title={t("error", "Error")}
subtitle={
t("pleaseFillField", "Please fill at least one field") + "."
}
hideCloseButton
/>
)}
{isTextOrNumeric(concept) && (
<Controller
control={control}
rules={{
required: true,
}}
name={concept.uuid}
render={({ field }) => (
<TextInput
Expand All @@ -98,8 +82,6 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
: "")
}
autoFocus
invalid={!!errors[concept.uuid]}
invalidText={errors[concept.uuid]?.message}
/>
)}
/>
Expand All @@ -109,19 +91,22 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
<Controller
name={concept.uuid}
control={control}
rules={{
required: true,
}}
render={({ field }) => (
<Select
key={concept.uuid}
className={styles.textInput}
{...field}
type="text"
labelText={concept?.display}
invalid={!!errors[concept.uuid]}
invalidText={errors[concept.uuid]?.message}
>
<SelectItem
text={t("chooseOption", "Choose an Option")}
value=""
/>

{concept?.answers?.map((answer) => (
<SelectItem
key={answer.uuid}
Expand All @@ -141,11 +126,14 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
if (isTextOrNumeric(member)) {
return (
<Controller
key={member.uuid}
control={control}
name={member.uuid}
rules={{
required: true,
}}
render={({ field }) => (
<TextInput
key={member.uuid}
className={styles.textInput}
{...field}
type={
Expand All @@ -158,8 +146,6 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
: "")
}
autoFocus={index === 0}
invalid={!!errors[member.uuid]}
invalidText={errors[member.uuid]?.message}
/>
)}
/>
Expand All @@ -169,22 +155,25 @@ const ResultFormField: React.FC<ResultFormFieldProps> = ({
if (isCoded(member)) {
return (
<Controller
key={member.uuid}
name={member.uuid}
control={control}
rules={{
required: true,
}}
render={({ field }) => (
<Select
key={member.uuid}
className={styles.textInput}
{...field}
type="text"
labelText={member?.display}
autoFocus={index === 0}
invalid={!!errors[member.uuid]}
invalidText={errors[member.uuid]?.message}
>
<SelectItem
text={t("chooseOption", "Choose an Option")}
text={t("option", "Choose an Option")}
value=""
/>

{member?.answers?.map((answer) => (
<SelectItem
key={answer.uuid}
Expand Down
Loading

0 comments on commit 6db0fb2

Please sign in to comment.