// src/ui/index.tsx
import {
  usePluginAction,
  usePluginData,
  usePluginToast
} from "@rudderhq/plugin-sdk/ui";
import {
  useEffect,
  useMemo,
  useState
} from "react";

// src/constants.ts
var LINEAR_TOKEN_SETTINGS_URL = "https://linear.app/settings/account/security";
var LINEAR_PAGE_SIZE = 25;
var LINEAR_IMPORT_ALL_LIMIT = 100;
var DATA_KEYS = {
  settingsBootstrap: "settings-bootstrap",
  pageBootstrap: "page-bootstrap",
  settingsCatalog: "settings-catalog",
  catalog: "linear-catalog",
  issues: "linear-issues",
  issueLink: "issue-link"
};
var ACTION_KEYS = {
  importIssues: "import-linear-issues"
};
var RUDDER_STATUS_OPTIONS = [
  "backlog",
  "todo",
  "in_progress",
  "in_review",
  "done",
  "blocked",
  "cancelled"
];

// src/ui/index.tsx
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var layoutStyles = {
  shell: {
    display: "grid",
    gap: 16,
    color: "var(--foreground, #111827)",
    fontFamily: "ui-sans-serif, system-ui, sans-serif"
  },
  card: {
    border: "1px solid var(--border, rgba(15, 23, 42, 0.14))",
    borderRadius: 8,
    padding: 16,
    background: "var(--card, var(--background, #fff))"
  },
  title: {
    fontSize: 22,
    fontWeight: 700,
    margin: 0
  },
  subtitle: {
    margin: "6px 0 0",
    color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))",
    fontSize: 14,
    lineHeight: 1.5
  },
  row: {
    display: "flex",
    gap: 12,
    flexWrap: "wrap",
    alignItems: "center"
  },
  connectionGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
    gap: 12,
    alignItems: "end"
  },
  field: {
    display: "grid",
    gap: 6,
    minWidth: 180,
    flex: "1 1 180px"
  },
  label: {
    fontSize: 12,
    fontWeight: 700,
    color: "var(--muted-foreground, rgba(15, 23, 42, 0.66))",
    letterSpacing: 0
  },
  input: {
    width: "100%",
    border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
    borderRadius: 6,
    padding: "10px 12px",
    fontSize: 14,
    background: "var(--background, #fff)",
    color: "var(--foreground, #111827)",
    boxSizing: "border-box"
  },
  select: {
    width: "100%",
    border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
    borderRadius: 6,
    padding: "10px 12px",
    fontSize: 14,
    background: "var(--background, #fff)",
    color: "var(--foreground, #111827)",
    boxSizing: "border-box"
  },
  button: {
    border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
    borderRadius: 6,
    padding: "10px 14px",
    fontSize: 14,
    fontWeight: 600,
    background: "var(--background, #fff)",
    color: "var(--foreground, #111827)",
    cursor: "pointer"
  },
  primaryButton: {
    border: "1px solid var(--primary, #0f172a)",
    borderRadius: 6,
    padding: "10px 14px",
    fontSize: 14,
    fontWeight: 700,
    background: "var(--primary, #0f172a)",
    color: "var(--primary-foreground, #fff)",
    cursor: "pointer"
  },
  subtleButton: {
    border: "1px solid var(--border, rgba(15, 23, 42, 0.12))",
    borderRadius: 6,
    padding: "8px 12px",
    fontSize: 13,
    fontWeight: 600,
    background: "var(--secondary, rgba(15, 23, 42, 0.04))",
    color: "var(--secondary-foreground, var(--foreground, #111827))",
    cursor: "pointer"
  },
  warning: {
    border: "1px solid rgba(217, 119, 6, 0.24)",
    background: "rgba(251, 191, 36, 0.12)",
    borderRadius: 8,
    padding: 14,
    fontSize: 14,
    lineHeight: 1.5
  },
  table: {
    width: "100%",
    borderCollapse: "collapse",
    fontSize: 14
  },
  th: {
    textAlign: "left",
    fontSize: 12,
    letterSpacing: 0,
    color: "var(--muted-foreground, rgba(15, 23, 42, 0.62))",
    padding: "10px 12px",
    borderBottom: "1px solid var(--border, rgba(15, 23, 42, 0.1))"
  },
  td: {
    padding: "12px",
    borderBottom: "1px solid var(--border, rgba(15, 23, 42, 0.08))",
    verticalAlign: "top"
  },
  pill: {
    display: "inline-flex",
    alignItems: "center",
    borderRadius: 999,
    padding: "4px 10px",
    background: "var(--secondary, rgba(15, 23, 42, 0.06))",
    color: "var(--secondary-foreground, var(--foreground, #111827))",
    fontSize: 12,
    fontWeight: 600
  },
  monoLink: {
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: 12
  },
  helpText: {
    fontSize: 13,
    lineHeight: 1.5,
    color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))"
  },
  statusLine: {
    marginTop: 14,
    paddingTop: 14,
    borderTop: "1px solid var(--border, rgba(15, 23, 42, 0.1))",
    fontSize: 13,
    lineHeight: 1.5,
    color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))"
  },
  sectionHeader: {
    display: "flex",
    justifyContent: "space-between",
    gap: 12,
    alignItems: "flex-start",
    flexWrap: "wrap"
  },
  teamGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
    gap: 10,
    marginTop: 14
  },
  teamChoice: {
    display: "flex",
    gap: 10,
    alignItems: "flex-start",
    border: "1px solid var(--border, rgba(15, 23, 42, 0.14))",
    borderRadius: 8,
    padding: 12,
    cursor: "pointer",
    background: "var(--background, transparent)"
  },
  checkbox: {
    marginTop: 3
  },
  statusRuleGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
    gap: 10,
    alignItems: "center"
  }
};
var LINEAR_TOKEN_SECRET_NAME = "Linear token";
function normalizeConfig(config) {
  const legacyOrganizationMappings = Array.isArray(config?.organizationMappings) ? config.organizationMappings : [];
  const explicitTeamMappings = Array.isArray(config?.teamMappings) ? config.teamMappings : [];
  return {
    apiTokenSecretRef: config?.apiTokenSecretRef ?? "",
    teamMappings: explicitTeamMappings.length > 0 ? explicitTeamMappings : mergeLegacyTeamMappings(legacyOrganizationMappings),
    organizationMappings: legacyOrganizationMappings,
    ...config?.fixtureMode === true ? { fixtureMode: true } : {}
  };
}
function mergeLegacyTeamMappings(mappings) {
  const byTeamId = /* @__PURE__ */ new Map();
  for (const mapping of mappings) {
    for (const team of mapping.teamMappings ?? []) {
      if (!team.teamId || byTeamId.has(team.teamId)) continue;
      byTeamId.set(team.teamId, team);
    }
  }
  return [...byTeamId.values()];
}
function getOrgPrefix(context) {
  const orgPrefix = typeof context["orgPrefix"] === "string" ? context["orgPrefix"] : null;
  const companyPrefix = typeof context["companyPrefix"] === "string" ? context["companyPrefix"] : null;
  return orgPrefix ?? companyPrefix;
}
function getPluginIdFromLocation() {
  if (typeof window === "undefined") return null;
  const match = window.location.pathname.match(/\/instance\/settings\/plugins\/([^/?#]+)/);
  return match?.[1] ?? null;
}
async function apiFetch(path, init) {
  const response = await fetch(path, {
    credentials: "same-origin",
    headers: {
      "Content-Type": "application/json",
      ...init?.headers ?? {}
    },
    ...init
  });
  if (!response.ok) {
    const payload = await response.json().catch(async () => ({ error: await response.text() }));
    const message = typeof payload?.error === "string" ? payload.error : typeof payload?.message === "string" ? payload.message : `Request failed (${response.status})`;
    throw new Error(message);
  }
  return await response.json();
}
function formatRudderStatus(status) {
  return status.replaceAll("_", " ");
}
function inferRudderStatus(state) {
  const type = (state.type ?? "").toLowerCase();
  const name = state.name.toLowerCase();
  if (type.includes("completed") || name.includes("done") || name.includes("complete")) return "done";
  if (type.includes("cancel") || name.includes("cancel")) return "cancelled";
  if (name.includes("review")) return "in_review";
  if (type.includes("backlog") || type.includes("triage") || name.includes("backlog") || name.includes("triage")) return "backlog";
  if (type.includes("started") || type.includes("unstarted") || name.includes("progress") || name.includes("todo")) return "todo";
  return "backlog";
}
function buildTeamMappingsFromCatalog(catalog) {
  return catalog.teams.map((team) => buildTeamMappingFromCatalog(team));
}
function buildTeamMappingFromCatalog(team, existing) {
  const existingStatusByStateId = new Map(
    (existing?.stateMappings ?? []).map((state) => [state.linearStateId, state.rudderStatus])
  );
  return {
    teamId: team.id,
    teamName: team.name,
    stateMappings: team.states.map((state) => ({
      linearStateId: state.id,
      linearStateName: state.name,
      rudderStatus: existingStatusByStateId.get(state.id) ?? inferRudderStatus(state)
    }))
  };
}
function buildTeamMappingsForSelectedTeams(catalog, selectedTeamIds, existingTeamMappings) {
  const selected = new Set(selectedTeamIds);
  const existingByTeamId = new Map(existingTeamMappings.map((team) => [team.teamId, team]));
  return catalog.teams.filter((team) => selected.has(team.id)).map((team) => buildTeamMappingFromCatalog(team, existingByTeamId.get(team.id)));
}
function countMappedStates(teamMappings) {
  return teamMappings?.reduce((sum, team) => sum + team.stateMappings.length, 0) ?? 0;
}
function summarizeMapping(teamMappings) {
  if (!teamMappings) return "No Linear workspace loaded yet.";
  const teamCount = teamMappings.length;
  const stateCount = countMappedStates(teamMappings);
  return `${teamCount} team${teamCount === 1 ? "" : "s"} and ${stateCount} workflow state${stateCount === 1 ? "" : "s"} ready.`;
}
function isMissingSettingsCatalogHandler(error) {
  const message = error instanceof Error ? error.message : String(error);
  return /No data handler registered/i.test(message) && /settings-catalog/i.test(message);
}
function prepareConfigForSubmit(config) {
  const teamMappings = config.teamMappings.map((team) => ({
    teamId: team.teamId.trim(),
    teamName: team.teamName?.trim() || void 0,
    stateMappings: team.stateMappings.map((state) => ({
      linearStateId: state.linearStateId.trim(),
      linearStateName: state.linearStateName?.trim() || void 0,
      rudderStatus: state.rudderStatus
    })).filter((state) => state.linearStateId)
  })).filter((team) => team.teamId);
  return {
    apiTokenSecretRef: config.apiTokenSecretRef?.trim() ?? "",
    ...config.fixtureMode === true ? { fixtureMode: true } : {},
    teamMappings,
    // Keep a legacy-compatible shape for already-installed manifests that still
    // require organizationMappings during config validation. New runtime code
    // reads the top-level teamMappings field.
    organizationMappings: teamMappings.length > 0 ? [{ orgId: "__global__", teamMappings }] : []
  };
}
function summarizeImportResult(result) {
  const parts = [`Imported ${result.importedCount}`];
  if (result.duplicateCount > 0) parts.push(`${result.duplicateCount} duplicate`);
  if (result.fallbackCount > 0) parts.push(`${result.fallbackCount} fallback`);
  if (result.adjustedCount > 0) parts.push(`${result.adjustedCount} adjusted`);
  return parts.join(" / ");
}
function formatRelativeTime(timestamp) {
  if (!timestamp) return "Unknown";
  const date = new Date(timestamp);
  if (Number.isNaN(date.getTime())) return timestamp;
  return new Intl.DateTimeFormat(void 0, {
    month: "short",
    day: "numeric",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    hourCycle: "h23"
  }).format(date);
}
function issueHref(orgPrefix, issueId) {
  return orgPrefix ? `/${orgPrefix}/issues/${issueId}` : `/issues/${issueId}`;
}
function pageHref(orgPrefix, query) {
  if (!orgPrefix) return "/linear";
  const url = new URL(`/${orgPrefix}/linear`, "https://local.invalid");
  if (query) url.searchParams.set("q", query);
  return `${url.pathname}${url.search}`;
}
function linearIssueBoardHref(orgPrefix, teamId) {
  const basePath = orgPrefix ? `/${encodeURIComponent(orgPrefix)}/issues` : "/issues";
  const url = new URL(basePath, "https://local.invalid");
  url.searchParams.set("source", "linear");
  if (teamId) url.searchParams.set("linearTeamId", teamId);
  return `${url.pathname}${url.search}`;
}
function readLinearPageUrlFilters() {
  if (typeof window === "undefined") {
    return { query: "", projectId: "", teamId: "" };
  }
  const params = new URLSearchParams(window.location.search);
  return {
    query: params.get("q") ?? "",
    projectId: params.get("linearProjectId") ?? "",
    teamId: params.get("linearTeamId") ?? ""
  };
}
function useLinearFilters(initialQuery, initialProjectId = "", initialTeamId = "") {
  const [filters, setFilters] = useState({
    teamId: initialTeamId,
    stateId: "",
    projectId: initialProjectId,
    assigneeId: "",
    query: initialQuery
  });
  return [filters, setFilters];
}
function LinearPluginPage({ context }) {
  const toast = usePluginToast();
  const importIssues = usePluginAction(ACTION_KEYS.importIssues);
  const orgId = context.orgId ?? "__missing__";
  const orgPrefix = getOrgPrefix(context);
  const urlFilters = readLinearPageUrlFilters();
  const bootstrap = usePluginData(DATA_KEYS.pageBootstrap, { orgId });
  const catalog = usePluginData(DATA_KEYS.catalog, { orgId });
  const [filters, setFilters] = useLinearFilters(urlFilters.query, urlFilters.projectId, urlFilters.teamId);
  const [targetProjectId, setTargetProjectId] = useState("");
  const [afterCursor, setAfterCursor] = useState(null);
  const [cursorHistory, setCursorHistory] = useState([]);
  const [selectedIssueIds, setSelectedIssueIds] = useState([]);
  const [importing, setImporting] = useState(false);
  const issues = usePluginData(DATA_KEYS.issues, {
    orgId,
    limit: LINEAR_PAGE_SIZE,
    after: afterCursor ?? void 0,
    teamId: filters.teamId || void 0,
    stateId: filters.stateId || void 0,
    projectId: filters.projectId || void 0,
    assigneeId: filters.assigneeId || void 0,
    query: filters.query || void 0
  });
  useEffect(() => {
    setFilters((current) => {
      if (current.query === urlFilters.query && current.projectId === urlFilters.projectId && current.teamId === urlFilters.teamId) {
        return current;
      }
      return {
        ...current,
        query: urlFilters.query,
        projectId: urlFilters.projectId,
        teamId: urlFilters.teamId
      };
    });
  }, [setFilters, urlFilters.projectId, urlFilters.query, urlFilters.teamId]);
  const stateOptions = useMemo(() => {
    if (!catalog.data?.teams?.length) return [];
    const sourceTeams = filters.teamId ? catalog.data.teams.filter((team) => team.id === filters.teamId) : catalog.data.teams;
    const deduped = /* @__PURE__ */ new Map();
    for (const team of sourceTeams) {
      for (const state of team.states) {
        deduped.set(state.id, { id: state.id, name: state.name });
      }
    }
    return [...deduped.values()];
  }, [catalog.data?.teams, filters.teamId]);
  useEffect(() => {
    setAfterCursor(null);
    setCursorHistory([]);
    setSelectedIssueIds([]);
  }, [filters.teamId, filters.stateId, filters.projectId, filters.assigneeId, filters.query]);
  useEffect(() => {
    const visibleIds = new Set(issues.data?.rows.map((row) => row.id) ?? []);
    setSelectedIssueIds((current) => {
      const next = current.filter((id) => visibleIds.has(id));
      if (next.length === current.length && next.every((id, index) => id === current[index])) {
        return current;
      }
      return next;
    });
  }, [issues.data?.rows]);
  async function handleImport(mode, issueIds) {
    if (!targetProjectId) {
      toast({
        title: "Choose a target project",
        body: "Imports are disabled until a Rudder project is selected.",
        tone: "warn"
      });
      return;
    }
    setImporting(true);
    try {
      const result = await importIssues({
        orgId,
        targetProjectId,
        mode,
        issueIds,
        filters: {
          teamId: filters.teamId || void 0,
          stateId: filters.stateId || void 0,
          projectId: filters.projectId || void 0,
          assigneeId: filters.assigneeId || void 0,
          query: filters.query || void 0
        }
      });
      toast({
        title: "Linear import complete",
        body: summarizeImportResult(result),
        tone: "success"
      });
      issues.refresh();
      setSelectedIssueIds([]);
    } catch (error) {
      toast({
        title: "Linear import failed",
        body: error instanceof Error ? error.message : String(error),
        tone: "error"
      });
    } finally {
      setImporting(false);
    }
  }
  return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
    /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsx("h1", { style: layoutStyles.title, children: "Linear intake" }),
      /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Import Linear issues into a chosen Rudder project. This page is the bulk workspace; the issue tab is the linked detail view." })
    ] }),
    bootstrap.loading ? /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: "Loading Linear import context\u2026" }) : !bootstrap.data?.configured ? /* @__PURE__ */ jsxs("section", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: [
      /* @__PURE__ */ jsx("strong", { children: "Linear is not configured yet." }),
      /* @__PURE__ */ jsx("div", { style: { marginTop: 8 }, children: bootstrap.data?.message ?? "Connect Linear and choose teams in plugin settings." }),
      /* @__PURE__ */ jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsx("a", { href: "/instance/settings/plugins", style: layoutStyles.monoLink, children: "Open plugin settings" }) })
    ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "target-project", children: "Target Rudder project" }),
          /* @__PURE__ */ jsxs(
            "select",
            {
              id: "target-project",
              "data-testid": "linear-target-project",
              style: layoutStyles.select,
              value: targetProjectId,
              onChange: (event) => setTargetProjectId(event.target.value),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: "Choose a project" }),
                (bootstrap.data?.projects ?? []).map((project) => /* @__PURE__ */ jsx("option", { value: project.id, children: project.name }, project.id))
              ]
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-team-filter", children: "Linear team" }),
          /* @__PURE__ */ jsxs(
            "select",
            {
              id: "linear-team-filter",
              style: layoutStyles.select,
              value: filters.teamId,
              onChange: (event) => setFilters((current) => ({ ...current, teamId: event.target.value, stateId: "" })),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: "All allowed teams" }),
                (catalog.data?.teams ?? []).map((team) => /* @__PURE__ */ jsx("option", { value: team.id, children: team.name }, team.id))
              ]
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-state-filter", children: "Workflow state" }),
          /* @__PURE__ */ jsxs(
            "select",
            {
              id: "linear-state-filter",
              style: layoutStyles.select,
              value: filters.stateId,
              onChange: (event) => setFilters((current) => ({ ...current, stateId: event.target.value })),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: "All states" }),
                stateOptions.map((state) => /* @__PURE__ */ jsx("option", { value: state.id, children: state.name }, state.id))
              ]
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-project-filter", children: "Linear project" }),
          /* @__PURE__ */ jsxs(
            "select",
            {
              id: "linear-project-filter",
              style: layoutStyles.select,
              value: filters.projectId,
              onChange: (event) => setFilters((current) => ({ ...current, projectId: event.target.value })),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: "All projects" }),
                (catalog.data?.projects ?? []).map((project) => /* @__PURE__ */ jsx("option", { value: project.id, children: project.name }, project.id))
              ]
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-assignee-filter", children: "Assignee" }),
          /* @__PURE__ */ jsxs(
            "select",
            {
              id: "linear-assignee-filter",
              style: layoutStyles.select,
              value: filters.assigneeId,
              onChange: (event) => setFilters((current) => ({ ...current, assigneeId: event.target.value })),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: "Anyone" }),
                (catalog.data?.users ?? []).map((user) => /* @__PURE__ */ jsx("option", { value: user.id, children: user.name }, user.id))
              ]
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-query-filter", children: "Search" }),
          /* @__PURE__ */ jsx(
            "input",
            {
              id: "linear-query-filter",
              style: layoutStyles.input,
              value: filters.query,
              onChange: (event) => setFilters((current) => ({ ...current, query: event.target.value })),
              placeholder: "Identifier, title, or description"
            }
          )
        ] })
      ] }) }),
      /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
        /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between" }, children: [
          /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.button,
                onClick: () => {
                  const rows = issues.data?.rows ?? [];
                  const selectableIds = rows.filter((row) => !row.imported).map((row) => row.id);
                  setSelectedIssueIds(selectableIds);
                },
                disabled: issues.loading,
                children: "Select current page"
              }
            ),
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.button,
                onClick: () => setSelectedIssueIds([]),
                disabled: selectedIssueIds.length === 0,
                children: "Clear selection"
              }
            )
          ] }),
          /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.button,
                disabled: !targetProjectId || selectedIssueIds.length === 0 || importing,
                onClick: () => void handleImport("selected", selectedIssueIds),
                children: "Import selected"
              }
            ),
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.primaryButton,
                "data-testid": "linear-import-all",
                disabled: !targetProjectId || importing,
                onClick: () => void handleImport("allMatching"),
                title: `Imports up to ${LINEAR_IMPORT_ALL_LIMIT} matching issues.`,
                children: "Import all matching"
              }
            )
          ] })
        ] }),
        !targetProjectId && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, ...layoutStyles.warning }, children: "Choose a target Rudder project to enable per-row, selected, or all-matching import actions." })
      ] }),
      /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: issues.loading ? /* @__PURE__ */ jsx("div", { children: "Loading Linear issues\u2026" }) : issues.error ? /* @__PURE__ */ jsx("div", { style: layoutStyles.warning, children: issues.error.message }) : /* @__PURE__ */ jsxs(Fragment, { children: [
        /* @__PURE__ */ jsxs("table", { style: layoutStyles.table, children: [
          /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Issue" }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "State" }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Project" }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Assignee" }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Status" }),
            /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Action" })
          ] }) }),
          /* @__PURE__ */ jsx("tbody", { children: (issues.data?.rows ?? []).map((row) => {
            const checked = selectedIssueIds.includes(row.id);
            const sameOrgLink = row.imported && (!row.importedOrgId || row.importedOrgId === context.orgId);
            return /* @__PURE__ */ jsxs("tr", { children: [
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: /* @__PURE__ */ jsx(
                "input",
                {
                  type: "checkbox",
                  checked,
                  disabled: row.imported,
                  onChange: (event) => {
                    setSelectedIssueIds((current) => {
                      if (event.target.checked) return [...current, row.id];
                      return current.filter((id) => id !== row.id);
                    });
                  }
                }
              ) }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6 }, children: [
                /* @__PURE__ */ jsxs("a", { href: row.url, target: "_blank", rel: "noreferrer", children: [
                  /* @__PURE__ */ jsx("strong", { children: row.identifier }),
                  " ",
                  row.title
                ] }),
                /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: row.team.name })
              ] }) }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.state.name }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.project?.name ?? "None" }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.assignee?.name ?? "Unassigned" }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.imported ? /* @__PURE__ */ jsx("span", { "data-testid": `linear-imported-${row.id}`, style: layoutStyles.pill, children: "Imported" }) : /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: "Ready" }) }),
              /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.imported ? sameOrgLink && row.importedRudderIssueId ? /* @__PURE__ */ jsx("a", { href: issueHref(orgPrefix, row.importedRudderIssueId), children: "Open Rudder issue" }) : /* @__PURE__ */ jsx("span", { children: "Imported elsewhere" }) : /* @__PURE__ */ jsx(
                "button",
                {
                  type: "button",
                  style: layoutStyles.subtleButton,
                  disabled: !targetProjectId || importing,
                  onClick: () => void handleImport("single", [row.id]),
                  children: "Import"
                }
              ) })
            ] }, row.id);
          }) })
        ] }),
        (issues.data?.rows.length ?? 0) === 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 16, color: "rgba(15, 23, 42, 0.68)" }, children: "No Linear issues matched the current filters." }),
        /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between", marginTop: 16 }, children: [
          /* @__PURE__ */ jsxs("span", { style: { fontSize: 13, color: "rgba(15, 23, 42, 0.68)" }, children: [
            "Showing ",
            issues.data?.totalShown ?? 0,
            " issue(s)."
          ] }),
          /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.button,
                disabled: cursorHistory.length === 0 || importing,
                onClick: () => {
                  setCursorHistory((current) => {
                    const nextHistory = [...current];
                    const previousCursor = nextHistory.pop() ?? null;
                    setAfterCursor(previousCursor);
                    return nextHistory;
                  });
                },
                children: "Previous"
              }
            ),
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                style: layoutStyles.button,
                disabled: !issues.data?.hasNextPage || importing,
                onClick: () => {
                  if (!issues.data?.endCursor) return;
                  setCursorHistory((current) => [...current, afterCursor ?? ""]);
                  setAfterCursor(issues.data.endCursor);
                },
                children: "Next"
              }
            )
          ] })
        ] })
      ] }) })
    ] })
  ] });
}
function LinearIssueTab({ context }) {
  const orgId = context.orgId ?? "__missing__";
  const orgPrefix = getOrgPrefix(context);
  const data = usePluginData(DATA_KEYS.issueLink, {
    orgId,
    issueId: context.entityId
  });
  if (data.loading) {
    return /* @__PURE__ */ jsx("div", { style: layoutStyles.card, children: "Loading Linear issue details\u2026" });
  }
  if (data.error) {
    return /* @__PURE__ */ jsx("div", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: data.error.message });
  }
  if (!data.data || !data.data.linked) {
    return /* @__PURE__ */ jsxs("div", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "No linked Linear issue" }),
      /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "This Rudder issue has not been imported from Linear yet." }),
      /* @__PURE__ */ jsx("a", { href: pageHref(orgPrefix, data.data?.searchQuery ?? ""), children: "Open Linear intake with this issue title as the search query" })
    ] });
  }
  const latest = data.data.latestIssue;
  const link = data.data.link;
  return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
    /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "Linked Linear issue" }),
      /* @__PURE__ */ jsxs("p", { style: layoutStyles.subtitle, children: [
        link.linearIdentifier,
        " maps to this Rudder issue."
      ] }),
      /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, marginTop: 12 }, children: [
        /* @__PURE__ */ jsx("a", { href: link.linearUrl, target: "_blank", rel: "noreferrer", children: "Open in Linear" }),
        /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.team.name ?? link.teamName }),
        /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.state.name ?? link.stateName }),
        latest?.project?.name ? /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest.project.name }) : null
      ] })
    ] }),
    data.data.staleReason ? /* @__PURE__ */ jsx("section", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: data.data.staleReason }) : null,
    /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsxs("h3", { style: { marginTop: 0 }, children: [
        latest?.identifier ?? link.linearIdentifier,
        " ",
        latest?.title ?? link.linearTitle
      ] }),
      /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, marginBottom: 12 }, children: [
        /* @__PURE__ */ jsxs("span", { style: layoutStyles.pill, children: [
          "Updated ",
          formatRelativeTime(latest?.updatedAt ?? link.updatedAt)
        ] }),
        /* @__PURE__ */ jsxs("span", { style: layoutStyles.pill, children: [
          "Imported ",
          formatRelativeTime(link.importedAt)
        ] }),
        /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.assignee?.name ?? "Unassigned" })
      ] }),
      /* @__PURE__ */ jsx("div", { style: { whiteSpace: "pre-wrap", lineHeight: 1.6 }, children: latest?.description?.trim() || "This Linear issue has no description." })
    ] })
  ] });
}
function LinearPluginSettingsPage(_props) {
  const toast = usePluginToast();
  const bootstrap = usePluginData(DATA_KEYS.settingsBootstrap);
  const [draft, setDraft] = useState(normalizeConfig(null));
  const [tokenInput, setTokenInput] = useState("");
  const [settingsCatalog, setSettingsCatalog] = useState(null);
  const [catalogLoading, setCatalogLoading] = useState(false);
  const [catalogError, setCatalogError] = useState(null);
  const [connecting, setConnecting] = useState(false);
  const [saving, setSaving] = useState(false);
  const pluginId = getPluginIdFromLocation();
  useEffect(() => {
    if (!bootstrap.data) return;
    const nextDraft = normalizeConfig(bootstrap.data.config);
    setDraft(nextDraft);
  }, [bootstrap.data]);
  useEffect(() => {
    if (!pluginId || !draft.apiTokenSecretRef) {
      setSettingsCatalog(null);
      setCatalogError(null);
      setCatalogLoading(false);
      return;
    }
    let cancelled = false;
    setCatalogLoading(true);
    setCatalogError(null);
    void fetchSettingsCatalog().then((catalog) => {
      if (cancelled) return;
      setSettingsCatalog(catalog);
      setDraft((current) => {
        const normalized = normalizeConfig(current);
        const selectedTeamIds2 = normalized.teamMappings.map((team) => team.teamId).filter(Boolean);
        const nextTeamMappings = selectedTeamIds2.length > 0 ? buildTeamMappingsForSelectedTeams(catalog, selectedTeamIds2, normalized.teamMappings) : buildTeamMappingsFromCatalog(catalog);
        return {
          ...normalized,
          teamMappings: nextTeamMappings
        };
      });
    }).catch((error) => {
      if (cancelled) return;
      setSettingsCatalog(null);
      setCatalogError(error instanceof Error ? error.message : String(error));
    }).finally(() => {
      if (!cancelled) setCatalogLoading(false);
    });
    return () => {
      cancelled = true;
    };
  }, [draft.apiTokenSecretRef, pluginId]);
  const selectedTeamIds = draft.teamMappings.map((team) => team.teamId).filter(Boolean);
  const selectedTeamIdSet = new Set(selectedTeamIds);
  const selectedTeamCount = selectedTeamIds.length;
  const catalogTeamCount = settingsCatalog?.teams.length ?? 0;
  const issueBoardHref = linearIssueBoardHref(
    bootstrap.data?.organizations[0]?.issuePrefix ?? null,
    selectedTeamIds[0] ?? null
  );
  async function savePluginConfig(config) {
    if (!pluginId) throw new Error("Unable to resolve plugin id");
    return await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/config`, {
      method: "POST",
      body: JSON.stringify({ configJson: prepareConfigForSubmit(config) })
    });
  }
  async function listOrgSecrets(orgId) {
    return await apiFetch(`/api/orgs/${encodeURIComponent(orgId)}/secrets`);
  }
  async function rotateSecret(secretId, value) {
    return await apiFetch(`/api/secrets/${encodeURIComponent(secretId)}/rotate`, {
      method: "POST",
      body: JSON.stringify({ value })
    });
  }
  async function createLinearTokenSecret(orgId, value) {
    return await apiFetch(`/api/orgs/${encodeURIComponent(orgId)}/secrets`, {
      method: "POST",
      body: JSON.stringify({
        name: LINEAR_TOKEN_SECRET_NAME,
        value,
        description: "Used by the Linear plugin to read issues across Rudder organizations."
      })
    });
  }
  async function saveLinearTokenSecret(orgId, value, currentSecretRef) {
    if (currentSecretRef) {
      const rotated = await rotateSecret(currentSecretRef, value);
      return rotated.id;
    }
    try {
      const created = await createLinearTokenSecret(orgId, value);
      return created.id;
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      if (!/Secret already exists/i.test(message)) throw error;
      const existing = (await listOrgSecrets(orgId)).find((secret) => secret.name === LINEAR_TOKEN_SECRET_NAME);
      if (!existing) throw error;
      const rotated = await rotateSecret(existing.id, value);
      return rotated.id;
    }
  }
  async function fetchPluginData(key, params = {}, orgId) {
    if (!pluginId) throw new Error("Unable to resolve plugin id");
    const payload = await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/data/${key}`, {
      method: "POST",
      body: JSON.stringify({
        ...orgId ? { orgId } : {},
        params: {
          ...params,
          ...orgId ? { orgId } : {}
        }
      })
    });
    return payload.data;
  }
  async function fetchSettingsCatalogWithRetry() {
    let lastError = null;
    for (let attempt = 0; attempt < 5; attempt += 1) {
      try {
        return await fetchPluginData(DATA_KEYS.settingsCatalog);
      } catch (error) {
        if (isMissingSettingsCatalogHandler(error)) throw error;
        lastError = error;
        await new Promise((resolve) => window.setTimeout(resolve, 350 + attempt * 250));
      }
    }
    throw lastError instanceof Error ? lastError : new Error(String(lastError));
  }
  async function refreshPluginRuntime() {
    if (!pluginId) throw new Error("Unable to resolve plugin id");
    await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/disable`, {
      method: "POST",
      body: JSON.stringify({ reason: "Refresh Linear plugin after settings update" })
    });
    await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/enable`, {
      method: "POST",
      body: JSON.stringify({})
    });
  }
  async function fetchSettingsCatalog() {
    try {
      return await fetchSettingsCatalogWithRetry();
    } catch (error) {
      if (!isMissingSettingsCatalogHandler(error)) throw error;
      await refreshPluginRuntime();
      return await fetchSettingsCatalogWithRetry();
    }
  }
  function toggleTeam(teamId) {
    if (!settingsCatalog) return;
    setDraft((current) => {
      const normalized = normalizeConfig(current);
      const nextTeamIds = new Set(normalized.teamMappings.map((team) => team.teamId).filter(Boolean));
      if (nextTeamIds.has(teamId)) {
        nextTeamIds.delete(teamId);
      } else {
        nextTeamIds.add(teamId);
      }
      return {
        ...normalized,
        teamMappings: buildTeamMappingsForSelectedTeams(settingsCatalog, [...nextTeamIds], normalized.teamMappings)
      };
    });
  }
  function selectAllTeams() {
    if (!settingsCatalog) return;
    setDraft((current) => {
      const normalized = normalizeConfig(current);
      return {
        ...normalized,
        teamMappings: buildTeamMappingsForSelectedTeams(
          settingsCatalog,
          settingsCatalog.teams.map((team) => team.id),
          normalized.teamMappings
        )
      };
    });
  }
  function setStatusRule(teamId, stateId, rudderStatus) {
    setDraft((current) => ({
      ...current,
      teamMappings: current.teamMappings.map((team) => {
        if (team.teamId !== teamId) return team;
        return {
          ...team,
          stateMappings: team.stateMappings.map(
            (state) => state.linearStateId === stateId ? { ...state, rudderStatus } : state
          )
        };
      })
    }));
  }
  async function connectLinear() {
    if (!pluginId) {
      toast({ title: "Unable to resolve plugin id", tone: "error" });
      return;
    }
    setConnecting(true);
    try {
      let apiTokenSecretRef = draft.apiTokenSecretRef?.trim() ?? "";
      const trimmedToken = tokenInput.trim();
      if (trimmedToken) {
        const secretOrgId = bootstrap.data?.organizations[0]?.id ?? "";
        if (!secretOrgId) {
          toast({
            title: "Create a Rudder organization first",
            body: "Rudder needs one organization to store the Linear token reference.",
            tone: "warn"
          });
          return;
        }
        apiTokenSecretRef = await saveLinearTokenSecret(secretOrgId, trimmedToken, apiTokenSecretRef);
      }
      if (!apiTokenSecretRef) {
        toast({
          title: "Paste a Linear token",
          body: "Create one in Linear, paste it here, then connect.",
          tone: "warn"
        });
        return;
      }
      const seedConfig = {
        ...draft,
        apiTokenSecretRef
      };
      await savePluginConfig(seedConfig);
      const catalog = await fetchSettingsCatalog();
      if (catalog.teams.length === 0) {
        throw new Error("Linear returned no teams for this token.");
      }
      const generatedTeamMappings = buildTeamMappingsFromCatalog(catalog);
      const nextConfig = prepareConfigForSubmit({
        ...seedConfig,
        teamMappings: generatedTeamMappings
      });
      await savePluginConfig(nextConfig);
      setSettingsCatalog(catalog);
      setCatalogError(null);
      setDraft(nextConfig);
      setTokenInput("");
      bootstrap.refresh();
      const firstTeamId = generatedTeamMappings[0]?.teamId ?? null;
      const firstOrgPrefix = bootstrap.data?.organizations[0]?.issuePrefix ?? null;
      toast({
        title: "Linear is ready",
        body: summarizeMapping(generatedTeamMappings),
        tone: "success",
        action: {
          label: "Open Linear issues",
          href: linearIssueBoardHref(firstOrgPrefix, firstTeamId)
        }
      });
    } catch (error) {
      toast({
        title: "Linear connection failed",
        body: error instanceof Error ? error.message : String(error),
        tone: "error"
      });
    } finally {
      setConnecting(false);
    }
  }
  async function saveConfig() {
    if (!pluginId) {
      toast({ title: "Unable to resolve plugin id", tone: "error" });
      return;
    }
    if (draft.apiTokenSecretRef && settingsCatalog && selectedTeamCount === 0) {
      toast({
        title: "Choose at least one Linear team",
        body: "The import page needs one or more teams to show Linear issues.",
        tone: "warn"
      });
      return;
    }
    setSaving(true);
    try {
      await savePluginConfig(draft);
      bootstrap.refresh();
      toast({
        title: "Linear settings saved",
        tone: "success"
      });
    } catch (error) {
      toast({
        title: "Failed to save Linear settings",
        body: error instanceof Error ? error.message : String(error),
        tone: "error"
      });
    } finally {
      setSaving(false);
    }
  }
  function connectionStatusText() {
    if (bootstrap.loading) return "Loading plugin settings\u2026";
    if (catalogLoading) return "Reading teams and workflow states from Linear\u2026";
    if (catalogError) return `Linear could not be loaded: ${catalogError}`;
    if (settingsCatalog) {
      return `Connected. ${catalogTeamCount} Linear team${catalogTeamCount === 1 ? "" : "s"} found; ${selectedTeamCount} selected for import.`;
    }
    if (draft.apiTokenSecretRef) return "Token saved. Refresh from Linear to load teams.";
    return "Paste a Linear token to connect this instance.";
  }
  return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
    /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "Linear" }),
      /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Paste a Linear token once. Rudder will read your teams and workflow states, then prepare the import settings automatically." }),
      bootstrap.data?.fixtureMode ? /* @__PURE__ */ jsx("div", { style: { marginTop: 12, ...layoutStyles.warning }, children: "Fixture mode is enabled in this environment. Linear reads use deterministic test data." }) : null
    ] }, "linear-settings-intro"),
    /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsx("div", { style: layoutStyles.sectionHeader, children: /* @__PURE__ */ jsxs("div", { children: [
        /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: "Connect Linear" }),
        /* @__PURE__ */ jsxs("p", { style: layoutStyles.subtitle, children: [
          "Paste a token and Rudder will prepare the import setup from Linear.",
          " ",
          /* @__PURE__ */ jsx("a", { href: LINEAR_TOKEN_SETTINGS_URL, target: "_blank", rel: "noreferrer", style: layoutStyles.monoLink, children: "Create a Linear token" }),
          "."
        ] })
      ] }) }),
      /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.connectionGrid, marginTop: 14 }, children: [
        /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
          /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-token", children: "Linear token" }),
          /* @__PURE__ */ jsx(
            "input",
            {
              id: "linear-token",
              "data-testid": "linear-token-input",
              style: layoutStyles.input,
              type: "password",
              autoComplete: "off",
              value: tokenInput,
              onChange: (event) => setTokenInput(event.target.value),
              placeholder: draft.apiTokenSecretRef ? "Token saved. Paste a new token to replace it." : "Paste a Linear token"
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6, justifySelf: "start" }, children: [
          /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { ...layoutStyles.label, visibility: "hidden" }, children: "Action" }),
          /* @__PURE__ */ jsx(
            "button",
            {
              type: "button",
              style: layoutStyles.primaryButton,
              "data-testid": "linear-connect",
              onClick: () => void connectLinear(),
              disabled: connecting,
              children: connecting ? "Connecting\u2026" : draft.apiTokenSecretRef ? "Refresh from Linear" : "Connect Linear"
            }
          )
        ] })
      ] }),
      /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.statusLine, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }, children: [
        /* @__PURE__ */ jsx("span", { children: connectionStatusText() }),
        settingsCatalog && selectedTeamCount > 0 ? /* @__PURE__ */ jsx("a", { href: issueBoardHref, style: layoutStyles.monoLink, children: "Open Linear issues" }) : null
      ] })
    ] }, "linear-settings-connect"),
    draft.apiTokenSecretRef ? /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
      /* @__PURE__ */ jsxs("div", { style: layoutStyles.sectionHeader, children: [
        /* @__PURE__ */ jsxs("div", { children: [
          /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: "Teams to import" }),
          /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Choose the Linear teams that should appear on the import page. Rudder stores the technical details for you." })
        ] }),
        /* @__PURE__ */ jsx(
          "button",
          {
            type: "button",
            style: layoutStyles.subtleButton,
            onClick: selectAllTeams,
            disabled: !settingsCatalog || catalogLoading || catalogTeamCount === selectedTeamCount,
            children: "Select all teams"
          }
        )
      ] }),
      catalogLoading ? /* @__PURE__ */ jsx("p", { style: layoutStyles.helpText, children: "Loading teams from Linear\u2026" }) : catalogError ? /* @__PURE__ */ jsxs("div", { style: { marginTop: 14, ...layoutStyles.warning }, children: [
        /* @__PURE__ */ jsx("strong", { children: "Linear could not be loaded." }),
        /* @__PURE__ */ jsx("div", { style: { marginTop: 6 }, children: catalogError })
      ] }) : settingsCatalog ? /* @__PURE__ */ jsxs(Fragment, { children: [
        /* @__PURE__ */ jsx("div", { style: layoutStyles.teamGrid, children: settingsCatalog.teams.map((team, index) => {
          const checked = selectedTeamIdSet.has(team.id);
          return /* @__PURE__ */ jsxs(
            "label",
            {
              style: {
                ...layoutStyles.teamChoice,
                borderColor: checked ? "var(--primary, #2563eb)" : "var(--border, rgba(15, 23, 42, 0.14))",
                background: checked ? "rgba(37, 99, 235, 0.08)" : "var(--background, transparent)"
              },
              children: [
                /* @__PURE__ */ jsx(
                  "input",
                  {
                    "data-testid": `linear-team-choice-${team.id}`,
                    style: layoutStyles.checkbox,
                    type: "checkbox",
                    checked,
                    onChange: () => toggleTeam(team.id)
                  }
                ),
                /* @__PURE__ */ jsxs("span", { children: [
                  /* @__PURE__ */ jsx("strong", { children: team.name }),
                  /* @__PURE__ */ jsxs("span", { style: { display: "block", marginTop: 3, ...layoutStyles.helpText }, children: [
                    team.key,
                    " \xB7 ",
                    team.states.length,
                    " workflow state",
                    team.states.length === 1 ? "" : "s"
                  ] })
                ] })
              ]
            },
            `${team.id}-${index}`
          );
        }) }),
        /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between", marginTop: 14 }, children: [
          /* @__PURE__ */ jsx("span", { style: layoutStyles.helpText, children: selectedTeamCount === 0 ? "Choose at least one team before saving." : `${selectedTeamCount} team${selectedTeamCount === 1 ? "" : "s"} selected for import.` }),
          /* @__PURE__ */ jsx(
            "button",
            {
              type: "button",
              style: layoutStyles.primaryButton,
              "data-testid": "linear-save-team-choices",
              onClick: () => void saveConfig(),
              disabled: saving || selectedTeamCount === 0,
              children: saving ? "Saving\u2026" : "Save choices"
            }
          )
        ] })
      ] }) : /* @__PURE__ */ jsx("p", { style: layoutStyles.helpText, children: "Refresh from Linear to load teams for this token." })
    ] }, "linear-settings-teams") : null,
    settingsCatalog && draft.teamMappings.length > 0 ? /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: /* @__PURE__ */ jsxs("details", { children: [
      /* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontWeight: 700 }, children: "Status rules (optional)" }),
      /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Rudder applies smart defaults from Linear. Change these only if imported issues land in the wrong Rudder status." }),
      /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 18, marginTop: 14 }, children: draft.teamMappings.map((teamMapping, teamIndex) => {
        const catalogTeam = settingsCatalog.teams.find((team) => team.id === teamMapping.teamId);
        const states = catalogTeam?.states ?? teamMapping.stateMappings.map((state) => ({
          id: state.linearStateId,
          name: state.linearStateName ?? "Linear status",
          type: null
        }));
        const statusByStateId = new Map(teamMapping.stateMappings.map((state) => [state.linearStateId, state.rudderStatus]));
        return /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid var(--border, rgba(15, 23, 42, 0.1))", paddingTop: 14 }, children: [
          /* @__PURE__ */ jsx("h4", { style: { margin: "0 0 10px" }, children: teamMapping.teamName ?? catalogTeam?.name ?? "Linear team" }),
          /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 8 }, children: states.map((state, stateIndex) => /* @__PURE__ */ jsxs("div", { style: layoutStyles.statusRuleGrid, children: [
            /* @__PURE__ */ jsxs("div", { children: [
              /* @__PURE__ */ jsx("strong", { children: state.name }),
              /* @__PURE__ */ jsx("div", { style: layoutStyles.helpText, children: state.type ? `${state.type} in Linear` : "Linear workflow state" })
            ] }),
            /* @__PURE__ */ jsx(
              "select",
              {
                style: layoutStyles.select,
                value: statusByStateId.get(state.id) ?? inferRudderStatus(state),
                onChange: (event) => setStatusRule(teamMapping.teamId, state.id, event.target.value),
                children: RUDDER_STATUS_OPTIONS.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: formatRudderStatus(status) }, `${teamMapping.teamId}-${state.id}-${status}`))
              }
            )
          ] }, `${teamMapping.teamId}-${state.id}-${stateIndex}`)) })
        ] }, `${teamMapping.teamId}-${teamIndex}`);
      }) }),
      /* @__PURE__ */ jsx("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx("button", { type: "button", style: layoutStyles.primaryButton, onClick: () => void saveConfig(), disabled: saving, children: saving ? "Saving\u2026" : "Save status rules" }) })
    ] }) }, "linear-settings-status-rules") : null
  ] });
}
export {
  LinearIssueTab,
  LinearPluginPage,
  LinearPluginSettingsPage
};
//# sourceMappingURL=index.js.map
