@burdenoff/microfe-cosmicintersection 2026.805.1 → 2026.830.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/cosmicintersection/api/cosmicApi.d.ts +84 -2
  2. package/dist/cosmicintersection/api/cosmicApi.d.ts.map +1 -1
  3. package/dist/cosmicintersection/api/cosmicApi.js +135 -79
  4. package/dist/cosmicintersection/api/cosmicApi.js.map +1 -1
  5. package/dist/cosmicintersection/components/ActionMenu.d.ts +1 -1
  6. package/dist/cosmicintersection/components/ActionMenu.d.ts.map +1 -1
  7. package/dist/cosmicintersection/components/ActionMenu.js +51 -54
  8. package/dist/cosmicintersection/components/ActionMenu.js.map +1 -1
  9. package/dist/cosmicintersection/components/EntityFormShell.d.ts +1 -1
  10. package/dist/cosmicintersection/components/EntityFormShell.d.ts.map +1 -1
  11. package/dist/cosmicintersection/components/EntityFormShell.js +29 -27
  12. package/dist/cosmicintersection/components/EntityFormShell.js.map +1 -1
  13. package/dist/cosmicintersection/components/ErrorState.d.ts +1 -1
  14. package/dist/cosmicintersection/components/ErrorState.d.ts.map +1 -1
  15. package/dist/cosmicintersection/components/ErrorState.js +19 -17
  16. package/dist/cosmicintersection/components/ErrorState.js.map +1 -1
  17. package/dist/cosmicintersection/components/FileUploadField.d.ts.map +1 -1
  18. package/dist/cosmicintersection/components/FileUploadField.js +61 -60
  19. package/dist/cosmicintersection/components/FileUploadField.js.map +1 -1
  20. package/dist/cosmicintersection/components/LineageGraph.d.ts +6 -1
  21. package/dist/cosmicintersection/components/LineageGraph.d.ts.map +1 -1
  22. package/dist/cosmicintersection/components/LineageGraph.js.map +1 -1
  23. package/dist/cosmicintersection/components/LoadingState.d.ts +1 -1
  24. package/dist/cosmicintersection/components/LoadingState.d.ts.map +1 -1
  25. package/dist/cosmicintersection/components/LoadingState.js +15 -13
  26. package/dist/cosmicintersection/components/LoadingState.js.map +1 -1
  27. package/dist/cosmicintersection/components/PageLayout.d.ts.map +1 -1
  28. package/dist/cosmicintersection/components/PageLayout.js +28 -27
  29. package/dist/cosmicintersection/components/PageLayout.js.map +1 -1
  30. package/dist/cosmicintersection/components/Pagination.d.ts.map +1 -1
  31. package/dist/cosmicintersection/components/Pagination.js +38 -35
  32. package/dist/cosmicintersection/components/Pagination.js.map +1 -1
  33. package/dist/cosmicintersection/components/StatusBadge.d.ts.map +1 -1
  34. package/dist/cosmicintersection/components/StatusBadge.js +30 -9
  35. package/dist/cosmicintersection/components/StatusBadge.js.map +1 -1
  36. package/dist/cosmicintersection/components/StepDAG.d.ts.map +1 -1
  37. package/dist/cosmicintersection/components/StepDAG.js +22 -18
  38. package/dist/cosmicintersection/components/StepDAG.js.map +1 -1
  39. package/dist/cosmicintersection/pages/access/AccessPage.d.ts.map +1 -1
  40. package/dist/cosmicintersection/pages/access/AccessPage.js +147 -146
  41. package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
  42. package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts.map +1 -1
  43. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +260 -259
  44. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -1
  45. package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts.map +1 -1
  46. package/dist/cosmicintersection/pages/collections/CollectionsPage.js +80 -65
  47. package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -1
  48. package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts.map +1 -1
  49. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +132 -131
  50. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
  51. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.d.ts.map +1 -1
  52. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +212 -164
  53. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -1
  54. package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts.map +1 -1
  55. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +178 -177
  56. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -1
  57. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts.map +1 -1
  58. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js +138 -145
  59. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js.map +1 -1
  60. package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts.map +1 -1
  61. package/dist/cosmicintersection/pages/lineage/LineagePage.js +78 -88
  62. package/dist/cosmicintersection/pages/lineage/LineagePage.js.map +1 -1
  63. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts.map +1 -1
  64. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +125 -124
  65. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -1
  66. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts.map +1 -1
  67. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +152 -151
  68. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -1
  69. package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts.map +1 -1
  70. package/dist/cosmicintersection/pages/releases/ReleasesPage.js +175 -174
  71. package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
  72. package/dist/cosmicintersection/pages/runs/RunDetailPage.d.ts.map +1 -1
  73. package/dist/cosmicintersection/pages/runs/RunDetailPage.js +252 -118
  74. package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -1
  75. package/dist/cosmicintersection/pages/runs/RunsPage.d.ts.map +1 -1
  76. package/dist/cosmicintersection/pages/runs/RunsPage.js +197 -188
  77. package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
  78. package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts.map +1 -1
  79. package/dist/cosmicintersection/pages/sources/SourcesPage.js +65 -64
  80. package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
  81. package/dist/dev/main.d.ts.map +1 -1
  82. package/dist/shared/hooks/useTr.d.ts +12 -0
  83. package/dist/shared/hooks/useTr.d.ts.map +1 -0
  84. package/dist/shared/hooks/useTr.js +16 -0
  85. package/dist/shared/hooks/useTr.js.map +1 -0
  86. package/package.json +1 -1
@@ -1,23 +1,25 @@
1
- import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
- import { Skeleton as n, Spinner as r } from "@burdenoff/fe-libs/ui";
1
+ import { useTr as e } from "../../shared/hooks/useTr.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ import { Skeleton as r, Spinner as i } from "@burdenoff/fe-libs/ui";
3
4
  //#region src/cosmicintersection/components/LoadingState.tsx
4
- function i({ variant: i = "spinner", rows: a = 5, label: o = "Loading…", className: s }) {
5
- return i === "rows" ? /* @__PURE__ */ e("div", {
6
- className: `space-y-3 ${s ?? ""}`,
5
+ function a({ variant: a = "spinner", rows: o = 5, label: s, className: c }) {
6
+ let l = e(), u = s ?? l("cosmicintersection.common.loading", "Loading…");
7
+ return a === "rows" ? /* @__PURE__ */ t("div", {
8
+ className: `space-y-3 ${c ?? ""}`,
7
9
  role: "status",
8
- "aria-label": o,
9
- children: Array.from({ length: a }).map((t, r) => /* @__PURE__ */ e(n, { className: "h-14 w-full rounded-card" }, r))
10
- }) : /* @__PURE__ */ t("div", {
11
- className: `flex min-h-[240px] flex-col items-center justify-center gap-3 ${s ?? ""}`,
10
+ "aria-label": u,
11
+ children: Array.from({ length: o }).map((e, n) => /* @__PURE__ */ t(r, { className: "h-14 w-full rounded-card" }, n))
12
+ }) : /* @__PURE__ */ n("div", {
13
+ className: `flex min-h-[240px] flex-col items-center justify-center gap-3 ${c ?? ""}`,
12
14
  role: "status",
13
- "aria-label": o,
14
- children: [/* @__PURE__ */ e(r, { className: "size-6 text-text-secondary" }), /* @__PURE__ */ e("p", {
15
+ "aria-label": u,
16
+ children: [/* @__PURE__ */ t(i, { className: "size-6 text-text-secondary" }), /* @__PURE__ */ t("p", {
15
17
  className: "text-sm text-text-secondary",
16
- children: o
18
+ children: u
17
19
  })]
18
20
  });
19
21
  }
20
22
  //#endregion
21
- export { i as default };
23
+ export { a as default };
22
24
 
23
25
  //# sourceMappingURL=LoadingState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingState.js","names":[],"sources":["../../../src/cosmicintersection/components/LoadingState.tsx"],"sourcesContent":["import { Skeleton, Spinner } from '@burdenoff/fe-libs/ui';\n\nexport interface LoadingStateProps {\n /** `spinner` centres a spinner; `rows` renders shimmering list placeholders. */\n variant?: 'spinner' | 'rows';\n /** Number of placeholder rows for the `rows` variant. */\n rows?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * Consistent loading affordance for every CosmicIntersection query surface.\n * Token-styled only — no raw palette colours.\n */\nexport function LoadingState({\n variant = 'spinner',\n rows = 5,\n label = 'Loading…',\n className,\n}: LoadingStateProps) {\n if (variant === 'rows') {\n return (\n <div className={`space-y-3 ${className ?? ''}`} role=\"status\" aria-label={label}>\n {Array.from({ length: rows }).map((_, index) => (\n <Skeleton key={index} className=\"h-14 w-full rounded-card\" />\n ))}\n </div>\n );\n }\n\n return (\n <div\n className={`flex min-h-[240px] flex-col items-center justify-center gap-3 ${className ?? ''}`}\n role=\"status\"\n aria-label={label}\n >\n <Spinner className=\"size-6 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">{label}</p>\n </div>\n );\n}\n\nexport default LoadingState;\n"],"mappings":";;;AAeA,SAAgB,EAAa,EAC3B,aAAU,WACV,UAAO,GACP,WAAQ,YACR,gBACoB;CAWpB,OAVI,MAAY,SAEZ,kBAAC,OAAD;EAAK,WAAW,aAAa,KAAa;EAAM,MAAK;EAAS,cAAY;YACvE,MAAM,KAAK,EAAE,QAAQ,EAAK,CAAC,EAAE,KAAK,GAAG,MACpC,kBAAC,GAAD,EAAsB,WAAU,2BAA4B,GAA7C,CAA6C,CAC7D;CACE,CAAA,IAKP,kBAAC,OAAD;EACE,WAAW,iEAAiE,KAAa;EACzF,MAAK;EACL,cAAY;YAHd,CAKE,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GACjD,kBAAC,KAAD;GAAG,WAAU;aAA+B;EAAS,CAAA,CAClD;;AAET"}
1
+ {"version":3,"file":"LoadingState.js","names":[],"sources":["../../../src/cosmicintersection/components/LoadingState.tsx"],"sourcesContent":["import { Skeleton, Spinner } from '@burdenoff/fe-libs/ui';\nimport { useTr } from '../../shared/hooks/useTr';\n\nexport interface LoadingStateProps {\n /** `spinner` centres a spinner; `rows` renders shimmering list placeholders. */\n variant?: 'spinner' | 'rows';\n /** Number of placeholder rows for the `rows` variant. */\n rows?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * Consistent loading affordance for every CosmicIntersection query surface.\n * Token-styled only — no raw palette colours.\n */\nexport function LoadingState({\n variant = 'spinner',\n rows = 5,\n label: labelProp,\n className,\n}: LoadingStateProps) {\n const tr = useTr();\n const label = labelProp ?? tr('cosmicintersection.common.loading', 'Loading…');\n if (variant === 'rows') {\n return (\n <div className={`space-y-3 ${className ?? ''}`} role=\"status\" aria-label={label}>\n {Array.from({ length: rows }).map((_, index) => (\n <Skeleton key={index} className=\"h-14 w-full rounded-card\" />\n ))}\n </div>\n );\n }\n\n return (\n <div\n className={`flex min-h-[240px] flex-col items-center justify-center gap-3 ${className ?? ''}`}\n role=\"status\"\n aria-label={label}\n >\n <Spinner className=\"size-6 text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">{label}</p>\n </div>\n );\n}\n\nexport default LoadingState;\n"],"mappings":";;;;AAgBA,SAAgB,EAAa,EAC3B,aAAU,WACV,UAAO,GACP,OAAO,GACP,gBACoB;CACpB,IAAM,IAAK,EAAM,GACX,IAAQ,KAAa,EAAG,qCAAqC,UAAU;CAW7E,OAVI,MAAY,SAEZ,kBAAC,OAAD;EAAK,WAAW,aAAa,KAAa;EAAM,MAAK;EAAS,cAAY;YACvE,MAAM,KAAK,EAAE,QAAQ,EAAK,CAAC,EAAE,KAAK,GAAG,MACpC,kBAAC,GAAD,EAAsB,WAAU,2BAA4B,GAA7C,CAA6C,CAC7D;CACE,CAAA,IAKP,kBAAC,OAAD;EACE,WAAW,iEAAiE,KAAa;EACzF,MAAK;EACL,cAAY;YAHd,CAKE,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GACjD,kBAAC,KAAD;GAAG,WAAU;aAA+B;EAAS,CAAA,CAClD;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,UAAU,eAAe;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAkC9F;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,UAAU,eAAe;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAmC9F;AAED,eAAe,UAAU,CAAC"}
@@ -1,46 +1,47 @@
1
1
  import { useCosmicIntersection as e } from "../context/CosmicIntersectionContext.js";
2
- import { cn as t } from "../utils/cn.js";
3
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
- import { ChevronLeft as i } from "lucide-react";
2
+ import { useTr as t } from "../../shared/hooks/useTr.js";
3
+ import { cn as n } from "../utils/cn.js";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ import { ChevronLeft as a } from "lucide-react";
5
6
  //#region src/cosmicintersection/components/PageLayout.tsx
6
- function a({ title: a, description: o, actions: s, children: c, backPath: l }) {
7
- let { navigate: u } = e();
8
- return /* @__PURE__ */ r("div", {
9
- className: t("flex h-full flex-col bg-bg-surface"),
10
- children: [/* @__PURE__ */ r("div", {
11
- className: t("flex items-start justify-between gap-4 border-b border-border-seam bg-bg-surface px-6 py-5"),
12
- children: [/* @__PURE__ */ r("div", {
7
+ function o({ title: o, description: s, actions: c, children: l, backPath: u }) {
8
+ let { navigate: d } = e(), f = t();
9
+ return /* @__PURE__ */ i("div", {
10
+ className: n("flex h-full flex-col bg-bg-surface"),
11
+ children: [/* @__PURE__ */ i("div", {
12
+ className: n("flex items-start justify-between gap-4 border-b border-border-seam bg-bg-surface px-6 py-5"),
13
+ children: [/* @__PURE__ */ i("div", {
13
14
  className: "flex min-w-0 flex-col gap-1",
14
15
  children: [
15
- l ? /* @__PURE__ */ r("button", {
16
+ u ? /* @__PURE__ */ i("button", {
16
17
  type: "button",
17
- onClick: () => u(l),
18
- className: t("flex w-fit items-center gap-1 rounded-button text-sm text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus"),
19
- children: [/* @__PURE__ */ n(i, {
18
+ onClick: () => d(u),
19
+ className: n("flex w-fit items-center gap-1 rounded-button text-sm text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus"),
20
+ children: [/* @__PURE__ */ r(a, {
20
21
  className: "size-4",
21
22
  "aria-hidden": "true"
22
- }), "Back"]
23
+ }), f("cosmicintersection.common.back", "Back")]
23
24
  }) : null,
24
- /* @__PURE__ */ n("h1", {
25
- className: t("truncate text-2xl font-semibold text-text-primary"),
26
- children: a
27
- }),
28
- o ? /* @__PURE__ */ n("p", {
29
- className: t("mt-0.5 text-sm text-text-secondary"),
25
+ /* @__PURE__ */ r("h1", {
26
+ className: n("truncate text-2xl font-semibold text-text-primary"),
30
27
  children: o
28
+ }),
29
+ s ? /* @__PURE__ */ r("p", {
30
+ className: n("mt-0.5 text-sm text-text-secondary"),
31
+ children: s
31
32
  }) : null
32
33
  ]
33
- }), s ? /* @__PURE__ */ n("div", {
34
+ }), c ? /* @__PURE__ */ r("div", {
34
35
  className: "flex shrink-0 items-center gap-2",
35
- children: s
36
+ children: c
36
37
  }) : null]
37
- }), /* @__PURE__ */ n("div", {
38
- className: t("flex-1 overflow-auto p-6"),
39
- children: c
38
+ }), /* @__PURE__ */ r("div", {
39
+ className: n("flex-1 overflow-auto p-6"),
40
+ children: l
40
41
  })]
41
42
  });
42
43
  }
43
44
  //#endregion
44
- export { a as default };
45
+ export { o as default };
45
46
 
46
47
  //# sourceMappingURL=PageLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ChevronLeft } from 'lucide-react';\nimport { useCosmicIntersection } from '../context/CosmicIntersectionContext';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: ReactNode;\n actions?: ReactNode;\n children: ReactNode;\n /** basePath-relative path for the header back button (e.g. \"datasets\"). */\n backPath?: string;\n}\n\n/**\n * Standard page scaffold: a sticky-feeling header (optional back button, title,\n * description, right-aligned actions) over a scrollable content region. Token\n * styling only.\n */\nexport function PageLayout({ title, description, actions, children, backPath }: PageLayoutProps) {\n const { navigate } = useCosmicIntersection();\n\n return (\n <div className={cn('flex h-full flex-col bg-bg-surface')}>\n <div\n className={cn(\n 'flex items-start justify-between gap-4 border-b border-border-seam bg-bg-surface px-6 py-5'\n )}\n >\n <div className=\"flex min-w-0 flex-col gap-1\">\n {backPath ? (\n <button\n type=\"button\"\n onClick={() => navigate(backPath)}\n className={cn(\n 'flex w-fit items-center gap-1 rounded-button text-sm text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus'\n )}\n >\n <ChevronLeft className=\"size-4\" aria-hidden=\"true\" />\n Back\n </button>\n ) : null}\n <h1 className={cn('truncate text-2xl font-semibold text-text-primary')}>{title}</h1>\n {description ? (\n <p className={cn('mt-0.5 text-sm text-text-secondary')}>{description}</p>\n ) : null}\n </div>\n {actions ? <div className=\"flex shrink-0 items-center gap-2\">{actions}</div> : null}\n </div>\n\n <div className={cn('flex-1 overflow-auto p-6')}>{children}</div>\n </div>\n );\n}\n\nexport default PageLayout;\n"],"mappings":";;;;;AAmBA,SAAgB,EAAW,EAAE,UAAO,gBAAa,YAAS,aAAU,eAA6B;CAC/F,IAAM,EAAE,gBAAa,EAAsB;CAE3C,OACE,kBAAC,OAAD;EAAK,WAAW,EAAG,oCAAoC;YAAvD,CACE,kBAAC,OAAD;GACE,WAAW,EACT,4FACF;aAHF,CAKE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,IACC,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAS,CAAQ;MAChC,WAAW,EACT,oMACF;gBALF,CAOE,kBAAC,GAAD;OAAa,WAAU;OAAS,eAAY;MAAQ,CAAA,GAAC,MAE/C;UACN;KACJ,kBAAC,MAAD;MAAI,WAAW,EAAG,mDAAmD;gBAAI;KAAU,CAAA;KAClF,IACC,kBAAC,KAAD;MAAG,WAAW,EAAG,oCAAoC;gBAAI;KAAe,CAAA,IACtE;IACD;OACJ,IAAU,kBAAC,OAAD;IAAK,WAAU;cAAoC;GAAa,CAAA,IAAI,IAC5E;MAEL,kBAAC,OAAD;GAAK,WAAW,EAAG,0BAA0B;GAAI;EAAc,CAAA,CAC5D;;AAET"}
1
+ {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ChevronLeft } from 'lucide-react';\nimport { useCosmicIntersection } from '../context/CosmicIntersectionContext';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: ReactNode;\n actions?: ReactNode;\n children: ReactNode;\n /** basePath-relative path for the header back button (e.g. \"datasets\"). */\n backPath?: string;\n}\n\n/**\n * Standard page scaffold: a sticky-feeling header (optional back button, title,\n * description, right-aligned actions) over a scrollable content region. Token\n * styling only.\n */\nexport function PageLayout({ title, description, actions, children, backPath }: PageLayoutProps) {\n const { navigate } = useCosmicIntersection();\n const tr = useTr();\n\n return (\n <div className={cn('flex h-full flex-col bg-bg-surface')}>\n <div\n className={cn(\n 'flex items-start justify-between gap-4 border-b border-border-seam bg-bg-surface px-6 py-5'\n )}\n >\n <div className=\"flex min-w-0 flex-col gap-1\">\n {backPath ? (\n <button\n type=\"button\"\n onClick={() => navigate(backPath)}\n className={cn(\n 'flex w-fit items-center gap-1 rounded-button text-sm text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus'\n )}\n >\n <ChevronLeft className=\"size-4\" aria-hidden=\"true\" />\n {tr('cosmicintersection.common.back', 'Back')}\n </button>\n ) : null}\n <h1 className={cn('truncate text-2xl font-semibold text-text-primary')}>{title}</h1>\n {description ? (\n <p className={cn('mt-0.5 text-sm text-text-secondary')}>{description}</p>\n ) : null}\n </div>\n {actions ? <div className=\"flex shrink-0 items-center gap-2\">{actions}</div> : null}\n </div>\n\n <div className={cn('flex-1 overflow-auto p-6')}>{children}</div>\n </div>\n );\n}\n\nexport default PageLayout;\n"],"mappings":";;;;;;AAoBA,SAAgB,EAAW,EAAE,UAAO,gBAAa,YAAS,aAAU,eAA6B;CAC/F,IAAM,EAAE,gBAAa,EAAsB,GACrC,IAAK,EAAM;CAEjB,OACE,kBAAC,OAAD;EAAK,WAAW,EAAG,oCAAoC;YAAvD,CACE,kBAAC,OAAD;GACE,WAAW,EACT,4FACF;aAHF,CAKE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,IACC,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAS,CAAQ;MAChC,WAAW,EACT,oMACF;gBALF,CAOE,kBAAC,GAAD;OAAa,WAAU;OAAS,eAAY;MAAQ,CAAA,GACnD,EAAG,kCAAkC,MAAM,CACtC;UACN;KACJ,kBAAC,MAAD;MAAI,WAAW,EAAG,mDAAmD;gBAAI;KAAU,CAAA;KAClF,IACC,kBAAC,KAAD;MAAG,WAAW,EAAG,oCAAoC;gBAAI;KAAe,CAAA,IACtE;IACD;OACJ,IAAU,kBAAC,OAAD;IAAK,WAAU;cAAoC;GAAa,CAAA,IAAI,IAC5E;MAEL,kBAAC,OAAD;GAAK,WAAW,EAAG,0BAA0B;GAAI;EAAc,CAAA,CAC5D;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"names":[],"mappings":"AAgBA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAsBrF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAmB,EACnB,OAAe,EACf,SAAS,GACV,EAAE,eAAe,kDA8CjB;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAsBrF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAmB,EACnB,OAAe,EACf,SAAS,GACV,EAAE,eAAe,kDAiDjB;AAED,eAAe,UAAU,CAAC"}
@@ -1,12 +1,13 @@
1
- import { useState as e } from "react";
2
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
- import { ChevronLeft as r, ChevronRight as i } from "lucide-react";
4
- import { Button as a } from "@burdenoff/fe-libs/ui";
1
+ import { useTr as e } from "../../shared/hooks/useTr.js";
2
+ import { useState as t } from "react";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ import { ChevronLeft as i, ChevronRight as a } from "lucide-react";
5
+ import { Button as o } from "@burdenoff/fe-libs/ui";
5
6
  //#region src/cosmicintersection/components/Pagination.tsx
6
- var o = 50;
7
- function s(t = {}) {
8
- let { pageSize: n = o, resetKey: r } = t, [i, a] = e(0), [s, c] = e(r);
9
- return s !== r && (c(r), i !== 0 && a(0)), {
7
+ var s = 50;
8
+ function c(e = {}) {
9
+ let { pageSize: n = s, resetKey: r } = e, [i, a] = t(0), [o, c] = t(r);
10
+ return o !== r && (c(r), i !== 0 && a(0)), {
10
11
  limit: n,
11
12
  offset: i,
12
13
  page: Math.floor(i / Math.max(1, n)) + 1,
@@ -15,51 +16,53 @@ function s(t = {}) {
15
16
  reset: () => a(0)
16
17
  };
17
18
  }
18
- function c({ offset: e, limit: o, loadedCount: s, hasMore: c, onPrev: l, onNext: u, itemLabel: d = "items", loading: f = !1, className: p }) {
19
- if (e === 0 && !c && s === 0) return null;
20
- let m = s === 0 ? 0 : e + 1, h = e + s, g = e > 0, _ = c, v = Math.floor(e / Math.max(1, o)) + 1;
21
- return /* @__PURE__ */ n("div", {
22
- className: `flex flex-wrap items-center justify-between gap-3 pt-4 ${p ?? ""}`,
19
+ function l({ offset: t, limit: s, loadedCount: c, hasMore: l, onPrev: u, onNext: d, itemLabel: f = "items", loading: p = !1, className: m }) {
20
+ let h = e();
21
+ if (t === 0 && !l && c === 0) return null;
22
+ let g = c === 0 ? 0 : t + 1, _ = t + c, v = t > 0, y = l, b = Math.floor(t / Math.max(1, s)) + 1;
23
+ return /* @__PURE__ */ r("div", {
24
+ className: `flex flex-wrap items-center justify-between gap-3 pt-4 ${m ?? ""}`,
23
25
  role: "navigation",
24
26
  "aria-label": "Pagination",
25
27
  children: [/* @__PURE__ */ n("p", {
26
28
  className: "text-xs tabular-nums text-text-secondary",
27
- children: [
28
- "Showing ",
29
- m,
30
- "–",
31
- h,
32
- " ",
33
- d
34
- ]
35
- }), /* @__PURE__ */ n("div", {
29
+ children: h("cosmicintersection.common.showingResults", "Showing {{from}}–{{to}} {{itemLabel}}", {
30
+ from: g,
31
+ to: _,
32
+ itemLabel: f
33
+ })
34
+ }), /* @__PURE__ */ r("div", {
36
35
  className: "flex items-center gap-2",
37
36
  children: [
38
- /* @__PURE__ */ n("span", {
37
+ /* @__PURE__ */ r("span", {
39
38
  className: "text-xs tabular-nums text-text-secondary",
40
- children: ["Page ", v]
39
+ children: [
40
+ h("cosmicintersection.common.page", "Page"),
41
+ " ",
42
+ b
43
+ ]
41
44
  }),
42
- /* @__PURE__ */ n(a, {
45
+ /* @__PURE__ */ r(o, {
43
46
  size: "sm",
44
47
  variant: "outline",
45
- onClick: l,
46
- disabled: !g || f,
47
- "aria-label": "Previous page",
48
- children: [/* @__PURE__ */ t(r, { className: "size-4" }), "Prev"]
48
+ onClick: u,
49
+ disabled: !v || p,
50
+ "aria-label": h("cosmicintersection.common.prev", "Previous page"),
51
+ children: [/* @__PURE__ */ n(i, { className: "size-4" }), h("cosmicintersection.common.prev", "Prev")]
49
52
  }),
50
- /* @__PURE__ */ n(a, {
53
+ /* @__PURE__ */ r(o, {
51
54
  size: "sm",
52
55
  variant: "outline",
53
- onClick: u,
54
- disabled: !_ || f,
55
- "aria-label": "Next page",
56
- children: ["Next", /* @__PURE__ */ t(i, { className: "size-4" })]
56
+ onClick: d,
57
+ disabled: !y || p,
58
+ "aria-label": h("cosmicintersection.common.next", "Next page"),
59
+ children: [h("cosmicintersection.common.next", "Next"), /* @__PURE__ */ n(a, { className: "size-4" })]
57
60
  })
58
61
  ]
59
62
  })]
60
63
  });
61
64
  }
62
65
  //#endregion
63
- export { c as default, s as usePagination };
66
+ export { l as default, c as usePagination };
64
67
 
65
68
  //# sourceMappingURL=Pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\n\n/**\n * Offset/limit pagination for the CosmicIntersection list surfaces.\n *\n * The Cos* connection resolvers return `{ items, pageInfo { hasMore, cursor } }`\n * with NO total count, so paging is driven by `offset`/`limit` + the boolean\n * `hasMore` rather than a computable page count. `usePagination` owns the window;\n * the page feeds `limit`/`offset` into `PaginationInput`, then renders\n * `<Pagination>` with `hasMore` so Next gates correctly.\n */\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport interface UsePaginationOptions {\n pageSize?: number;\n /** When this changes (a filter/search term), the window resets to page 1. */\n resetKey?: unknown;\n}\n\nexport interface UsePaginationResult {\n limit: number;\n offset: number;\n /** 1-based page index derived from offset/limit. */\n page: number;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\nexport function usePagination(options: UsePaginationOptions = {}): UsePaginationResult {\n const { pageSize = DEFAULT_PAGE_SIZE, resetKey } = options;\n const [offset, setOffset] = useState(0);\n\n // Reset to the first page whenever resetKey changes (React's documented\n // derive-state-during-render pattern — no extra effect/render pass).\n const [prevResetKey, setPrevResetKey] = useState(resetKey);\n if (prevResetKey !== resetKey) {\n setPrevResetKey(resetKey);\n if (offset !== 0) {\n setOffset(0);\n }\n }\n\n return {\n limit: pageSize,\n offset,\n page: Math.floor(offset / Math.max(1, pageSize)) + 1,\n nextPage: () => setOffset((current) => current + pageSize),\n prevPage: () => setOffset((current) => Math.max(0, current - pageSize)),\n reset: () => setOffset(0),\n };\n}\n\nexport interface PaginationProps {\n offset: number;\n limit: number;\n /** Number of rows returned for the current page (`items.length`). */\n loadedCount: number;\n /** Whether the backend reports more rows after this page (`pageInfo.hasMore`). */\n hasMore: boolean;\n onPrev: () => void;\n onNext: () => void;\n /** Plural noun for the range label, e.g. \"datasets\". Defaults to \"items\". */\n itemLabel?: string;\n loading?: boolean;\n className?: string;\n}\n\nexport function Pagination({\n offset,\n limit,\n loadedCount,\n hasMore,\n onPrev,\n onNext,\n itemLabel = 'items',\n loading = false,\n className,\n}: PaginationProps) {\n // Nothing to page through: first page and no more results.\n if (offset === 0 && !hasMore && loadedCount === 0) {\n return null;\n }\n\n const rangeStart = loadedCount === 0 ? 0 : offset + 1;\n const rangeEnd = offset + loadedCount;\n const canPrev = offset > 0;\n const canNext = hasMore;\n const page = Math.floor(offset / Math.max(1, limit)) + 1;\n\n return (\n <div\n className={`flex flex-wrap items-center justify-between gap-3 pt-4 ${className ?? ''}`}\n role=\"navigation\"\n aria-label=\"Pagination\"\n >\n <p className=\"text-xs tabular-nums text-text-secondary\">\n Showing {rangeStart}–{rangeEnd} {itemLabel}\n </p>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs tabular-nums text-text-secondary\">Page {page}</span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onPrev}\n disabled={!canPrev || loading}\n aria-label=\"Previous page\"\n >\n <ChevronLeft className=\"size-4\" />\n Prev\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onNext}\n disabled={!canNext || loading}\n aria-label=\"Next page\"\n >\n Next\n <ChevronRight className=\"size-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\nexport default Pagination;\n"],"mappings":";;;;;AAcA,IAAM,IAAoB;AAkB1B,SAAgB,EAAc,IAAgC,CAAC,GAAwB;CACrF,IAAM,EAAE,cAAW,GAAmB,gBAAa,GAC7C,CAAC,GAAQ,KAAa,EAAS,CAAC,GAIhC,CAAC,GAAc,KAAmB,EAAS,CAAQ;CAQzD,OAPI,MAAiB,MACnB,EAAgB,CAAQ,GACpB,MAAW,KACb,EAAU,CAAC,IAIR;EACL,OAAO;EACP;EACA,MAAM,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAQ,CAAC,IAAI;EACnD,gBAAgB,GAAW,MAAY,IAAU,CAAQ;EACzD,gBAAgB,GAAW,MAAY,KAAK,IAAI,GAAG,IAAU,CAAQ,CAAC;EACtE,aAAa,EAAU,CAAC;CAC1B;AACF;AAiBA,SAAgB,EAAW,EACzB,WACA,UACA,gBACA,YACA,WACA,WACA,eAAY,SACZ,aAAU,IACV,gBACkB;CAElB,IAAI,MAAW,KAAK,CAAC,KAAW,MAAgB,GAC9C,OAAO;CAGT,IAAM,IAAa,MAAgB,IAAI,IAAI,IAAS,GAC9C,IAAW,IAAS,GACpB,IAAU,IAAS,GACnB,IAAU,GACV,IAAO,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAK,CAAC,IAAI;CAEvD,OACE,kBAAC,OAAD;EACE,WAAW,0DAA0D,KAAa;EAClF,MAAK;EACL,cAAW;YAHb,CAKE,kBAAC,KAAD;GAAG,WAAU;aAAb;IAAwD;IAC7C;IAAW;IAAE;IAAS;IAAE;GAChC;MACH,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,QAAD;KAAM,WAAU;eAAhB,CAA2D,SAAM,CAAW;;IAC5E,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAW;eALb,CAOE,kBAAC,GAAD,EAAa,WAAU,SAAU,CAAA,GAAC,MAE5B;;IACR,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAW;eALb,CAMC,QAEC,kBAAC,GAAD,EAAc,WAAU,SAAU,CAAA,CAC5B;;GACL;IACF;;AAET"}
1
+ {"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Offset/limit pagination for the CosmicIntersection list surfaces.\n *\n * The Cos* connection resolvers return `{ items, pageInfo { hasMore, cursor } }`\n * with NO total count, so paging is driven by `offset`/`limit` + the boolean\n * `hasMore` rather than a computable page count. `usePagination` owns the window;\n * the page feeds `limit`/`offset` into `PaginationInput`, then renders\n * `<Pagination>` with `hasMore` so Next gates correctly.\n */\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport interface UsePaginationOptions {\n pageSize?: number;\n /** When this changes (a filter/search term), the window resets to page 1. */\n resetKey?: unknown;\n}\n\nexport interface UsePaginationResult {\n limit: number;\n offset: number;\n /** 1-based page index derived from offset/limit. */\n page: number;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\nexport function usePagination(options: UsePaginationOptions = {}): UsePaginationResult {\n const { pageSize = DEFAULT_PAGE_SIZE, resetKey } = options;\n const [offset, setOffset] = useState(0);\n\n // Reset to the first page whenever resetKey changes (React's documented\n // derive-state-during-render pattern — no extra effect/render pass).\n const [prevResetKey, setPrevResetKey] = useState(resetKey);\n if (prevResetKey !== resetKey) {\n setPrevResetKey(resetKey);\n if (offset !== 0) {\n setOffset(0);\n }\n }\n\n return {\n limit: pageSize,\n offset,\n page: Math.floor(offset / Math.max(1, pageSize)) + 1,\n nextPage: () => setOffset((current) => current + pageSize),\n prevPage: () => setOffset((current) => Math.max(0, current - pageSize)),\n reset: () => setOffset(0),\n };\n}\n\nexport interface PaginationProps {\n offset: number;\n limit: number;\n /** Number of rows returned for the current page (`items.length`). */\n loadedCount: number;\n /** Whether the backend reports more rows after this page (`pageInfo.hasMore`). */\n hasMore: boolean;\n onPrev: () => void;\n onNext: () => void;\n /** Plural noun for the range label, e.g. \"datasets\". Defaults to \"items\". */\n itemLabel?: string;\n loading?: boolean;\n className?: string;\n}\n\nexport function Pagination({\n offset,\n limit,\n loadedCount,\n hasMore,\n onPrev,\n onNext,\n itemLabel = 'items',\n loading = false,\n className,\n}: PaginationProps) {\n const tr = useTr();\n // Nothing to page through: first page and no more results.\n if (offset === 0 && !hasMore && loadedCount === 0) {\n return null;\n }\n\n const rangeStart = loadedCount === 0 ? 0 : offset + 1;\n const rangeEnd = offset + loadedCount;\n const canPrev = offset > 0;\n const canNext = hasMore;\n const page = Math.floor(offset / Math.max(1, limit)) + 1;\n\n return (\n <div\n className={`flex flex-wrap items-center justify-between gap-3 pt-4 ${className ?? ''}`}\n role=\"navigation\"\n aria-label=\"Pagination\"\n >\n <p className=\"text-xs tabular-nums text-text-secondary\">\n {tr('cosmicintersection.common.showingResults', 'Showing {{from}}–{{to}} {{itemLabel}}', { from: rangeStart, to: rangeEnd, itemLabel })}\n </p>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs tabular-nums text-text-secondary\">\n {tr('cosmicintersection.common.page', 'Page')} {page}\n </span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onPrev}\n disabled={!canPrev || loading}\n aria-label={tr('cosmicintersection.common.prev', 'Previous page')}\n >\n <ChevronLeft className=\"size-4\" />\n {tr('cosmicintersection.common.prev', 'Prev')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onNext}\n disabled={!canNext || loading}\n aria-label={tr('cosmicintersection.common.next', 'Next page')}\n >\n {tr('cosmicintersection.common.next', 'Next')}\n <ChevronRight className=\"size-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\nexport default Pagination;\n"],"mappings":";;;;;;AAeA,IAAM,IAAoB;AAkB1B,SAAgB,EAAc,IAAgC,CAAC,GAAwB;CACrF,IAAM,EAAE,cAAW,GAAmB,gBAAa,GAC7C,CAAC,GAAQ,KAAa,EAAS,CAAC,GAIhC,CAAC,GAAc,KAAmB,EAAS,CAAQ;CAQzD,OAPI,MAAiB,MACnB,EAAgB,CAAQ,GACpB,MAAW,KACb,EAAU,CAAC,IAIR;EACL,OAAO;EACP;EACA,MAAM,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAQ,CAAC,IAAI;EACnD,gBAAgB,GAAW,MAAY,IAAU,CAAQ;EACzD,gBAAgB,GAAW,MAAY,KAAK,IAAI,GAAG,IAAU,CAAQ,CAAC;EACtE,aAAa,EAAU,CAAC;CAC1B;AACF;AAiBA,SAAgB,EAAW,EACzB,WACA,UACA,gBACA,YACA,WACA,WACA,eAAY,SACZ,aAAU,IACV,gBACkB;CAClB,IAAM,IAAK,EAAM;CAEjB,IAAI,MAAW,KAAK,CAAC,KAAW,MAAgB,GAC9C,OAAO;CAGT,IAAM,IAAa,MAAgB,IAAI,IAAI,IAAS,GAC9C,IAAW,IAAS,GACpB,IAAU,IAAS,GACnB,IAAU,GACV,IAAO,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAK,CAAC,IAAI;CAEvD,OACE,kBAAC,OAAD;EACE,WAAW,0DAA0D,KAAa;EAClF,MAAK;EACL,cAAW;YAHb,CAKE,kBAAC,KAAD;GAAG,WAAU;aACV,EAAG,4CAA4C,yCAAyC;IAAE,MAAM;IAAY,IAAI;IAAU;GAAU,CAAC;EACrI,CAAA,GACH,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,EAAG,kCAAkC,MAAM;MAAE;MAAE;KAC5C;;IACN,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAY,EAAG,kCAAkC,eAAe;eALlE,CAOE,kBAAC,GAAD,EAAa,WAAU,SAAU,CAAA,GAChC,EAAG,kCAAkC,MAAM,CACtC;;IACR,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAY,EAAG,kCAAkC,WAAW;eAL9D,CAOG,EAAG,kCAAkC,MAAM,GAC5C,kBAAC,GAAD,EAAc,WAAU,SAAU,CAAA,CAC5B;;GACL;IACF;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAiD9E,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAS/E;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAiD9E,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD;AAuBD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAe/E;AAED,eAAe,WAAW,CAAC"}
@@ -1,12 +1,13 @@
1
- import { jsx as e } from "react/jsx-runtime";
1
+ import { useTr as e } from "../../shared/hooks/useTr.js";
2
+ import { jsx as t } from "react/jsx-runtime";
2
3
  //#region src/cosmicintersection/components/StatusBadge.tsx
3
- var t = {
4
+ var n = {
4
5
  success: "bg-status-success-bg-subtle text-status-success-text border-status-success-border",
5
6
  info: "bg-status-info-bg-subtle text-status-info-text border-status-info-border",
6
7
  warning: "bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border",
7
8
  error: "bg-status-error-bg-subtle text-status-error-text border-status-error-border",
8
9
  neutral: "bg-status-neutral-bg-subtle text-status-neutral-text border-status-neutral-border"
9
- }, n = {
10
+ }, r = {
10
11
  AVAILABLE: "success",
11
12
  CONNECTED: "success",
12
13
  SUCCEEDED: "success",
@@ -37,17 +38,37 @@ var t = {
37
38
  DISABLED: "error",
38
39
  ARCHIVED: "neutral"
39
40
  };
40
- function r(e) {
41
+ function i(e) {
41
42
  let t = e.replace(/_/g, " ").toLowerCase();
42
43
  return t.charAt(0).toUpperCase() + t.slice(1);
43
44
  }
44
- function i({ status: i, tone: a, label: o, className: s }) {
45
- return /* @__PURE__ */ e("span", {
46
- className: `inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${t[a ?? n[i] ?? "neutral"]} ${s ?? ""}`,
47
- children: o ?? r(i)
45
+ var a = {
46
+ DRAFT: "cosmicintersection.status.draft",
47
+ ACTIVE: "cosmicintersection.status.active",
48
+ ARCHIVED: "cosmicintersection.status.archived",
49
+ ERROR: "cosmicintersection.status.error",
50
+ PENDING: "cosmicintersection.status.pending",
51
+ RUNNING: "cosmicintersection.status.running",
52
+ SUCCEEDED: "cosmicintersection.status.succeeded",
53
+ COMPLETED: "cosmicintersection.status.succeeded",
54
+ PUBLISHED: "cosmicintersection.status.succeeded",
55
+ FAILED: "cosmicintersection.status.failed",
56
+ CANCELLED: "cosmicintersection.status.cancelled",
57
+ PAUSED: "cosmicintersection.status.paused",
58
+ DISABLED: "cosmicintersection.status.disabled",
59
+ ENABLED: "cosmicintersection.status.enabled",
60
+ PUBLIC: "cosmicintersection.status.public",
61
+ PRIVATE: "cosmicintersection.status.private",
62
+ RESTRICTED: "cosmicintersection.status.restricted"
63
+ };
64
+ function o({ status: o, tone: s, label: c, className: l }) {
65
+ let u = e(), d = s ?? r[o] ?? "neutral", f = i(o), p = c ?? (a[o] ? u(a[o], f) : f);
66
+ return /* @__PURE__ */ t("span", {
67
+ className: `inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${n[d]} ${l ?? ""}`,
68
+ children: p
48
69
  });
49
70
  }
50
71
  //#endregion
51
- export { i as default, r as formatEnumLabel };
72
+ export { o as default, i as formatEnumLabel };
52
73
 
53
74
  //# sourceMappingURL=StatusBadge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"sourcesContent":["/**\n * StatusBadge — maps the Cos* enum values to the semantic status token families.\n *\n * One badge component covers every CosmicIntersection enum (dataset/source/\n * pipeline/run/step/notebook/analysis/release/grant status, plus access level).\n * Colour comes only from the `status-{success,info,warning,error,neutral}`\n * token families — never a raw palette colour — so it renders correctly in every\n * theme.\n */\n\nexport type StatusTone = 'success' | 'info' | 'warning' | 'error' | 'neutral';\n\nconst TONE_CLASS: Record<StatusTone, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text border-status-success-border',\n info: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border',\n error: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n neutral: 'bg-status-neutral-bg-subtle text-status-neutral-text border-status-neutral-border',\n};\n\n// Every Cos* enum value → tone. Values are unique enough across enums that a\n// single map is unambiguous; unknown values fall back to neutral.\nconst STATUS_TONE: Record<string, StatusTone> = {\n // healthy / terminal-good\n AVAILABLE: 'success',\n CONNECTED: 'success',\n SUCCEEDED: 'success',\n COMPLETED: 'success',\n PUBLISHED: 'success',\n ACTIVE: 'success',\n PUBLIC: 'success',\n // in-flight / attention\n INGESTING: 'warning',\n SYNCING: 'warning',\n RUNNING: 'warning',\n DEGRADED: 'warning',\n PAUSED: 'warning',\n DEPRECATED: 'warning',\n EXPIRED: 'warning',\n EMBARGOED: 'warning',\n RESTRICTED: 'warning',\n UNDER_REVIEW: 'warning',\n // queued / neutral-info\n DRAFT: 'info',\n CONFIGURING: 'info',\n QUEUED: 'info',\n PENDING: 'info',\n WORKSPACE: 'info',\n // failed / removed\n ERROR: 'error',\n FAILED: 'error',\n CANCELLED: 'error',\n RETRACTED: 'error',\n REVOKED: 'error',\n DISABLED: 'error',\n // archived / inert\n ARCHIVED: 'neutral',\n};\n\n/** Turn an ENUM_VALUE into a human label, e.g. GROUND_SENSOR -> \"Ground sensor\". */\nexport function formatEnumLabel(value: string): string {\n const lower = value.replace(/_/g, ' ').toLowerCase();\n return lower.charAt(0).toUpperCase() + lower.slice(1);\n}\n\nexport interface StatusBadgeProps {\n status: string;\n /** Override the derived tone (e.g. to force a colour for a domain-specific case). */\n tone?: StatusTone;\n /** Override the rendered label; defaults to a title-cased enum value. */\n label?: string;\n className?: string;\n}\n\nexport function StatusBadge({ status, tone, label, className }: StatusBadgeProps) {\n const resolvedTone: StatusTone = tone ?? STATUS_TONE[status] ?? 'neutral';\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${TONE_CLASS[resolvedTone]} ${className ?? ''}`}\n >\n {label ?? formatEnumLabel(status)}\n </span>\n );\n}\n\nexport default StatusBadge;\n"],"mappings":";;AAYA,IAAM,IAAyC;CAC7C,SAAS;CACT,MAAM;CACN,SAAS;CACT,OAAO;CACP,SAAS;AACX,GAIM,IAA0C;CAE9C,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,QAAQ;CACR,QAAQ;CAER,WAAW;CACX,SAAS;CACT,SAAS;CACT,UAAU;CACV,QAAQ;CACR,YAAY;CACZ,SAAS;CACT,WAAW;CACX,YAAY;CACZ,cAAc;CAEd,OAAO;CACP,aAAa;CACb,QAAQ;CACR,SAAS;CACT,WAAW;CAEX,OAAO;CACP,QAAQ;CACR,WAAW;CACX,WAAW;CACX,SAAS;CACT,UAAU;CAEV,UAAU;AACZ;AAGA,SAAgB,EAAgB,GAAuB;CACrD,IAAM,IAAQ,EAAM,QAAQ,MAAM,GAAG,EAAE,YAAY;CACnD,OAAO,EAAM,OAAO,CAAC,EAAE,YAAY,IAAI,EAAM,MAAM,CAAC;AACtD;AAWA,SAAgB,EAAY,EAAE,WAAQ,SAAM,UAAO,gBAA+B;CAEhF,OACE,kBAAC,QAAD;EACE,WAAW,sFAAsF,EAHpE,KAAQ,EAAY,MAAW,WAG8D,GAAG,KAAa;YAEzI,KAAS,EAAgB,CAAM;CAC5B,CAAA;AAEV"}
1
+ {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"sourcesContent":["import { useTr } from '../../shared/hooks/useTr';\n\n/**\n * StatusBadge — maps the Cos* enum values to the semantic status token families.\n *\n * One badge component covers every CosmicIntersection enum (dataset/source/\n * pipeline/run/step/notebook/analysis/release/grant status, plus access level).\n * Colour comes only from the `status-{success,info,warning,error,neutral}`\n * token families — never a raw palette colour — so it renders correctly in every\n * theme.\n */\n\nexport type StatusTone = 'success' | 'info' | 'warning' | 'error' | 'neutral';\n\nconst TONE_CLASS: Record<StatusTone, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text border-status-success-border',\n info: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border',\n error: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n neutral: 'bg-status-neutral-bg-subtle text-status-neutral-text border-status-neutral-border',\n};\n\n// Every Cos* enum value → tone. Values are unique enough across enums that a\n// single map is unambiguous; unknown values fall back to neutral.\nconst STATUS_TONE: Record<string, StatusTone> = {\n // healthy / terminal-good\n AVAILABLE: 'success',\n CONNECTED: 'success',\n SUCCEEDED: 'success',\n COMPLETED: 'success',\n PUBLISHED: 'success',\n ACTIVE: 'success',\n PUBLIC: 'success',\n // in-flight / attention\n INGESTING: 'warning',\n SYNCING: 'warning',\n RUNNING: 'warning',\n DEGRADED: 'warning',\n PAUSED: 'warning',\n DEPRECATED: 'warning',\n EXPIRED: 'warning',\n EMBARGOED: 'warning',\n RESTRICTED: 'warning',\n UNDER_REVIEW: 'warning',\n // queued / neutral-info\n DRAFT: 'info',\n CONFIGURING: 'info',\n QUEUED: 'info',\n PENDING: 'info',\n WORKSPACE: 'info',\n // failed / removed\n ERROR: 'error',\n FAILED: 'error',\n CANCELLED: 'error',\n RETRACTED: 'error',\n REVOKED: 'error',\n DISABLED: 'error',\n // archived / inert\n ARCHIVED: 'neutral',\n};\n\n/** Turn an ENUM_VALUE into a human label, e.g. GROUND_SENSOR -> \"Ground sensor\". */\nexport function formatEnumLabel(value: string): string {\n const lower = value.replace(/_/g, ' ').toLowerCase();\n return lower.charAt(0).toUpperCase() + lower.slice(1);\n}\n\n/** Known Cos* enum values → translation keys under `cosmicintersection.status`. */\nconst STATUS_LABEL_KEYS: Record<string, string> = {\n DRAFT: 'cosmicintersection.status.draft',\n ACTIVE: 'cosmicintersection.status.active',\n ARCHIVED: 'cosmicintersection.status.archived',\n ERROR: 'cosmicintersection.status.error',\n PENDING: 'cosmicintersection.status.pending',\n RUNNING: 'cosmicintersection.status.running',\n SUCCEEDED: 'cosmicintersection.status.succeeded',\n COMPLETED: 'cosmicintersection.status.succeeded',\n PUBLISHED: 'cosmicintersection.status.succeeded',\n FAILED: 'cosmicintersection.status.failed',\n CANCELLED: 'cosmicintersection.status.cancelled',\n PAUSED: 'cosmicintersection.status.paused',\n DISABLED: 'cosmicintersection.status.disabled',\n ENABLED: 'cosmicintersection.status.enabled',\n PUBLIC: 'cosmicintersection.status.public',\n PRIVATE: 'cosmicintersection.status.private',\n RESTRICTED: 'cosmicintersection.status.restricted',\n};\n\nexport interface StatusBadgeProps {\n status: string;\n /** Override the derived tone (e.g. to force a colour for a domain-specific case). */\n tone?: StatusTone;\n /** Override the rendered label; defaults to a title-cased enum value. */\n label?: string;\n className?: string;\n}\n\nexport function StatusBadge({ status, tone, label, className }: StatusBadgeProps) {\n const tr = useTr();\n const resolvedTone: StatusTone = tone ?? STATUS_TONE[status] ?? 'neutral';\n const fallbackLabel = formatEnumLabel(status);\n const translatedLabel = label ??\n (STATUS_LABEL_KEYS[status]\n ? tr(STATUS_LABEL_KEYS[status], fallbackLabel)\n : fallbackLabel);\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${TONE_CLASS[resolvedTone]} ${className ?? ''}`}\n >\n {translatedLabel}\n </span>\n );\n}\n\nexport default StatusBadge;\n"],"mappings":";;;AAcA,IAAM,IAAyC;CAC7C,SAAS;CACT,MAAM;CACN,SAAS;CACT,OAAO;CACP,SAAS;AACX,GAIM,IAA0C;CAE9C,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,QAAQ;CACR,QAAQ;CAER,WAAW;CACX,SAAS;CACT,SAAS;CACT,UAAU;CACV,QAAQ;CACR,YAAY;CACZ,SAAS;CACT,WAAW;CACX,YAAY;CACZ,cAAc;CAEd,OAAO;CACP,aAAa;CACb,QAAQ;CACR,SAAS;CACT,WAAW;CAEX,OAAO;CACP,QAAQ;CACR,WAAW;CACX,WAAW;CACX,SAAS;CACT,UAAU;CAEV,UAAU;AACZ;AAGA,SAAgB,EAAgB,GAAuB;CACrD,IAAM,IAAQ,EAAM,QAAQ,MAAM,GAAG,EAAE,YAAY;CACnD,OAAO,EAAM,OAAO,CAAC,EAAE,YAAY,IAAI,EAAM,MAAM,CAAC;AACtD;AAGA,IAAM,IAA4C;CAChD,OAAO;CACP,QAAQ;CACR,UAAU;CACV,OAAO;CACP,SAAS;CACT,SAAS;CACT,WAAW;CACX,WAAW;CACX,WAAW;CACX,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;CACR,SAAS;CACT,YAAY;AACd;AAWA,SAAgB,EAAY,EAAE,WAAQ,SAAM,UAAO,gBAA+B;CAChF,IAAM,IAAK,EAAM,GACX,IAA2B,KAAQ,EAAY,MAAW,WAC1D,IAAgB,EAAgB,CAAM,GACtC,IAAkB,MACrB,EAAkB,KACf,EAAG,EAAkB,IAAS,CAAa,IAC3C;CACN,OACE,kBAAC,QAAD;EACE,WAAW,sFAAsF,EAAW,GAAc,GAAG,KAAa;YAEzI;CACG,CAAA;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"StepDAG.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2GD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,kDAkBzD;AAED,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"StepDAG.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoHD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,kDAkBzD;AAED,eAAe,OAAO,CAAC"}
@@ -1,20 +1,24 @@
1
1
  import { formatEnumLabel as e } from "./StatusBadge.js";
2
2
  import { Fragment as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
- import { Bell as i, Database as a, Gauge as o, Shuffle as s, SlidersHorizontal as c, Upload as l } from "lucide-react";
4
+ import { Bell as i, Boxes as a, Calculator as o, Database as s, Gauge as c, Globe2 as l, Grid3x3 as u, Shuffle as d, SlidersHorizontal as f, Upload as p } from "lucide-react";
5
5
  //#region src/cosmicintersection/components/StepDAG.tsx
6
- var u = {
7
- INGEST: { icon: a },
8
- CALIBRATE: { icon: c },
9
- TRANSFORM: { icon: s },
10
- ANALYZE: { icon: o },
11
- EXPORT: { icon: l },
12
- NOTIFY: { icon: i }
13
- }, d = {
6
+ var m = {
7
+ INGEST: { icon: s },
8
+ CALIBRATE: { icon: f },
9
+ TRANSFORM: { icon: d },
10
+ ANALYZE: { icon: c },
11
+ EXPORT: { icon: p },
12
+ NOTIFY: { icon: i },
13
+ RASTER_CALC: { icon: o },
14
+ REPROJECT: { icon: l },
15
+ TILE: { icon: u },
16
+ ZONAL_STATS: { icon: a }
17
+ }, h = { icon: a }, g = {
14
18
  border: "border-border-default",
15
19
  icon: "bg-bg-sunken text-text-secondary",
16
20
  ring: ""
17
- }, f = {
21
+ }, _ = {
18
22
  SUCCEEDED: {
19
23
  border: "border-status-success-border",
20
24
  icon: "bg-status-success-bg-subtle text-status-success-text",
@@ -35,9 +39,9 @@ var u = {
35
39
  icon: "bg-status-info-bg-subtle text-status-info-text",
36
40
  ring: ""
37
41
  },
38
- CANCELLED: d
42
+ CANCELLED: g
39
43
  };
40
- function p() {
44
+ function v() {
41
45
  return /* @__PURE__ */ n("span", {
42
46
  "aria-hidden": "true",
43
47
  className: "flex shrink-0 items-center justify-center text-border-strong",
@@ -58,8 +62,8 @@ function p() {
58
62
  })
59
63
  });
60
64
  }
61
- function m({ step: t, index: i }) {
62
- let a = u[t.kind].icon, o = t.status && f[t.status] || d, s = e(t.kind), c = !!(t.name && t.name.trim() && t.name.trim().toLowerCase() !== s.toLowerCase());
65
+ function y({ step: t, index: i }) {
66
+ let a = (m[t.kind] ?? h).icon, o = t.status && _[t.status] || g, s = e(t.kind), c = !!(t.name && t.name.trim() && t.name.trim().toLowerCase() !== s.toLowerCase());
63
67
  return /* @__PURE__ */ r("div", {
64
68
  role: "listitem",
65
69
  className: `flex w-full items-center gap-3 rounded-card border bg-bg-elevated px-3.5 py-3 md:w-auto md:min-w-[8.5rem] ${o.border} ${o.ring}`,
@@ -87,18 +91,18 @@ function m({ step: t, index: i }) {
87
91
  })]
88
92
  });
89
93
  }
90
- function h({ steps: e, className: i }) {
94
+ function b({ steps: e, className: i }) {
91
95
  return e.length === 0 ? null : /* @__PURE__ */ n("div", {
92
96
  role: "list",
93
97
  "aria-label": "Pipeline step flow",
94
98
  className: `flex flex-col items-stretch gap-2 md:flex-row md:flex-wrap md:items-center ${i ?? ""}`,
95
- children: e.map((i, a) => /* @__PURE__ */ r(t, { children: [/* @__PURE__ */ n(m, {
99
+ children: e.map((i, a) => /* @__PURE__ */ r(t, { children: [/* @__PURE__ */ n(y, {
96
100
  step: i,
97
101
  index: a
98
- }), a < e.length - 1 ? /* @__PURE__ */ n(p, {}) : null] }, `${i.kind}-${a}`))
102
+ }), a < e.length - 1 ? /* @__PURE__ */ n(v, {}) : null] }, `${i.kind}-${a}`))
99
103
  });
100
104
  }
101
105
  //#endregion
102
- export { h as default };
106
+ export { b as default };
103
107
 
104
108
  //# sourceMappingURL=StepDAG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StepDAG.js","names":[],"sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"sourcesContent":["/**\n * StepDAG — a lightweight, dependency-free step-flow visualization.\n *\n * Renders an ordered list of pipeline steps as connected rounded nodes: each\n * node shows a per-kind icon + label (and an optional custom step name), and an\n * optional run status tint. Nodes are joined by custom inline-SVG arrow\n * connectors — horizontal on md+ screens, vertical (stacked) on small screens\n * so it never forces a horizontal-scroll.\n *\n * Colour comes only from the semantic token families (bg-bg-*, text-text-*,\n * border-border-*, status-*) — never a raw palette colour — matching mockups\n * 11 & 14.\n */\nimport { Fragment } from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport { Bell, Database, Gauge, Shuffle, SlidersHorizontal, Upload } from 'lucide-react';\n\nimport type { CosRunStatus, CosStepKind } from '../api/cosmicApi';\nimport { formatEnumLabel } from './StatusBadge';\n\nexport interface StepDAGStep {\n /** Optional human-authored step name; shown under the kind label when it differs. */\n name?: string | null;\n kind: CosStepKind;\n /** Optional run status — tints the node when present. */\n status?: CosRunStatus | null;\n}\n\nexport interface StepDAGProps {\n steps: StepDAGStep[];\n className?: string;\n}\n\nconst KIND_META: Record<CosStepKind, { icon: LucideIcon }> = {\n INGEST: { icon: Database },\n CALIBRATE: { icon: SlidersHorizontal },\n TRANSFORM: { icon: Shuffle },\n ANALYZE: { icon: Gauge },\n EXPORT: { icon: Upload },\n NOTIFY: { icon: Bell },\n};\n\ninterface Accent {\n /** Node border. */\n border: string;\n /** Icon chip background + text. */\n icon: string;\n /** Optional focus ring (used to flag an in-flight node). */\n ring: string;\n}\n\nconst DEFAULT_ACCENT: Accent = {\n border: 'border-border-default',\n icon: 'bg-bg-sunken text-text-secondary',\n ring: '',\n};\n\nconst STATUS_ACCENT: Partial<Record<CosRunStatus, Accent>> = {\n SUCCEEDED: {\n border: 'border-status-success-border',\n icon: 'bg-status-success-bg-subtle text-status-success-text',\n ring: '',\n },\n RUNNING: {\n border: 'border-status-warning-border',\n icon: 'bg-status-warning-bg-subtle text-status-warning-text',\n ring: 'ring-2 ring-status-warning-border',\n },\n FAILED: {\n border: 'border-status-error-border',\n icon: 'bg-status-error-bg-subtle text-status-error-text',\n ring: '',\n },\n QUEUED: {\n border: 'border-status-info-border',\n icon: 'bg-status-info-bg-subtle text-status-info-text',\n ring: '',\n },\n CANCELLED: DEFAULT_ACCENT,\n};\n\n/** Custom inline-SVG connector: a line + arrowhead. Points right on md+, down below. */\nfunction StepConnector() {\n return (\n <span\n aria-hidden=\"true\"\n className=\"flex shrink-0 items-center justify-center text-border-strong\"\n >\n <svg\n viewBox=\"0 0 40 12\"\n className=\"h-4 w-6 rotate-90 md:h-3 md:w-9 md:rotate-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"2\" y1=\"6\" x2=\"33\" y2=\"6\" />\n <path d=\"M28 2 L34 6 L28 10\" />\n </svg>\n </span>\n );\n}\n\nfunction StepNode({ step, index }: { step: StepDAGStep; index: number }) {\n const meta = KIND_META[step.kind];\n const Icon = meta.icon;\n const accent = (step.status && STATUS_ACCENT[step.status]) || DEFAULT_ACCENT;\n const label = formatEnumLabel(step.kind);\n const showName = Boolean(\n step.name && step.name.trim() && step.name.trim().toLowerCase() !== label.toLowerCase()\n );\n\n return (\n <div\n role=\"listitem\"\n className={`flex w-full items-center gap-3 rounded-card border bg-bg-elevated px-3.5 py-3 md:w-auto md:min-w-[8.5rem] ${accent.border} ${accent.ring}`}\n >\n <span\n className={`flex size-9 shrink-0 items-center justify-center rounded-lg ${accent.icon}`}\n >\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n </span>\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"flex items-baseline gap-1.5\">\n <span className=\"text-[0.65rem] font-semibold tabular-nums text-text-secondary\">\n {index + 1}\n </span>\n <span className=\"truncate text-sm font-medium text-text-primary\">{label}</span>\n </span>\n {showName ? (\n <span className=\"truncate text-xs text-text-secondary\">{step.name}</span>\n ) : null}\n </span>\n </div>\n );\n}\n\n/**\n * Horizontal (md+) / vertical (mobile) step-flow diagram. Presentational only —\n * callers decide where the step list comes from (pipeline definition or a run).\n */\nexport function StepDAG({ steps, className }: StepDAGProps) {\n if (steps.length === 0) {\n return null;\n }\n return (\n <div\n role=\"list\"\n aria-label=\"Pipeline step flow\"\n className={`flex flex-col items-stretch gap-2 md:flex-row md:flex-wrap md:items-center ${className ?? ''}`}\n >\n {steps.map((step, index) => (\n <Fragment key={`${step.kind}-${index}`}>\n <StepNode step={step} index={index} />\n {index < steps.length - 1 ? <StepConnector /> : null}\n </Fragment>\n ))}\n </div>\n );\n}\n\nexport default StepDAG;\n"],"mappings":";;;;;AAiCA,IAAM,IAAuD;CAC3D,QAAQ,EAAE,MAAM,EAAS;CACzB,WAAW,EAAE,MAAM,EAAkB;CACrC,WAAW,EAAE,MAAM,EAAQ;CAC3B,SAAS,EAAE,MAAM,EAAM;CACvB,QAAQ,EAAE,MAAM,EAAO;CACvB,QAAQ,EAAE,MAAM,EAAK;AACvB,GAWM,IAAyB;CAC7B,QAAQ;CACR,MAAM;CACN,MAAM;AACR,GAEM,IAAuD;CAC3D,WAAW;EACT,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,WAAW;AACb;AAGA,SAAS,IAAgB;CACvB,OACE,kBAAC,QAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,OAAD;GACE,SAAQ;GACR,WAAU;GACV,MAAK;GACL,QAAO;GACP,aAAa;GACb,eAAc;GACd,gBAAe;aAPjB,CASE,kBAAC,QAAD;IAAM,IAAG;IAAI,IAAG;IAAI,IAAG;IAAK,IAAG;GAAK,CAAA,GACpC,kBAAC,QAAD,EAAM,GAAE,qBAAsB,CAAA,CAC3B;;CACD,CAAA;AAEV;AAEA,SAAS,EAAS,EAAE,SAAM,YAA+C;CAEvE,IAAM,IADO,EAAU,EAAK,MACV,MACZ,IAAU,EAAK,UAAU,EAAc,EAAK,WAAY,GACxD,IAAQ,EAAgB,EAAK,IAAI,GACjC,IAAW,GACf,EAAK,QAAQ,EAAK,KAAK,KAAK,KAAK,EAAK,KAAK,KAAK,EAAE,YAAY,MAAM,EAAM,YAAY;CAGxF,OACE,kBAAC,OAAD;EACE,MAAK;EACL,WAAW,6GAA6G,EAAO,OAAO,GAAG,EAAO;YAFlJ,CAIE,kBAAC,QAAD;GACE,WAAW,+DAA+D,EAAO;aAEjF,kBAAC,GAAD;IAAM,WAAU;IAAS,eAAY;GAAQ,CAAA;EACzC,CAAA,GACN,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,QAAD;KAAM,WAAU;eACb,IAAQ;IACL,CAAA,GACN,kBAAC,QAAD;KAAM,WAAU;eAAkD;IAAY,CAAA,CAC1E;OACL,IACC,kBAAC,QAAD;IAAM,WAAU;cAAwC,EAAK;GAAW,CAAA,IACtE,IACA;IACH;;AAET;AAMA,SAAgB,EAAQ,EAAE,UAAO,gBAA2B;CAI1D,OAHI,EAAM,WAAW,IACZ,OAGP,kBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,WAAW,8EAA8E,KAAa;YAErG,EAAM,KAAK,GAAM,MAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAgB;GAAa;EAAQ,CAAA,GACpC,IAAQ,EAAM,SAAS,IAAI,kBAAC,GAAD,CAAgB,CAAA,IAAI,IACxC,EAAA,GAHK,GAAG,EAAK,KAAK,GAAG,GAGrB,CACX;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"StepDAG.js","names":[],"sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"sourcesContent":["/**\n * StepDAG — a lightweight, dependency-free step-flow visualization.\n *\n * Renders an ordered list of pipeline steps as connected rounded nodes: each\n * node shows a per-kind icon + label (and an optional custom step name), and an\n * optional run status tint. Nodes are joined by custom inline-SVG arrow\n * connectors — horizontal on md+ screens, vertical (stacked) on small screens\n * so it never forces a horizontal-scroll.\n *\n * Colour comes only from the semantic token families (bg-bg-*, text-text-*,\n * border-border-*, status-*) — never a raw palette colour — matching mockups\n * 11 & 14.\n */\nimport { Fragment } from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport {\n Bell,\n Boxes,\n Calculator,\n Database,\n Gauge,\n Globe2,\n Grid3x3,\n Shuffle,\n SlidersHorizontal,\n Upload,\n} from 'lucide-react';\n\nimport type { CosRunStatus, CosStepKind } from '../api/cosmicApi';\nimport { formatEnumLabel } from './StatusBadge';\n\nexport interface StepDAGStep {\n /** Optional human-authored step name; shown under the kind label when it differs. */\n name?: string | null;\n kind: CosStepKind;\n /** Optional run status — tints the node when present. */\n status?: CosRunStatus | null;\n}\n\nexport interface StepDAGProps {\n steps: StepDAGStep[];\n className?: string;\n}\n\nconst KIND_META: Record<CosStepKind, { icon: LucideIcon }> = {\n INGEST: { icon: Database },\n CALIBRATE: { icon: SlidersHorizontal },\n TRANSFORM: { icon: Shuffle },\n ANALYZE: { icon: Gauge },\n EXPORT: { icon: Upload },\n NOTIFY: { icon: Bell },\n // Geospatial kinds (BOFF-4355) — a step can already carry these, so they get\n // a real icon rather than falling through to the generic one.\n RASTER_CALC: { icon: Calculator },\n REPROJECT: { icon: Globe2 },\n TILE: { icon: Grid3x3 },\n ZONAL_STATS: { icon: Boxes },\n};\n\n/** Guards against a kind the subgraph adds before this map catches up. */\nconst FALLBACK_KIND_META: { icon: LucideIcon } = { icon: Boxes };\n\ninterface Accent {\n /** Node border. */\n border: string;\n /** Icon chip background + text. */\n icon: string;\n /** Optional focus ring (used to flag an in-flight node). */\n ring: string;\n}\n\nconst DEFAULT_ACCENT: Accent = {\n border: 'border-border-default',\n icon: 'bg-bg-sunken text-text-secondary',\n ring: '',\n};\n\nconst STATUS_ACCENT: Partial<Record<CosRunStatus, Accent>> = {\n SUCCEEDED: {\n border: 'border-status-success-border',\n icon: 'bg-status-success-bg-subtle text-status-success-text',\n ring: '',\n },\n RUNNING: {\n border: 'border-status-warning-border',\n icon: 'bg-status-warning-bg-subtle text-status-warning-text',\n ring: 'ring-2 ring-status-warning-border',\n },\n FAILED: {\n border: 'border-status-error-border',\n icon: 'bg-status-error-bg-subtle text-status-error-text',\n ring: '',\n },\n QUEUED: {\n border: 'border-status-info-border',\n icon: 'bg-status-info-bg-subtle text-status-info-text',\n ring: '',\n },\n CANCELLED: DEFAULT_ACCENT,\n};\n\n/** Custom inline-SVG connector: a line + arrowhead. Points right on md+, down below. */\nfunction StepConnector() {\n return (\n <span\n aria-hidden=\"true\"\n className=\"flex shrink-0 items-center justify-center text-border-strong\"\n >\n <svg\n viewBox=\"0 0 40 12\"\n className=\"h-4 w-6 rotate-90 md:h-3 md:w-9 md:rotate-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"2\" y1=\"6\" x2=\"33\" y2=\"6\" />\n <path d=\"M28 2 L34 6 L28 10\" />\n </svg>\n </span>\n );\n}\n\nfunction StepNode({ step, index }: { step: StepDAGStep; index: number }) {\n const meta = KIND_META[step.kind] ?? FALLBACK_KIND_META;\n const Icon = meta.icon;\n const accent = (step.status && STATUS_ACCENT[step.status]) || DEFAULT_ACCENT;\n const label = formatEnumLabel(step.kind);\n const showName = Boolean(\n step.name && step.name.trim() && step.name.trim().toLowerCase() !== label.toLowerCase()\n );\n\n return (\n <div\n role=\"listitem\"\n className={`flex w-full items-center gap-3 rounded-card border bg-bg-elevated px-3.5 py-3 md:w-auto md:min-w-[8.5rem] ${accent.border} ${accent.ring}`}\n >\n <span\n className={`flex size-9 shrink-0 items-center justify-center rounded-lg ${accent.icon}`}\n >\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n </span>\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"flex items-baseline gap-1.5\">\n <span className=\"text-[0.65rem] font-semibold tabular-nums text-text-secondary\">\n {index + 1}\n </span>\n <span className=\"truncate text-sm font-medium text-text-primary\">{label}</span>\n </span>\n {showName ? (\n <span className=\"truncate text-xs text-text-secondary\">{step.name}</span>\n ) : null}\n </span>\n </div>\n );\n}\n\n/**\n * Horizontal (md+) / vertical (mobile) step-flow diagram. Presentational only —\n * callers decide where the step list comes from (pipeline definition or a run).\n */\nexport function StepDAG({ steps, className }: StepDAGProps) {\n if (steps.length === 0) {\n return null;\n }\n return (\n <div\n role=\"list\"\n aria-label=\"Pipeline step flow\"\n className={`flex flex-col items-stretch gap-2 md:flex-row md:flex-wrap md:items-center ${className ?? ''}`}\n >\n {steps.map((step, index) => (\n <Fragment key={`${step.kind}-${index}`}>\n <StepNode step={step} index={index} />\n {index < steps.length - 1 ? <StepConnector /> : null}\n </Fragment>\n ))}\n </div>\n );\n}\n\nexport default StepDAG;\n"],"mappings":";;;;;AA4CA,IAAM,IAAuD;CAC3D,QAAQ,EAAE,MAAM,EAAS;CACzB,WAAW,EAAE,MAAM,EAAkB;CACrC,WAAW,EAAE,MAAM,EAAQ;CAC3B,SAAS,EAAE,MAAM,EAAM;CACvB,QAAQ,EAAE,MAAM,EAAO;CACvB,QAAQ,EAAE,MAAM,EAAK;CAGrB,aAAa,EAAE,MAAM,EAAW;CAChC,WAAW,EAAE,MAAM,EAAO;CAC1B,MAAM,EAAE,MAAM,EAAQ;CACtB,aAAa,EAAE,MAAM,EAAM;AAC7B,GAGM,IAA2C,EAAE,MAAM,EAAM,GAWzD,IAAyB;CAC7B,QAAQ;CACR,MAAM;CACN,MAAM;AACR,GAEM,IAAuD;CAC3D,WAAW;EACT,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,SAAS;EACP,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,MAAM;CACR;CACA,WAAW;AACb;AAGA,SAAS,IAAgB;CACvB,OACE,kBAAC,QAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,OAAD;GACE,SAAQ;GACR,WAAU;GACV,MAAK;GACL,QAAO;GACP,aAAa;GACb,eAAc;GACd,gBAAe;aAPjB,CASE,kBAAC,QAAD;IAAM,IAAG;IAAI,IAAG;IAAI,IAAG;IAAK,IAAG;GAAK,CAAA,GACpC,kBAAC,QAAD,EAAM,GAAE,qBAAsB,CAAA,CAC3B;;CACD,CAAA;AAEV;AAEA,SAAS,EAAS,EAAE,SAAM,YAA+C;CAEvE,IAAM,KADO,EAAU,EAAK,SAAS,GACnB,MACZ,IAAU,EAAK,UAAU,EAAc,EAAK,WAAY,GACxD,IAAQ,EAAgB,EAAK,IAAI,GACjC,IAAW,GACf,EAAK,QAAQ,EAAK,KAAK,KAAK,KAAK,EAAK,KAAK,KAAK,EAAE,YAAY,MAAM,EAAM,YAAY;CAGxF,OACE,kBAAC,OAAD;EACE,MAAK;EACL,WAAW,6GAA6G,EAAO,OAAO,GAAG,EAAO;YAFlJ,CAIE,kBAAC,QAAD;GACE,WAAW,+DAA+D,EAAO;aAEjF,kBAAC,GAAD;IAAM,WAAU;IAAS,eAAY;GAAQ,CAAA;EACzC,CAAA,GACN,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,QAAD;KAAM,WAAU;eACb,IAAQ;IACL,CAAA,GACN,kBAAC,QAAD;KAAM,WAAU;eAAkD;IAAY,CAAA,CAC1E;OACL,IACC,kBAAC,QAAD;IAAM,WAAU;cAAwC,EAAK;GAAW,CAAA,IACtE,IACA;IACH;;AAET;AAMA,SAAgB,EAAQ,EAAE,UAAO,gBAA2B;CAI1D,OAHI,EAAM,WAAW,IACZ,OAGP,kBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,WAAW,8EAA8E,KAAa;YAErG,EAAM,KAAK,GAAM,MAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAgB;GAAa;EAAQ,CAAA,GACpC,IAAQ,EAAM,SAAS,IAAI,kBAAC,GAAD,CAAgB,CAAA,IAAI,IACxC,EAAA,GAHK,GAAG,EAAK,KAAK,GAAG,GAGrB,CACX;CACE,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"AccessPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"names":[],"mappings":"AAmFA,MAAM,CAAC,OAAO,UAAU,UAAU,4CA2ZjC"}
1
+ {"version":3,"file":"AccessPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"names":[],"mappings":"AAoFA,MAAM,CAAC,OAAO,UAAU,UAAU,4CA0ejC"}