73 lines · 2.8 KB
import { Button } from "~/ui/Button";
import { TextAreaField, TextField } from "~/ui/Field";
import { ErrorBanner } from "~/ui/Callout";
import { EmptyState } from "~/ui/EmptyState";
import { Panel } from "~/ui/Panel";
import { RelativeTime } from "~/ui/RelativeTime";

type Item = { name: string; value?: string; updatedAt: number; detail?: string };

type Props = {
  title: string;
  kind: "secret" | "variable";
  items: Item[];
  pending: boolean;
  error: string | null;
  onSave: (name: string, value: string, form: FormData) => Promise<boolean>;
  onDelete: (name: string) => void;
  extraFields?: React.ReactNode;
};

/** Add/list/remove panel shared by repository, environment and owner secrets and variables. */
export function ConfigValueList({ title, kind, items, pending, error, onSave, onDelete, extraFields }: Props) {
  return (
    <Panel title={title}>
      <form
        className="space-y-3 border-b border-gray-800 p-4"
        onSubmit={async (event) => {
          event.preventDefault();
          const element = event.currentTarget;
          const form = new FormData(element);
          const ok = await onSave(String(form.get("name") ?? ""), String(form.get("value") ?? ""), form);
          if (ok) element.reset();
        }}
      >
        <ErrorBanner message={error} />
        <div className="grid gap-3 md:grid-cols-[1fr_2fr]">
          <TextField label="Name" name="name" required placeholder={kind === "secret" ? "DEPLOY_TOKEN" : "REGION"} />
          {kind === "secret" ? (
            <TextAreaField label="Value" name="value" rows={2} required />
          ) : (