foxygit / RPA-Remisser Log in
commits tags

/webui/frontend/src/components/CallFlowFields.tsx · 4.36 KB

raw
import type { CallArg, CallRet, Step } from "../lib/api";
import type { T } from "../lib/i18n";

interface Props {
  step: Step;
  t: T;
  subflowTargets: { id: string; name: string }[];
  externalFlows: string[];
  onChange: (step: Step) => void;
  onOpenSubflow: (id: string) => void;
  onOpenExternal: (name: string) => void;
}

/** Editorn för call_flow: målväljare + in/ut-mappning. */
export function CallFlowFields({
  step,
  t,
  subflowTargets,
  externalFlows,
  onChange,
  onOpenSubflow,
  onOpenExternal,
}: Props) {
  const target = step.target ?? "";
  const ins: CallArg[] = step.in ?? [];
  const outs: CallRet[] = step.out ?? [];

  const setIn = (i: number, patch: Partial<CallArg>) =>
    onChange({ ...step, in: ins.map((r, j) => (j === i ? { ...r, ...patch } : r)) });
  const setOut = (i: number, patch: Partial<CallRet>) =>
    onChange({ ...step, out: outs.map((r, j) => (j === i ? { ...r, ...patch } : r)) });

  const isLocal = target.startsWith("#");
  const canOpen = isLocal
    ? subflowTargets.some((s) => "#" + s.id === target)
    : !!target && externalFlows.includes(target);

  return (
    <div className="callflow">
      <label className="field">
        <span>{t("callflow_target")}</span>
        <div className="callflow-target">
          <select value={target} onChange={(e) => onChange({ ...step, target: e.target.value })}>
            <option value="">—</option>
            {subflowTargets.length > 0 && (
              <optgroup label={t("callflow_local")}>
                {subflowTargets.map((s) => (
                  <option key={s.id} value={"#" + s.id}>
                    {s.name}
                  </option>
                ))}
              </optgroup>
            )}
            {externalFlows.length > 0 && (
              <optgroup label={t("callflow_external")}>
                {externalFlows.map((n) => (
                  <option key={n} value={n}>
                    {n}
                  </option>
                ))}
              </optgroup>
            )}
            {target && !canOpen && <option value={target}>{target}</option>}
          </select>
          <button
            type="button"
            className="secondary tiny"
            disabled={!canOpen}
            onClick={() => (isLocal ? onOpenSubflow(target.slice(1)) : onOpenExternal(target))}
          >
            {t("callflow_open")}
          </button>
        </div>
      </label>

      <div className="callflow-io">
        <strong>{t("callflow_in")}</strong>
        {ins.map((row, i) => (
          <div className="io-row" key={i}>
            <input
              type="text"
              placeholder={t("callflow_in_name")}
              value={row.name}
              onChange={(e) => setIn(i, { name: e.target.value })}
            />
            <span>=</span>
            <input
              type="text"
              placeholder={t("callflow_in_value")}
              value={row.value}
              onChange={(e) => setIn(i, { value: e.target.value })}
            />
            <button className="danger tiny" onClick={() => onChange({ ...step, in: ins.filter((_, j) => j !== i) })}>
              ✕
            </button>
          </div>
        ))}
        <button
          className="secondary tiny"
          onClick={() => onChange({ ...step, in: [...ins, { name: "", value: "" }] })}
        >
          {t("callflow_add_in")}
        </button>
      </div>

      <div className="callflow-io">
        <strong>{t("callflow_out")}</strong>
        {outs.map((row, i) => (
          <div className="io-row" key={i}>
            <input
              type="text"
              placeholder={t("callflow_out_from")}
              value={row.from}
              onChange={(e) => setOut(i, { from: e.target.value })}
            />
            <span>→</span>
            <input
              type="text"
              placeholder={t("callflow_out_to")}
              value={row.to}
              onChange={(e) => setOut(i, { to: e.target.value })}
            />
            <button className="danger tiny" onClick={() => onChange({ ...step, out: outs.filter((_, j) => j !== i) })}>
              ✕
            </button>
          </div>
        ))}
        <button
          className="secondary tiny"
          onClick={() => onChange({ ...step, out: [...outs, { from: "", to: "" }] })}
        >
          {t("callflow_add_out")}
        </button>
      </div>
    </div>
  );
}