feat: add form_type error (#18067)

Normally parameters had red text for error diagnostics. The goal here is
to make errors more obvious when the form_type is error meaning the
parameter could not be processed correctly.

<img width="543" alt="Screenshot 2025-05-27 at 18 35 50"
src="https://github.com/user-attachments/assets/2265553e-34a3-4526-8209-6253d541f784"
/>
This commit is contained in:
Jaayden Halko
2025-05-27 15:35:11 -04:00
committed by GitHub
parent 9fc3329575
commit 5b9c40481f
3 changed files with 82 additions and 50 deletions
@@ -156,6 +156,32 @@ export const Slider: Story = {
},
};
export const ErrorFormType: Story = {
args: {
parameter: {
...MockPreviewParameter,
form_type: "error",
type: "string",
diagnostics: [
{
severity: "error",
summary: "This is an error",
detail:
"This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message.",
extra: { code: "" },
},
{
severity: "error",
summary: "This is an error",
detail:
"This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message. This is a longer error message.",
extra: { code: "" },
},
],
},
},
};
export const Disabled: Story = {
args: {
parameter: {
@@ -34,7 +34,13 @@ import {
} from "components/Tooltip/Tooltip";
import { useDebouncedValue } from "hooks/debounce";
import { useEffectEvent } from "hooks/hookPolyfills";
import { Info, LinkIcon, Settings, TriangleAlert } from "lucide-react";
import {
CircleAlert,
Info,
LinkIcon,
Settings,
TriangleAlert,
} from "lucide-react";
import { type FC, useEffect, useId, useRef, useState } from "react";
import type { AutofillBuildParameter } from "utils/richParameters";
import * as Yup from "yup";
@@ -89,7 +95,9 @@ export const DynamicParameter: FC<DynamicParameterProps> = ({
/>
)}
</div>
<ParameterDiagnostics diagnostics={parameter.diagnostics} />
{parameter.form_type !== "error" && (
<ParameterDiagnostics diagnostics={parameter.diagnostics} />
)}
</div>
);
};
@@ -508,6 +516,8 @@ const ParameterField: FC<ParameterFieldProps> = ({
<span className="w-4 font-medium">{parameter.value.value}</span>
</div>
);
case "error":
return <Diagnostics diagnostics={parameter.diagnostics} />;
}
};
@@ -832,3 +842,45 @@ const parameterError = (
(match) => r.get(match) || "",
);
};
interface DiagnosticsProps {
diagnostics: PreviewParameter["diagnostics"];
}
// Displays a diagnostic with a border, icon and background color
export const Diagnostics: FC<DiagnosticsProps> = ({ diagnostics }) => {
return (
<div className="flex flex-col gap-4">
{diagnostics.map((diagnostic, index) => (
<div
key={`diagnostic-${diagnostic.summary}-${index}`}
className={`text-xs font-semibold flex flex-col rounded-md border px-3.5 py-3.5 border-solid
${
diagnostic.severity === "error"
? "text-content-primary border-border-destructive bg-content-destructive/15"
: "text-content-primary border-border-warning bg-content-warning/15"
}`}
>
<div className="flex flex-row items-start">
{diagnostic.severity === "error" && (
<CircleAlert
className="me-2 inline-flex shrink-0 text-content-destructive size-icon-sm"
aria-hidden="true"
/>
)}
{diagnostic.severity === "warning" && (
<TriangleAlert
className="me-2 inline-flex shrink-0 text-content-warning size-icon-sm"
aria-hidden="true"
/>
)}
<div className="flex flex-col gap-3">
<p className="m-0">{diagnostic.summary}</p>
{diagnostic.detail && <p className="m-0">{diagnostic.detail}</p>}
</div>
</div>
</div>
))}
</div>
);
};
@@ -26,14 +26,9 @@ import {
} from "components/Tooltip/Tooltip";
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
import { type FormikContextType, useFormik } from "formik";
import {
ArrowLeft,
CircleAlert,
CircleHelp,
TriangleAlert,
Undo2,
} from "lucide-react";
import { ArrowLeft, CircleHelp, Undo2 } from "lucide-react";
import { useSyncFormParameters } from "modules/hooks/useSyncFormParameters";
import { Diagnostics } from "modules/workspaces/DynamicParameter/DynamicParameter";
import {
DynamicParameter,
getInitialParameterValues,
@@ -665,44 +660,3 @@ export const CreateWorkspacePageViewExperimental: FC<
</>
);
};
interface DiagnosticsProps {
diagnostics: PreviewParameter["diagnostics"];
}
const Diagnostics: FC<DiagnosticsProps> = ({ diagnostics }) => {
return (
<div className="flex flex-col gap-4">
{diagnostics.map((diagnostic, index) => (
<div
key={`diagnostic-${diagnostic.summary}-${index}`}
className={`text-xs font-semibold flex flex-col rounded-md border px-3.5 py-3.5 border-solid
${
diagnostic.severity === "error"
? "text-content-primary border-border-destructive bg-content-destructive/15"
: "text-content-primary border-border-warning bg-content-warning/15"
}`}
>
<div className="flex flex-row items-start">
{diagnostic.severity === "error" && (
<CircleAlert
className="me-2 inline-flex shrink-0 text-content-destructive size-icon-sm"
aria-hidden="true"
/>
)}
{diagnostic.severity === "warning" && (
<TriangleAlert
className="me-2 inline-flex shrink-0 text-content-warning size-icon-sm"
aria-hidden="true"
/>
)}
<div className="flex flex-col gap-3">
<p className="m-0">{diagnostic.summary}</p>
{diagnostic.detail && <p className="m-0">{diagnostic.detail}</p>}
</div>
</div>
</div>
))}
</div>
);
};