Files
kandev/apps/web/components/automations/trigger-configs/github-ci-config.tsx
T
João Salavisa 24c3b594ce fix(i18n): anchor the literal guard's exclusions so they stop swallowing copy (#2288)
Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 19:36:27 +02:00

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>
);
}