mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: implement UI for top level dynamic parameters diagnostics (#17394)
<img width="672" alt="Screenshot 2025-04-14 at 21 31 11" src="https://github.com/user-attachments/assets/5ca25c9d-e82e-4d52-8c43-91e4dc31117d" />
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
--surface-sky: 201 94% 86%;
|
||||
--border-default: 240 6% 90%;
|
||||
--border-success: 142 76% 36%;
|
||||
--border-warning: 30.66, 97.16%, 72.35%;
|
||||
--border-destructive: 0 84% 60%;
|
||||
--border-hover: 240, 5%, 34%;
|
||||
--overlay-default: 240 5% 84% / 80%;
|
||||
@@ -67,6 +68,7 @@
|
||||
--surface-sky: 204 80% 16%;
|
||||
--border-default: 240 4% 16%;
|
||||
--border-success: 142 76% 36%;
|
||||
--border-warning: 30.66, 97.16%, 72.35%;
|
||||
--border-destructive: 0 91% 71%;
|
||||
--border-hover: 240, 5%, 34%;
|
||||
--overlay-default: 240 10% 4% / 80%;
|
||||
|
||||
@@ -247,10 +247,13 @@ const ParameterField: FC<ParameterFieldProps> = ({
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<RadioGroupItem
|
||||
id={option.value.value}
|
||||
id={`${id}-${option.value.value}`}
|
||||
value={option.value.value}
|
||||
/>
|
||||
<Label htmlFor={option.value.value} className="cursor-pointer">
|
||||
<Label
|
||||
htmlFor={`${id}-${option.value.value}`}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<OptionDisplay option={option} />
|
||||
</Label>
|
||||
</div>
|
||||
@@ -350,15 +353,15 @@ const ParameterDiagnostics: FC<ParameterDiagnosticsProps> = ({
|
||||
<div className="flex flex-col gap-2">
|
||||
{diagnostics.map((diagnostic, index) => (
|
||||
<div
|
||||
key={`diagnostic-${diagnostic.summary}-${index}`}
|
||||
key={`parameter-diagnostic-${diagnostic.summary}-${index}`}
|
||||
className={`text-xs px-1 ${
|
||||
diagnostic.severity === "error"
|
||||
? "text-content-destructive"
|
||||
: "text-content-warning"
|
||||
}`}
|
||||
>
|
||||
<div className="font-medium">{diagnostic.summary}</div>
|
||||
{diagnostic.detail && <div>{diagnostic.detail}</div>}
|
||||
<p className="font-medium">{diagnostic.summary}</p>
|
||||
{diagnostic.detail && <p className="m-0">{diagnostic.detail}</p>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import type * as TypesGen from "api/typesGenerated";
|
||||
import type {
|
||||
DynamicParametersRequest,
|
||||
PreviewDiagnostics,
|
||||
PreviewParameter,
|
||||
} from "api/typesGenerated";
|
||||
import type { PreviewDiagnostics, PreviewParameter } from "api/typesGenerated";
|
||||
import { Alert } from "components/Alert/Alert";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Avatar } from "components/Avatar/Avatar";
|
||||
@@ -19,7 +15,7 @@ import { Switch } from "components/Switch/Switch";
|
||||
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
|
||||
import { type FormikContextType, useFormik } from "formik";
|
||||
import { useDebouncedFunction } from "hooks/debounce";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { ArrowLeft, CircleAlert, TriangleAlert } from "lucide-react";
|
||||
import {
|
||||
DynamicParameter,
|
||||
getInitialParameterValues,
|
||||
@@ -413,6 +409,7 @@ export const CreateWorkspacePageViewExperimental: FC<
|
||||
parameters cannot be modified once the workspace is created.
|
||||
</p>
|
||||
</hgroup>
|
||||
<Diagnostics diagnostics={diagnostics} />
|
||||
{presets.length > 0 && (
|
||||
<Stack direction="column" spacing={2}>
|
||||
<div className="flex flex-col gap-2">
|
||||
@@ -502,3 +499,44 @@ export const CreateWorkspacePageViewExperimental: FC<
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface DiagnosticsProps {
|
||||
diagnostics: PreviewParameter["diagnostics"];
|
||||
}
|
||||
|
||||
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 flex flex-col rounded-md border px-4 pb-3 border-solid
|
||||
${
|
||||
diagnostic.severity === "error"
|
||||
? " text-content-destructive border-border-destructive"
|
||||
: " text-content-warning border-border-warning"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center m-0">
|
||||
{diagnostic.severity === "error" && (
|
||||
<CircleAlert
|
||||
className="me-2 -mt-0.5 inline-flex opacity-80"
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
{diagnostic.severity === "warning" && (
|
||||
<TriangleAlert
|
||||
className="me-2 -mt-0.5 inline-flex opacity-80"
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
<p className="font-medium">{diagnostic.summary}</p>
|
||||
</div>
|
||||
{diagnostic.detail && <p className="m-0 pb-0">{diagnostic.detail}</p>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -52,6 +52,7 @@ module.exports = {
|
||||
},
|
||||
border: {
|
||||
DEFAULT: "hsl(var(--border-default))",
|
||||
warning: "hsl(var(--border-warning))",
|
||||
destructive: "hsl(var(--border-destructive))",
|
||||
success: "hsl(var(--border-success))",
|
||||
hover: "hsl(var(--border-hover))",
|
||||
|
||||
Reference in New Issue
Block a user