24c3b594ce
Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Checkbox } from "@kandev/ui/checkbox";
|
|
import { Input } from "@kandev/ui/input";
|
|
import { Label } from "@kandev/ui/label";
|
|
|
|
type GitHubCIConfigProps = {
|
|
config: Record<string, unknown>;
|
|
onUpdate: (config: Record<string, unknown>) => void;
|
|
};
|
|
|
|
// `value` is the GitHub check-run conclusion persisted in the trigger config
|
|
// and matched by the backend — protocol. Only the label is copy.
|
|
const CI_CONCLUSIONS = [
|
|
{ value: "success", labelKey: "automations:ciConclusionSuccess" },
|
|
{ value: "failure", labelKey: "automations:ciConclusionFailure" },
|
|
{ value: "cancelled", labelKey: "automations:ciConclusionCancelled" },
|
|
] as const;
|
|
|
|
export function GitHubCIConfig({ config, onUpdate }: GitHubCIConfigProps) {
|
|
const { t } = useTranslation();
|
|
const conclusions = (config.conclusions as string[]) ?? [];
|
|
const configCheckNames = ((config.check_names as string[]) ?? []).join(", ");
|
|
const [checkNames, setCheckNames] = useState(configCheckNames);
|
|
useEffect(() => {
|
|
setCheckNames(configCheckNames);
|
|
}, [configCheckNames]);
|
|
|
|
const toggleConclusion = (conclusion: string) => {
|
|
const next = conclusions.includes(conclusion)
|
|
? conclusions.filter((c) => c !== conclusion)
|
|
: [...conclusions, conclusion];
|
|
onUpdate({ ...config, conclusions: next });
|
|
};
|
|
|
|
const handleCheckNamesBlur = () => {
|
|
const parsed = checkNames
|
|
.split(",")
|
|
.map((n) => n.trim())
|
|
.filter(Boolean);
|
|
onUpdate({ ...config, check_names: parsed });
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-3">
|
|
<div className="space-y-2">
|
|
<Label className="text-xs">{t("automations:ciConclusionsLabel")}</Label>
|
|
<div className="flex flex-wrap gap-3">
|
|
{CI_CONCLUSIONS.map((c) => (
|
|
<label key={c.value} className="flex items-center gap-1.5 cursor-pointer">
|
|
<Checkbox
|
|
checked={conclusions.includes(c.value)}
|
|
onCheckedChange={() => toggleConclusion(c.value)}
|
|
className="cursor-pointer"
|
|
/>
|
|
<span className="text-sm">{t(c.labelKey)}</span>
|
|
</label>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<div className="space-y-1.5">
|
|
<Label className="text-xs">{t("automations:checkNamesLabel")}</Label>
|
|
{/* The placeholder is an example list of literal CI check names — data
|
|
the user types verbatim, not copy. */}
|
|
<Input
|
|
value={checkNames}
|
|
onChange={(e) => setCheckNames(e.target.value)}
|
|
onBlur={handleCheckNamesBlur}
|
|
// eslint-disable-next-line i18next/no-literal-string -- example check names, see above
|
|
placeholder="build, test, lint"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|