@xyne/workflow-ui 1.1.0 → 1.3.0

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 (128) hide show
  1. package/dist/components/automations/CreateWorkflowDialog.d.ts +1 -1
  2. package/dist/components/automations/CreateWorkflowDialog.d.ts.map +1 -1
  3. package/dist/components/automations/CreateWorkflowDialog.js +14 -27
  4. package/dist/components/automations/CreateWorkflowDialog.js.map +1 -1
  5. package/dist/components/browser/EntryGrid.d.ts +3 -1
  6. package/dist/components/browser/EntryGrid.d.ts.map +1 -1
  7. package/dist/components/browser/EntryGrid.js +43 -38
  8. package/dist/components/browser/EntryGrid.js.map +1 -1
  9. package/dist/components/browser/EntryList.d.ts +3 -1
  10. package/dist/components/browser/EntryList.d.ts.map +1 -1
  11. package/dist/components/browser/EntryList.js +39 -35
  12. package/dist/components/browser/EntryList.js.map +1 -1
  13. package/dist/components/browser/MoveDialog.d.ts.map +1 -1
  14. package/dist/components/browser/MoveDialog.js +3 -1
  15. package/dist/components/browser/MoveDialog.js.map +1 -1
  16. package/dist/components/browser/NameDialog.d.ts.map +1 -1
  17. package/dist/components/browser/NameDialog.js +5 -2
  18. package/dist/components/browser/NameDialog.js.map +1 -1
  19. package/dist/components/browser/SearchField.js +1 -1
  20. package/dist/components/browser/SearchField.js.map +1 -1
  21. package/dist/components/browser/ViewToggle.js +5 -5
  22. package/dist/components/browser/ViewToggle.js.map +1 -1
  23. package/dist/components/builder/v3/ConditionEditorPanel.js +2 -2
  24. package/dist/components/builder/v3/ConditionEditorPanel.js.map +1 -1
  25. package/dist/components/builder/v3/DeleteStepDialog.js +1 -1
  26. package/dist/components/builder/v3/DeleteStepDialog.js.map +1 -1
  27. package/dist/components/builder/v3/DiscriminatedUnionEditor.js +1 -1
  28. package/dist/components/builder/v3/DiscriminatedUnionEditor.js.map +1 -1
  29. package/dist/components/builder/v3/EnhancedSchemaFormRenderer.js +1 -1
  30. package/dist/components/builder/v3/EnhancedSchemaFormRenderer.js.map +1 -1
  31. package/dist/components/builder/v3/InputSchemaBuilder.js +1 -1
  32. package/dist/components/builder/v3/InputSchemaBuilder.js.map +1 -1
  33. package/dist/components/builder/v3/SaveValidationDialog.js +1 -1
  34. package/dist/components/builder/v3/SaveValidationDialog.js.map +1 -1
  35. package/dist/components/builder/v3/StringArrayInput.js +1 -1
  36. package/dist/components/builder/v3/StringArrayInput.js.map +1 -1
  37. package/dist/components/builder/v3/SummaryDialog.js +1 -1
  38. package/dist/components/builder/v3/SummaryDialog.js.map +1 -1
  39. package/dist/components/builder/v3/SwitchCaseEditor.js +1 -1
  40. package/dist/components/builder/v3/SwitchCaseEditor.js.map +1 -1
  41. package/dist/components/builder/v3/VariableRefInput.js +1 -1
  42. package/dist/components/builder/v3/VariableRefInput.js.map +1 -1
  43. package/dist/components/dashboard/TriggerFormModal.js +1 -1
  44. package/dist/components/dashboard/TriggerFormModal.js.map +1 -1
  45. package/dist/components/execution/ApprovalReviewDisplay.d.ts.map +1 -1
  46. package/dist/components/execution/ApprovalReviewDisplay.js +5 -3
  47. package/dist/components/execution/ApprovalReviewDisplay.js.map +1 -1
  48. package/dist/components/execution/ApprovalsView.d.ts.map +1 -1
  49. package/dist/components/execution/ApprovalsView.js +144 -23
  50. package/dist/components/execution/ApprovalsView.js.map +1 -1
  51. package/dist/components/execution/PauseFormRenderer.d.ts.map +1 -1
  52. package/dist/components/execution/PauseFormRenderer.js +3 -2
  53. package/dist/components/execution/PauseFormRenderer.js.map +1 -1
  54. package/dist/components/execution/PauseInteractionPanel.js +1 -1
  55. package/dist/components/execution/PauseInteractionPanel.js.map +1 -1
  56. package/dist/components/execution/RerunDialog.js +1 -1
  57. package/dist/components/execution/RerunDialog.js.map +1 -1
  58. package/dist/components/execution/SidePanelShell.d.ts +3 -1
  59. package/dist/components/execution/SidePanelShell.d.ts.map +1 -1
  60. package/dist/components/execution/SidePanelShell.js +2 -2
  61. package/dist/components/execution/SidePanelShell.js.map +1 -1
  62. package/dist/components/execution/ValueEditor.js +21 -21
  63. package/dist/components/execution/ValueEditor.js.map +1 -1
  64. package/dist/components/execution/origin/OriginTrace.d.ts +6 -3
  65. package/dist/components/execution/origin/OriginTrace.d.ts.map +1 -1
  66. package/dist/components/execution/origin/OriginTrace.js +53 -12
  67. package/dist/components/execution/origin/OriginTrace.js.map +1 -1
  68. package/dist/components/index.d.ts +2 -0
  69. package/dist/components/index.d.ts.map +1 -1
  70. package/dist/components/index.js +1 -0
  71. package/dist/components/index.js.map +1 -1
  72. package/dist/components/runs/RunsFilters.js +1 -1
  73. package/dist/components/runs/RunsFilters.js.map +1 -1
  74. package/dist/components/runs/RunsTable.d.ts +3 -1
  75. package/dist/components/runs/RunsTable.d.ts.map +1 -1
  76. package/dist/components/runs/RunsTable.js +18 -28
  77. package/dist/components/runs/RunsTable.js.map +1 -1
  78. package/dist/components/runs/RunsView.d.ts.map +1 -1
  79. package/dist/components/runs/RunsView.js +51 -3
  80. package/dist/components/runs/RunsView.js.map +1 -1
  81. package/dist/components/schema-form/AttachmentFieldInput.js +8 -8
  82. package/dist/components/schema-form/AttachmentFieldInput.js.map +1 -1
  83. package/dist/components/schema-form/SchemaFormRenderer.js +4 -4
  84. package/dist/components/schema-form/SchemaFormRenderer.js.map +1 -1
  85. package/dist/components/shared/AttachmentCard.d.ts.map +1 -1
  86. package/dist/components/shared/AttachmentCard.js +8 -1
  87. package/dist/components/shared/AttachmentCard.js.map +1 -1
  88. package/dist/components/shared/ChatPanel.d.ts +3 -1
  89. package/dist/components/shared/ChatPanel.d.ts.map +1 -1
  90. package/dist/components/shared/ChatPanel.js +12 -12
  91. package/dist/components/shared/ChatPanel.js.map +1 -1
  92. package/dist/components/shared/DocPreviewContext.d.ts +10 -0
  93. package/dist/components/shared/DocPreviewContext.d.ts.map +1 -0
  94. package/dist/components/shared/DocPreviewContext.js +12 -0
  95. package/dist/components/shared/DocPreviewContext.js.map +1 -0
  96. package/dist/components/shared/JsonView.d.ts +13 -0
  97. package/dist/components/shared/JsonView.d.ts.map +1 -0
  98. package/dist/components/shared/JsonView.js +59 -0
  99. package/dist/components/shared/JsonView.js.map +1 -0
  100. package/dist/components/shared/MarkdownEditor.d.ts.map +1 -1
  101. package/dist/components/shared/MarkdownEditor.js +10 -5
  102. package/dist/components/shared/MarkdownEditor.js.map +1 -1
  103. package/dist/components/shared/MarkdownView.d.ts +1 -1
  104. package/dist/components/shared/MarkdownView.d.ts.map +1 -1
  105. package/dist/components/shared/MarkdownView.js +33 -20
  106. package/dist/components/shared/MarkdownView.js.map +1 -1
  107. package/dist/components/shared/Select.d.ts +20 -0
  108. package/dist/components/shared/Select.d.ts.map +1 -0
  109. package/dist/components/shared/Select.js +50 -0
  110. package/dist/components/shared/Select.js.map +1 -0
  111. package/dist/components/shared/Toolbar.d.ts +17 -0
  112. package/dist/components/shared/Toolbar.d.ts.map +1 -0
  113. package/dist/components/shared/Toolbar.js +26 -0
  114. package/dist/components/shared/Toolbar.js.map +1 -0
  115. package/dist/components/workflows/WorkflowBrowser.d.ts +4 -1
  116. package/dist/components/workflows/WorkflowBrowser.d.ts.map +1 -1
  117. package/dist/components/workflows/WorkflowBrowser.js +123 -30
  118. package/dist/components/workflows/WorkflowBrowser.js.map +1 -1
  119. package/dist/components/workflows/WorkflowHome.d.ts +22 -0
  120. package/dist/components/workflows/WorkflowHome.d.ts.map +1 -0
  121. package/dist/components/workflows/WorkflowHome.js +33 -0
  122. package/dist/components/workflows/WorkflowHome.js.map +1 -0
  123. package/dist/index.d.ts +2 -2
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +1 -1
  126. package/dist/index.js.map +1 -1
  127. package/dist/styles.css +1 -1
  128. package/package.json +2 -2
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import ReactMarkdown from 'react-markdown';
3
3
  import remarkGfm from 'remark-gfm';
4
4
  import { cn } from './cn.js';
5
+ import { JsonView, tryParseJson } from './JsonView.js';
5
6
  /**
6
7
  * Renders markdown (GitHub-flavored) to safe React nodes — no
7
8
  * `dangerouslySetInnerHTML`. Used for the workflow summary in both the builder
@@ -9,27 +10,39 @@ import { cn } from './cn.js';
9
10
  * it works without a Tailwind typography plugin.
10
11
  */
11
12
  export function MarkdownView({ children, className, bare }) {
12
- return (_jsx("div", { className: cn('wui-markdown min-w-0 max-w-full', !bare && 'text-[13px] leading-relaxed text-slate-700', className), children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: {
13
- h1: ({ node: _n, ...p }) => _jsx("h1", { className: "mb-2 mt-3 text-base font-bold text-slate-900 first:mt-0", ...p }),
14
- h2: ({ node: _n, ...p }) => _jsx("h2", { className: "mb-1.5 mt-3 text-sm font-bold text-slate-900 first:mt-0", ...p }),
15
- h3: ({ node: _n, ...p }) => _jsx("h3", { className: "mb-1 mt-2.5 text-[13px] font-bold text-slate-800 first:mt-0", ...p }),
16
- p: ({ node: _n, ...p }) => _jsx("p", { className: "my-2 first:mt-0 last:mb-0", ...p }),
17
- ul: ({ node: _n, ...p }) => _jsx("ul", { className: "my-2 list-disc space-y-0.5 pl-5", ...p }),
18
- ol: ({ node: _n, ...p }) => _jsx("ol", { className: "my-2 list-decimal space-y-0.5 pl-5", ...p }),
19
- li: ({ node: _n, ...p }) => _jsx("li", { className: "pl-0.5", ...p }),
20
- a: ({ node: _n, ...p }) => _jsx("a", { className: "text-indigo-600 underline underline-offset-2 hover:text-indigo-700", target: "_blank", rel: "noreferrer noopener", ...p }),
21
- code: ({ node: _n, className: c, ...p }) => c?.includes('language-') ? (_jsx("code", { className: cn('font-mono text-[12px]', c), ...p })) : (_jsx("code", { className: "rounded bg-slate-100 px-1 py-0.5 font-mono text-[12px] text-slate-800", ...p })),
22
- // Block code: dark <pre> owns the styling and neutralizes the inline-code
13
+ return (_jsx("div", { className: cn('wui-markdown min-w-0 max-w-full', !bare && 'text-[13px] leading-relaxed text-[var(--wui-fg)]', className), children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: {
14
+ h1: ({ node: _n, ...p }) => _jsx("h1", { className: "mb-2.5 mt-4 border-b border-[var(--wui-border)] pb-1.5 text-[15px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
15
+ h2: ({ node: _n, ...p }) => _jsx("h2", { className: "mb-2 mt-4 border-b border-[var(--wui-border)] pb-1 text-[13.5px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
16
+ h3: ({ node: _n, ...p }) => _jsx("h3", { className: "mb-1.5 mt-3 text-[12.5px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
17
+ p: ({ node: _n, ...p }) => _jsx("p", { className: "my-2 leading-relaxed first:mt-0 last:mb-0", ...p }),
18
+ ul: ({ node: _n, ...p }) => _jsx("ul", { className: "my-2 list-disc space-y-1 pl-5 marker:text-[var(--wui-fg-muted)]", ...p }),
19
+ ol: ({ node: _n, ...p }) => _jsx("ol", { className: "my-2 list-decimal space-y-1 pl-5 marker:text-[var(--wui-fg-muted)]", ...p }),
20
+ li: ({ node: _n, ...p }) => _jsx("li", { className: "pl-0.5 leading-relaxed", ...p }),
21
+ a: ({ node: _n, ...p }) => _jsx("a", { className: "font-medium text-[var(--wui-primary)] underline underline-offset-2 hover:text-[var(--wui-primary-hover)]", target: "_blank", rel: "noreferrer noopener", ...p }),
22
+ code: ({ node: _n, className: c, ...p }) => c?.includes('language-') ? (_jsx("code", { className: cn('font-mono text-[12px]', c), ...p })) : (_jsx("code", { className: "rounded-[4px] border border-[var(--wui-border)] bg-[var(--wui-bg-muted)] px-1.5 py-0.5 font-mono text-[0.85em] text-[var(--wui-fg)]", ...p })),
23
+ // Block code: the <pre> owns the styling and neutralizes the inline-code
23
24
  // chrome on its <code> child (an indented/no-language block otherwise gets
24
- // the light inline-code background, leaving white boxes inside the block).
25
- pre: ({ node: _n, ...p }) => _jsx("pre", { className: "my-2 overflow-x-auto rounded-md bg-slate-900 p-3 text-[12px] text-slate-100 [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:ring-0", ...p }),
26
- blockquote: ({ node: _n, ...p }) => _jsx("blockquote", { className: "my-2 border-l-2 border-slate-300 pl-3 italic text-slate-500", ...p }),
27
- // Wrap tables in a horizontal-scroll box so a wide (many-column) table
28
- // scrolls within its container instead of overflowing the panel.
29
- table: ({ node: _n, ...p }) => (_jsx("div", { className: "my-2 max-w-full overflow-x-auto", children: _jsx("table", { className: "w-full border-collapse text-[12px]", ...p }) })),
30
- th: ({ node: _n, ...p }) => _jsx("th", { className: "border border-slate-200 bg-slate-50 px-2 py-1 text-left font-semibold", ...p }),
31
- td: ({ node: _n, ...p }) => _jsx("td", { className: "border border-slate-200 px-2 py-1", ...p }),
32
- hr: ({ node: _n, ...p }) => _jsx("hr", { className: "my-3 border-slate-200", ...p }),
25
+ // the inline-code background, leaving boxes inside the block).
26
+ pre: ({ node: _n, children, ...p }) => {
27
+ // A fenced block whose body is JSON renders as a collapsible tree.
28
+ const child = Array.isArray(children) ? children[0] : children;
29
+ const raw = child && typeof child === 'object' && 'props' in child
30
+ ? child.props?.children
31
+ : undefined;
32
+ const text = typeof raw === 'string' ? raw : Array.isArray(raw) ? raw.map(String).join('') : '';
33
+ const json = tryParseJson(text);
34
+ if (json !== undefined) {
35
+ return (_jsx("div", { className: "my-2.5 overflow-x-auto rounded-lg border border-[var(--wui-border)] bg-[var(--wui-bg-muted)] p-3", children: _jsx(JsonView, { data: json }) }));
36
+ }
37
+ return _jsx("pre", { className: "my-2.5 overflow-x-auto rounded-lg border border-[var(--wui-border)] bg-[var(--wui-bg-muted)] p-3.5 text-[12px] leading-relaxed text-[var(--wui-fg)] [&_code]:border-0 [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:ring-0", ...p, children: children });
38
+ },
39
+ blockquote: ({ node: _n, ...p }) => _jsx("blockquote", { className: "my-2.5 border-l-[3px] border-[var(--wui-border-strong)] pl-3.5 text-[var(--wui-fg-muted)]", ...p }),
40
+ // GitHub-style tables: rounded bordered frame, header fill, zebra rows,
41
+ // and cell separators — scrolls horizontally inside the frame when wide.
42
+ table: ({ node: _n, ...p }) => (_jsx("div", { className: "my-3 max-w-full overflow-hidden rounded-lg border border-[var(--wui-border)]", children: _jsx("div", { className: "max-w-full overflow-x-auto", children: _jsx("table", { className: "w-full border-collapse text-[12px] [&_tbody_tr:nth-child(2n)]:bg-[color-mix(in_srgb,var(--wui-fg)_4%,transparent)] [&_tbody_tr:last-child_td]:border-b-0", ...p }) }) })),
43
+ th: ({ node: _n, ...p }) => _jsx("th", { className: "border-b border-[var(--wui-border)] bg-[var(--wui-bg-muted)] px-3 py-2 text-left font-semibold text-[var(--wui-fg)] [&:not(:last-child)]:border-r [&:not(:last-child)]:border-[var(--wui-border)]", ...p }),
44
+ td: ({ node: _n, ...p }) => _jsx("td", { className: "border-b border-[var(--wui-border)] px-3 py-2 align-top text-[var(--wui-fg)] [&:not(:last-child)]:border-r [&:not(:last-child)]:border-[var(--wui-border)]", ...p }),
45
+ hr: ({ node: _n, ...p }) => _jsx("hr", { className: "my-4 border-t border-[var(--wui-border)]", ...p }),
33
46
  }, children: children }) }));
34
47
  }
35
48
  //# sourceMappingURL=MarkdownView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SelectOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ /**
6
+ * Fully custom dropdown — a styled trigger + a themed option menu. Replaces the
7
+ * native <select> so the open popup is styled too (the native popup can't be).
8
+ * Closes on outside-click / Escape; the chosen option is highlighted in brand.
9
+ */
10
+ export declare function Select({ value, options, onChange, placeholder, disabled, compact, className, ariaLabel, }: {
11
+ value: string;
12
+ options: SelectOption[];
13
+ onChange: (value: string) => void;
14
+ placeholder?: string | undefined;
15
+ disabled?: boolean | undefined;
16
+ compact?: boolean | undefined;
17
+ className?: string | undefined;
18
+ ariaLabel?: string | undefined;
19
+ }): import("react").JSX.Element;
20
+ //# sourceMappingURL=Select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/shared/Select.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,+BA0GA"}
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { cn } from './cn.js';
4
+ /**
5
+ * Fully custom dropdown — a styled trigger + a themed option menu. Replaces the
6
+ * native <select> so the open popup is styled too (the native popup can't be).
7
+ * Closes on outside-click / Escape; the chosen option is highlighted in brand.
8
+ */
9
+ export function Select({ value, options, onChange, placeholder, disabled, compact, className, ariaLabel, }) {
10
+ const [open, setOpen] = useState(false);
11
+ const [openUp, setOpenUp] = useState(false);
12
+ const ref = useRef(null);
13
+ const current = options.find((o) => o.value === value);
14
+ const toggle = () => {
15
+ if (!open) {
16
+ // Flip the menu above the trigger when there isn't room below (e.g. the
17
+ // last field, where the menu would otherwise clip under the action bar).
18
+ const rect = ref.current?.getBoundingClientRect();
19
+ setOpenUp(!!rect && rect.bottom > window.innerHeight - 290);
20
+ }
21
+ setOpen((o) => !o);
22
+ };
23
+ useEffect(() => {
24
+ if (!open)
25
+ return undefined;
26
+ const onDoc = (e) => {
27
+ if (ref.current && !ref.current.contains(e.target))
28
+ setOpen(false);
29
+ };
30
+ const onKey = (e) => {
31
+ if (e.key === 'Escape')
32
+ setOpen(false);
33
+ };
34
+ document.addEventListener('mousedown', onDoc);
35
+ document.addEventListener('keydown', onKey);
36
+ return () => {
37
+ document.removeEventListener('mousedown', onDoc);
38
+ document.removeEventListener('keydown', onKey);
39
+ };
40
+ }, [open]);
41
+ return (_jsxs("div", { ref: ref, className: cn('relative', className), children: [_jsxs("button", { type: "button", disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": open, "aria-label": ariaLabel, onClick: toggle, className: cn('flex w-full items-center justify-between gap-1.5 rounded-[var(--wui-radius-sm)] border bg-[var(--wui-bg)] text-left text-[var(--wui-fg)] transition-colors', compact ? 'h-7 px-1.5 text-[11px]' : 'px-2.5 py-1.5 text-sm', 'disabled:cursor-not-allowed disabled:opacity-50', open
42
+ ? 'border-[var(--wui-primary)] ring-1 ring-[var(--wui-primary)]'
43
+ : 'border-[var(--wui-border)] hover:border-[var(--wui-border-strong)]'), children: [_jsx("span", { className: cn('min-w-0 truncate', !current && 'text-[var(--wui-fg-muted)]'), children: current?.label ?? placeholder ?? 'Select…' }), _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", className: cn('shrink-0 text-[var(--wui-fg-muted)] transition-transform', compact ? 'h-3 w-3' : 'h-3.5 w-3.5', open && 'rotate-180'), children: _jsx("polyline", { points: "6 9 12 15 18 9" }) })] }), open && (_jsx("div", { role: "listbox", className: cn('absolute left-0 z-50 max-h-56 w-max min-w-full max-w-[280px] overflow-y-auto rounded-[var(--wui-radius-sm)] border border-[var(--wui-border)] bg-[color-mix(in_srgb,var(--wui-bg-muted)_96%,var(--wui-fg)_4%)] py-1 shadow-lg', openUp ? 'bottom-full mb-1' : 'top-full mt-1'), children: options.length === 0 ? (_jsx("div", { className: "px-2.5 py-1.5 text-[13px] text-[var(--wui-fg-muted)]", children: "No options" })) : (options.map((opt) => {
44
+ const selected = opt.value === value;
45
+ return (_jsxs("button", { type: "button", role: "option", "aria-selected": selected, onClick: () => { onChange(opt.value); setOpen(false); }, className: cn('flex w-full items-center justify-between gap-2 whitespace-nowrap px-2.5 py-1.5 text-left text-[13px] transition-colors', selected
46
+ ? 'bg-[color-mix(in_srgb,var(--wui-primary)_12%,transparent)] font-medium text-[var(--wui-primary)]'
47
+ : 'text-[var(--wui-fg)] hover:bg-[color-mix(in_srgb,var(--wui-fg)_6%,transparent)]'), children: [_jsx("span", { className: "min-w-0 truncate", children: opt.label }), selected && (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", className: "h-3.5 w-3.5 shrink-0", children: _jsx("polyline", { points: "20 6 9 17 4 12" }) }))] }, opt.value));
48
+ })) }))] }));
49
+ }
50
+ //# sourceMappingURL=Select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.js","sourceRoot":"","sources":["../../../src/components/shared/Select.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ButtonHTMLAttributes, ReactNode, SelectHTMLAttributes } from 'react';
2
+ /**
3
+ * Shared section toolbar — one consistent bar across the workflow tabs
4
+ * (Workflows / Executions / Approvals) so every tab reads as the same surface.
5
+ * `left` holds context (breadcrumb / label); `right` holds controls.
6
+ */
7
+ export declare function SectionToolbar({ left, right, className, }: {
8
+ left?: ReactNode;
9
+ right?: ReactNode;
10
+ className?: string | undefined;
11
+ }): import("react").JSX.Element;
12
+ /** Base styling shared by every compact toolbar control (h-8, one radius). */
13
+ export declare const toolbarControl: string;
14
+ export declare function ToolbarButton({ className, ...props }: ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
15
+ export declare function ToolbarIconButton({ className, ...props }: ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
16
+ export declare function ToolbarSelect({ className, children, ...props }: SelectHTMLAttributes<HTMLSelectElement>): import("react").JSX.Element;
17
+ //# sourceMappingURL=Toolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/shared/Toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAGnF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAK,EACL,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,+BAaA;AAED,8EAA8E;AAC9E,eAAO,MAAM,cAAc,QAKwB,CAAC;AAEpD,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,+BAEzC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,+BAEzC;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,+BAMzC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from './cn.js';
3
+ /**
4
+ * Shared section toolbar — one consistent bar across the workflow tabs
5
+ * (Workflows / Executions / Approvals) so every tab reads as the same surface.
6
+ * `left` holds context (breadcrumb / label); `right` holds controls.
7
+ */
8
+ export function SectionToolbar({ left, right, className, }) {
9
+ return (_jsxs("div", { className: cn('flex h-12 shrink-0 flex-wrap items-center justify-between gap-x-3 gap-y-2 px-5', 'border-b border-[var(--wui-border)]', className), children: [_jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: left }), right ? _jsx("div", { className: "flex items-center gap-1.5", children: right }) : null] }));
10
+ }
11
+ /** Base styling shared by every compact toolbar control (h-8, one radius). */
12
+ export const toolbarControl = 'inline-flex h-7 items-center justify-center gap-1 rounded-[var(--wui-control-radius)] border border-[var(--wui-control-border)] ' +
13
+ 'bg-[var(--wui-control-bg)] text-[12px] font-medium text-[var(--wui-control-fg)] transition-colors ' +
14
+ 'hover:bg-[var(--wui-control-bg-hover)] ' +
15
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--wui-primary)_30%,transparent)] ' +
16
+ 'disabled:cursor-not-allowed disabled:opacity-50';
17
+ export function ToolbarButton({ className, ...props }) {
18
+ return _jsx("button", { type: "button", className: cn(toolbarControl, 'px-2', className), ...props });
19
+ }
20
+ export function ToolbarIconButton({ className, ...props }) {
21
+ return _jsx("button", { type: "button", className: cn(toolbarControl, 'w-7', className), ...props });
22
+ }
23
+ export function ToolbarSelect({ className, children, ...props }) {
24
+ return (_jsx("select", { className: cn(toolbarControl, 'cursor-pointer px-2 pr-7', className), ...props, children: children }));
25
+ }
26
+ //# sourceMappingURL=Toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.js","sourceRoot":"","sources":["../../../src/components/shared/Toolbar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAK,EACL,SAAS,GAKV;IACC,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,gFAAgF,EAChF,qCAAqC,EACrC,SAAS,CACV,aAED,cAAK,SAAS,EAAC,wCAAwC,YAAE,IAAI,GAAO,EACnE,KAAK,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,2BAA2B,YAAE,KAAK,GAAO,CAAC,CAAC,CAAC,IAAI,IACpE,CACP,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GACzB,kIAAkI;IAClI,oGAAoG;IACpG,yCAAyC;IACzC,6HAA6H;IAC7H,iDAAiD,CAAC;AAEpD,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACgC;IACxC,OAAO,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,EACT,GAAG,KAAK,EACgC;IACxC,OAAO,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACgC;IACxC,OAAO,CACL,iBAAQ,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,0BAA0B,EAAE,SAAS,CAAC,KAAM,KAAK,YACpF,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
@@ -8,7 +8,10 @@ export interface WorkflowBrowserProps {
8
8
  path: FolderCrumb[];
9
9
  onPathChange: (path: FolderCrumb[]) => void;
10
10
  onToast?: (kind: 'success' | 'error', message: string) => void;
11
+ /** Suppress the embedded "waiting for approval" banner + inline approvals view
12
+ * (used when approvals live in a sibling tab, e.g. WorkflowHome). */
13
+ hideApprovals?: boolean;
11
14
  className?: string;
12
15
  }
13
- export declare function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb, onPathChange, onToast, className, }: WorkflowBrowserProps): import("react").JSX.Element;
16
+ export declare function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb, onPathChange, onToast, hideApprovals, className, }: WorkflowBrowserProps): import("react").JSX.Element;
14
17
  //# sourceMappingURL=WorkflowBrowser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowBrowser.d.ts","sourceRoot":"","sources":["../../../src/components/workflows/WorkflowBrowser.tsx"],"names":[],"mappings":"AAiGA,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEzD,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IACpE,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,EAC9B,gBAAgB,EAChB,SAAS,EACT,IAAI,EAAE,UAAU,EAChB,YAAY,EACZ,OAAO,EACP,SAAS,GACV,EAAE,oBAAoB,+BAikBtB"}
1
+ {"version":3,"file":"WorkflowBrowser.d.ts","sourceRoot":"","sources":["../../../src/components/workflows/WorkflowBrowser.tsx"],"names":[],"mappings":"AAuKA,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEzD,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IACpE,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D;0EACsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,EAC9B,gBAAgB,EAChB,SAAS,EACT,IAAI,EAAE,UAAU,EAChB,YAAY,EACZ,OAAO,EACP,aAAqB,EACrB,SAAS,GACV,EAAE,oBAAoB,+BAumBtB"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useRef, useState } from 'react';
3
- import { AlertCircle, ArrowLeft, FolderPlus, Plus, RefreshCw, Workflow } from 'lucide-react';
3
+ import { AlertCircle, ArrowLeft, Clock, FolderPlus, MousePointerClick, Plus, RefreshCw, Webhook, Workflow, Zap } from 'lucide-react';
4
4
  import { useWorkflowClient } from '../../hooks/use-workflow-client.js';
5
5
  import { useApprovalCount } from '../../hooks/use-approval-count.js';
6
6
  import { CreateWorkflowDialog } from '../automations/CreateWorkflowDialog.js';
@@ -11,6 +11,7 @@ import { FolderCard } from '../browser/FolderCard.js';
11
11
  import { SearchField } from '../browser/SearchField.js';
12
12
  import { ViewToggle } from '../browser/ViewToggle.js';
13
13
  import { NameDialog } from '../browser/NameDialog.js';
14
+ import { ToolbarButton, ToolbarIconButton } from '../shared/Toolbar.js';
14
15
  import { MoveDialog } from '../browser/MoveDialog.js';
15
16
  import { TriggerFormModal } from '../dashboard/TriggerFormModal.js';
16
17
  import { TagInput } from '../shared/TagInput.js';
@@ -18,16 +19,67 @@ import { TagFilter } from '../shared/TagFilter.js';
18
19
  import { cn } from '../shared/cn.js';
19
20
  // ─── Column definitions ───────────────────────────────────────────────────────
20
21
  const WF_COLUMNS = [
21
- { key: 'status', header: 'Status', width: '100px' },
22
- { key: 'steps', header: 'Steps', width: '80px' },
23
- { key: 'trigger', header: 'Trigger', width: '140px' },
22
+ { key: 'status', header: 'Status', width: '104px', render: (e) => _jsx(WorkflowStatusPill, { status: e.columns?.['status'] }) },
23
+ { key: 'steps', header: 'Steps', width: '60px' },
24
+ { key: 'trigger', header: 'Trigger', width: '116px', render: (e) => _jsx(TriggerCell, { type: e.columns?.['trigger'] }) },
25
+ { key: 'lastRun', header: 'Last run', width: '116px', render: (e) => _jsx(LastRunCell, { status: e.columns?.['lastRunStatus'], at: e.columns?.['lastRunAt'] }) },
24
26
  ];
27
+ function timeAgo(ms) {
28
+ const sec = Math.floor(Math.max(0, Date.now() - ms) / 1000);
29
+ if (sec < 60)
30
+ return `${String(sec)}s ago`;
31
+ const min = Math.floor(sec / 60);
32
+ if (min < 60)
33
+ return `${String(min)}m ago`;
34
+ const hr = Math.floor(min / 60);
35
+ if (hr < 24)
36
+ return `${String(hr)}h ago`;
37
+ return `${String(Math.floor(hr / 24))}d ago`;
38
+ }
39
+ function LastRunCell({ status, at }) {
40
+ if (!status || !at) {
41
+ return _jsx("span", { className: "text-[12px] text-[var(--wui-fg-muted)]", children: "Never run" });
42
+ }
43
+ const s = status.toUpperCase();
44
+ const dot = s === 'COMPLETED' ? 'bg-[var(--wui-status-completed)]'
45
+ : s === 'FAILED' ? 'bg-[var(--wui-status-failed)]'
46
+ : s === 'RUNNING' ? 'bg-[var(--wui-status-running)]'
47
+ : s === 'EXTERNAL_WAIT' ? 'bg-[var(--wui-status-paused)]'
48
+ : 'bg-[var(--wui-fg-muted)]';
49
+ return (_jsxs("span", { className: "inline-flex items-center gap-1.5 text-[12px] text-[var(--wui-fg-muted)]", title: new Date(Number(at)).toLocaleString(), children: [_jsx("span", { className: cn('h-1.5 w-1.5 shrink-0 rounded-full', dot) }), timeAgo(Number(at))] }));
50
+ }
51
+ function WorkflowStatusPill({ status }) {
52
+ const s = (status ?? '').toUpperCase();
53
+ const styles = {
54
+ ACTIVE: 'text-[var(--wui-status-completed)] bg-[color-mix(in_srgb,var(--wui-status-completed)_14%,transparent)]',
55
+ PENDING_APPROVAL: 'text-[var(--wui-status-paused)] bg-[color-mix(in_srgb,var(--wui-status-paused)_14%,transparent)]',
56
+ DRAFT: 'text-[var(--wui-fg-muted)] bg-[var(--wui-bg-muted)]',
57
+ };
58
+ const cls = styles[s] ?? 'text-[var(--wui-fg-muted)] bg-[var(--wui-bg-muted)]';
59
+ const label = s ? s.charAt(0) + s.slice(1).toLowerCase().replace(/_/g, ' ') : '—';
60
+ return (_jsx("span", { className: cn('inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-medium', cls), children: label }));
61
+ }
62
+ function TriggerCell({ type }) {
63
+ const t = (type ?? '').toUpperCase();
64
+ const map = {
65
+ MANUAL: { Icon: MousePointerClick, label: 'Manual' },
66
+ WEBHOOK: { Icon: Webhook, label: 'Webhook' },
67
+ CRON: { Icon: Clock, label: 'Schedule' },
68
+ SCHEDULE: { Icon: Clock, label: 'Schedule' },
69
+ EVENT: { Icon: Zap, label: 'Event' },
70
+ };
71
+ const m = map[t];
72
+ if (!m)
73
+ return _jsx("span", { className: "text-[12px] text-[var(--wui-fg-muted)]", children: type || '—' });
74
+ const { Icon, label } = m;
75
+ return (_jsxs("span", { className: "inline-flex items-center gap-1.5 text-[12px] text-[var(--wui-fg-muted)]", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0", strokeWidth: 1.75 }), label] }));
76
+ }
25
77
  // ─── Leading visual ───────────────────────────────────────────────────────────
26
78
  const wfLeading = (entry, size) => {
27
79
  if (entry.kind === 'folder')
28
80
  return _jsx(FolderCard, { size: size });
29
81
  const isSm = size === 'sm';
30
- return (_jsx("div", { className: cn('flex items-center justify-center rounded-lg bg-indigo-50 dark:bg-indigo-950/30', isSm ? 'h-9 w-9' : 'h-14 w-14'), children: _jsx(Workflow, { strokeWidth: 1.5, className: cn('text-indigo-300 dark:text-indigo-400', isSm ? 'h-5 w-5' : 'h-8 w-8') }) }));
82
+ return (_jsx("div", { className: cn('flex items-center justify-center rounded-lg bg-[color-mix(in_srgb,var(--wui-primary)_12%,transparent)]', isSm ? 'h-9 w-9' : 'h-14 w-14'), children: _jsx(Workflow, { strokeWidth: 1.5, className: cn('text-[var(--wui-primary)]', isSm ? 'h-5 w-5' : 'h-8 w-8') }) }));
31
83
  };
32
84
  // ─── Helpers ──────────────────────────────────────────────────────────────────
33
85
  function parseMeta(raw) {
@@ -74,11 +126,11 @@ function folderToEntry(f, childCount) {
74
126
  kind: 'folder',
75
127
  id: f.id,
76
128
  name: f.name,
77
- caption: `${String(childCount)} item${childCount === 1 ? '' : 's'}`,
129
+ ...(childCount > 0 ? { caption: `${String(childCount)} item${childCount === 1 ? '' : 's'}` } : {}),
78
130
  };
79
131
  }
80
132
  // ─── Component ────────────────────────────────────────────────────────────────
81
- export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb, onPathChange, onToast, className, }) {
133
+ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb, onPathChange, onToast, hideApprovals = false, className, }) {
82
134
  const client = useWorkflowClient();
83
135
  const [view, setViewInternal] = useState(() => {
84
136
  try {
@@ -116,6 +168,8 @@ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb,
116
168
  const [selectedTags, setSelectedTags] = useState([]);
117
169
  /** Workflow whose tags are being edited. */
118
170
  const [tagEditTarget, setTagEditTarget] = useState(null);
171
+ const [deleteTarget, setDeleteTarget] = useState(null);
172
+ const [lastRunByWorkflow, setLastRunByWorkflow] = useState({});
119
173
  const [showCreateDialog, setShowCreateDialog] = useState(false);
120
174
  const [showApprovals, setShowApprovals] = useState(false);
121
175
  const polledCount = useApprovalCount();
@@ -149,6 +203,30 @@ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb,
149
203
  setLoading(false); });
150
204
  return () => { cancelled = true; };
151
205
  }, [currentFolderId, reloadKey]); // eslint-disable-line react-hooks/exhaustive-deps
206
+ // Most-recent execution per workflow in this folder — drives the "Last run" column.
207
+ useEffect(() => {
208
+ if (!currentFolderId) {
209
+ setLastRunByWorkflow({});
210
+ return;
211
+ }
212
+ let cancelled = false;
213
+ void client.executions
214
+ .list({ folderId: currentFolderId, limit: 300 })
215
+ .then((res) => {
216
+ if (cancelled)
217
+ return;
218
+ const map = {};
219
+ for (const ex of res.items) {
220
+ // list is newest-first, so the first hit per workflow is its latest run.
221
+ if (!map[ex.workflowId]) {
222
+ map[ex.workflowId] = { status: ex.status, createdAt: new Date(ex.createdAt).getTime() };
223
+ }
224
+ }
225
+ setLastRunByWorkflow(map);
226
+ })
227
+ .catch(() => { });
228
+ return () => { cancelled = true; };
229
+ }, [currentFolderId, reloadKey]); // eslint-disable-line react-hooks/exhaustive-deps
152
230
  const childFolders = allFolders.filter((f) => currentFolderId ? f.parentId === currentFolderId : !f.parentId);
153
231
  const itemCount = (id) => {
154
232
  const subfolders = allFolders.filter((f) => f.parentId === id).length;
@@ -157,7 +235,13 @@ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb,
157
235
  };
158
236
  const allEntries = [
159
237
  ...childFolders.map((f) => folderToEntry(f, itemCount(f.id))),
160
- ...(isAtRoot ? [] : workflows.map(workflowToEntry)),
238
+ ...(isAtRoot ? [] : workflows.map((wf) => {
239
+ const e = workflowToEntry(wf);
240
+ const lr = lastRunByWorkflow[wf.id];
241
+ return lr
242
+ ? { ...e, columns: { ...e.columns, lastRunStatus: lr.status, lastRunAt: String(lr.createdAt) } }
243
+ : e;
244
+ })),
161
245
  ];
162
246
  // Tags present in this folder's workflows — drives the filter selector.
163
247
  const availableTags = [
@@ -262,19 +346,22 @@ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb,
262
346
  onToast?.('error', err instanceof Error ? err.message : 'Could not update tags');
263
347
  }
264
348
  };
265
- const handleDelete = async (entry) => {
266
- if (entry.kind === 'folder') {
267
- const ok = window.confirm(`Delete folder "${entry.name}"?`);
268
- if (!ok)
269
- return;
270
- try {
271
- await client.folders.delete(entry.id);
272
- onToast?.('success', `Deleted "${entry.name}"`);
273
- refresh();
274
- }
275
- catch (err) {
276
- onToast?.('error', err instanceof Error ? err.message : 'Could not delete folder');
277
- }
349
+ const handleDelete = (entry) => {
350
+ if (entry.kind === 'folder')
351
+ setDeleteTarget(entry);
352
+ };
353
+ const confirmDelete = async () => {
354
+ const entry = deleteTarget;
355
+ if (!entry)
356
+ return;
357
+ setDeleteTarget(null);
358
+ try {
359
+ await client.folders.delete(entry.id);
360
+ onToast?.('success', `Deleted "${entry.name}"`);
361
+ refresh();
362
+ }
363
+ catch (err) {
364
+ onToast?.('error', err instanceof Error ? err.message : 'Could not delete folder');
278
365
  }
279
366
  };
280
367
  const triggerWorkflow = async (id, name, payload) => {
@@ -363,28 +450,34 @@ export function WorkflowBrowser({ onSelectWorkflow, onViewRun, path: breadcrumb,
363
450
  onSelectWorkflow(wf.id, breadcrumb);
364
451
  };
365
452
  // ── Render ──────────────────────────────────────────────────────────────────
366
- return (_jsxs("div", { className: cn('relative flex h-full flex-col', className), children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-border bg-background/70 px-5 py-2.5 backdrop-blur-md", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [_jsx("button", { type: "button", "aria-label": "Up one level", disabled: !showApprovals && isAtRoot, onClick: showApprovals ? () => { setShowApprovals(false); } : goUp, className: "grid h-7 w-7 place-items-center rounded-md text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent", children: _jsx(ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true, strokeWidth: 1.75 }) }), showApprovals ? (_jsxs("nav", { className: "flex min-w-0 items-center gap-1 text-[13px] text-muted-foreground", children: [_jsx("button", { type: "button", onClick: () => { setShowApprovals(false); }, className: "rounded-md px-1.5 py-0.5 transition hover:bg-secondary hover:text-foreground", children: "Workflows" }), _jsx("span", { className: "select-none text-muted-foreground/60", children: "\u203A" }), _jsx("span", { className: "cursor-default px-1.5 py-0.5 font-medium text-foreground", children: "Pending Approvals" })] })) : isAtRoot ? (_jsx("span", { className: "text-[13px] font-medium text-foreground", children: "Workflows" })) : (_jsxs("nav", { className: "flex min-w-0 items-center gap-1 text-[13px] text-muted-foreground", children: [_jsx("button", { type: "button", onClick: goRoot, className: "rounded-md px-1.5 py-0.5 transition hover:bg-secondary hover:text-foreground", children: "Workflows" }), breadcrumb.map((seg, i) => {
367
- const isLast = i === breadcrumb.length - 1;
368
- return (_jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [_jsx("span", { className: "select-none text-muted-foreground/60", children: "\u203A" }), _jsx("button", { type: "button", onClick: () => (isLast ? undefined : goToIndex(i)), className: cn('max-w-[24ch] truncate rounded-md px-1.5 py-0.5 transition', isLast
369
- ? 'cursor-default font-medium text-foreground'
370
- : 'hover:bg-secondary hover:text-foreground'), title: seg.name, children: seg.name })] }, seg.id));
371
- })] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [!showApprovals && !isAtRoot && (_jsxs("button", { type: "button", onClick: () => { setShowCreateDialog(true); }, className: "inline-flex h-7 items-center gap-1 rounded-md border border-border bg-surface-elevated px-2 text-[12px] text-foreground transition hover:bg-secondary", children: [_jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }), "Create workflow"] })), !showApprovals && (_jsxs("button", { type: "button", onClick: () => { setDialog('folder'); }, className: "inline-flex h-7 items-center gap-1 rounded-md border border-border bg-surface-elevated px-2 text-[12px] text-foreground transition hover:bg-secondary", children: [_jsx(FolderPlus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }), "New folder"] })), !showApprovals && (_jsx("button", { type: "button", onClick: refresh, disabled: loading, "aria-label": "Refresh", title: "Refresh", className: "inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-surface-elevated text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-60", children: _jsx(RefreshCw, { className: cn('h-3.5 w-3.5', loading && 'animate-spin'), strokeWidth: 1.75 }) })), !showApprovals && _jsx(ViewToggle, { value: view, onChange: setView }), !showApprovals && (_jsx(SearchField, { value: query, onChange: setQuery, className: "w-56", ariaLabel: "Search workflows", placeholder: "Search by name" }))] })] }), selectedIds.size > 0 && (_jsx("div", { className: "pointer-events-none absolute bottom-6 left-0 right-0 z-20 flex justify-center", children: _jsxs("div", { className: "pointer-events-auto flex items-center gap-2 rounded-full border border-border bg-surface-elevated px-4 py-2 shadow-lg backdrop-blur-md", children: [_jsxs("span", { className: "text-[13px] font-medium text-foreground", children: [selectedIds.size, " item", selectedIds.size === 1 ? '' : 's', " selected"] }), _jsx("div", { className: "mx-1 h-4 w-px bg-border" }), _jsx("button", { type: "button", onClick: () => { setMoveEntries(allEntries.filter((e) => selectedIds.has(e.id))); }, className: "inline-flex h-7 items-center rounded-full bg-foreground px-3 text-[12px] font-medium text-background transition hover:opacity-90", children: "Move selected" }), _jsx("button", { type: "button", onClick: clearSelection, className: "text-[12px] text-muted-foreground transition hover:text-foreground", children: "Clear" })] }) })), showApprovals && (_jsx("div", { className: "flex-1 overflow-hidden", children: _jsx(ApprovalsView, { className: "h-full", onCountChange: setLocalCount, ...(onViewRun
453
+ return (_jsxs("div", { className: cn('relative flex h-full flex-col', className), children: [_jsx("div", { className: "flex h-12 shrink-0 items-center border-b border-[var(--wui-border)] px-5", children: _jsxs("div", { className: "mx-auto flex w-full max-w-7xl items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 overflow-hidden", children: [(showApprovals || !isAtRoot) && (_jsx("button", { type: "button", "aria-label": "Up one level", onClick: showApprovals ? () => { setShowApprovals(false); } : goUp, className: "grid h-7 w-7 place-items-center rounded-md text-[var(--wui-fg-muted)] transition hover:bg-[var(--wui-bg-muted)] hover:text-[var(--wui-fg)]", children: _jsx(ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true, strokeWidth: 1.75 }) })), showApprovals ? (_jsxs("nav", { className: "flex min-w-0 items-center gap-1 text-[13px] text-muted-foreground", children: [_jsx("button", { type: "button", onClick: () => { setShowApprovals(false); }, className: "rounded-md px-1.5 py-0.5 transition hover:bg-secondary hover:text-foreground", children: "Workflows" }), _jsx("span", { className: "select-none text-muted-foreground/60", children: "\u203A" }), _jsx("span", { className: "cursor-default px-1.5 py-0.5 font-medium text-foreground", children: "Pending Approvals" })] })) : isAtRoot ? (_jsx("span", { className: "text-[13px] font-medium text-[var(--wui-fg)]", children: "Workflows" })) : (_jsxs("nav", { className: "flex min-w-0 items-center gap-1 text-[13px] text-muted-foreground", children: [_jsx("button", { type: "button", onClick: goRoot, className: "rounded-md px-1.5 py-0.5 transition hover:bg-secondary hover:text-foreground", children: "Workflows" }), breadcrumb.map((seg, i) => {
454
+ const isLast = i === breadcrumb.length - 1;
455
+ return (_jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [_jsx("span", { className: "select-none text-muted-foreground/60", children: "\u203A" }), _jsx("button", { type: "button", onClick: () => (isLast ? undefined : goToIndex(i)), className: cn('max-w-[24ch] truncate rounded-md px-1.5 py-0.5 transition', isLast
456
+ ? 'cursor-default font-medium text-foreground'
457
+ : 'hover:bg-secondary hover:text-foreground'), title: seg.name, children: seg.name })] }, seg.id));
458
+ })] }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [!showApprovals && !isAtRoot && (_jsxs(ToolbarButton, { onClick: () => { setShowCreateDialog(true); }, children: [_jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }), "Create workflow"] })), !showApprovals && (_jsxs(ToolbarButton, { onClick: () => { setDialog('folder'); }, children: [_jsx(FolderPlus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }), "New folder"] })), !showApprovals && (_jsx(ToolbarIconButton, { onClick: refresh, disabled: loading, "aria-label": "Refresh", title: "Refresh", children: _jsx(RefreshCw, { className: cn('h-3.5 w-3.5', loading && 'animate-spin'), strokeWidth: 1.75 }) })), !showApprovals && _jsx(ViewToggle, { value: view, onChange: setView }), !showApprovals && (_jsx(SearchField, { value: query, onChange: setQuery, className: "w-56", ariaLabel: "Search workflows", placeholder: "Search by name" }))] })] }) }), selectedIds.size > 0 && (_jsx("div", { className: "pointer-events-none absolute bottom-6 left-0 right-0 z-20 flex justify-center", children: _jsxs("div", { className: "pointer-events-auto flex items-center gap-2 rounded-full border border-border bg-surface-elevated px-4 py-2 shadow-lg backdrop-blur-md", children: [_jsxs("span", { className: "text-[13px] font-medium text-foreground", children: [selectedIds.size, " item", selectedIds.size === 1 ? '' : 's', " selected"] }), _jsx("div", { className: "mx-1 h-4 w-px bg-border" }), _jsx("button", { type: "button", onClick: () => { setMoveEntries(allEntries.filter((e) => selectedIds.has(e.id))); }, className: "inline-flex h-7 items-center rounded-full bg-[var(--wui-primary)] px-3 text-[12px] font-medium text-[var(--wui-primary-fg)] transition-colors hover:bg-[var(--wui-primary-hover)]", children: "Move selected" }), _jsx("button", { type: "button", onClick: clearSelection, className: "text-[12px] text-muted-foreground transition hover:text-foreground", children: "Clear" })] }) })), showApprovals && (_jsx("div", { className: "flex-1 overflow-hidden", children: _jsx(ApprovalsView, { className: "h-full", onCountChange: setLocalCount, ...(onViewRun
372
459
  ? {
373
460
  onViewRun: (executionId, workflowName) => {
374
461
  setShowApprovals(false);
375
462
  onViewRun(executionId, workflowName);
376
463
  },
377
464
  }
378
- : {}) }) })), _jsx("main", { ref: mainRef, className: cn('relative flex-1 overflow-auto px-5 py-5', showApprovals && 'hidden'), children: _jsx("div", { className: "mx-auto w-full max-w-7xl", children: false ? null : (_jsxs(_Fragment, { children: [approvalCount > 0 && (_jsxs("button", { type: "button", onClick: () => { setShowApprovals(true); }, className: "mb-4 flex w-full items-center gap-3 rounded-xl border border-orange-200 bg-orange-50 px-4 py-3 text-left transition hover:bg-orange-100 dark:border-orange-800 dark:bg-orange-950/30 dark:hover:bg-orange-950/50", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0 text-orange-500", strokeWidth: 1.75 }), _jsxs("span", { className: "flex-1 text-[13px] font-medium text-orange-800 dark:text-orange-300", children: [approvalCount, " workflow", approvalCount === 1 ? '' : 's', " waiting for approval"] }), _jsx("span", { className: "text-[12px] text-orange-600 dark:text-orange-400", children: "Review \u2192" })] })), _jsxs("div", { className: "mb-3 flex items-center justify-between gap-2", children: [_jsx("p", { className: "text-[12px] text-muted-foreground", children: countText }), _jsx(TagFilter, { tags: availableTags, selected: selectedTags, onChange: setSelectedTags })] }), entries.length === 0 && !loading ? (_jsx(EmptyPane, { isRoot: isAtRoot })) : view === 'grid' ? (_jsx(EntryGrid, { entries: entries, renderLeading: wfLeading, onOpen: openEntry, onOpenEditor: (e) => { onSelectWorkflow(e.id, breadcrumb); }, onEditTags: openTagEditor, onRename: (e, name) => { void handleRename(e, name); }, onDelete: (e) => { void handleDelete(e); }, onMove: (e) => { setMoveEntries([e]); }, selectedIds: selectedIds, onToggleSelect: toggleSelect, scrollParentRef: mainRef })) : (_jsx(EntryList, { entries: entries, columns: isAtRoot ? [] : WF_COLUMNS, renderLeading: wfLeading, onOpen: openEntry, onOpenEditor: (e) => { onSelectWorkflow(e.id, breadcrumb); }, onEditTags: openTagEditor, onRename: (e, name) => { void handleRename(e, name); }, onDelete: (e) => { void handleDelete(e); }, onMove: (e) => { setMoveEntries([e]); }, selectedIds: selectedIds, onToggleSelect: toggleSelect, scrollParentRef: mainRef }))] })) }) }), _jsx(NameDialog, { open: dialog === 'folder', title: "New folder", description: currentFolderId
465
+ : {}) }) })), _jsx("main", { ref: mainRef, className: cn('relative flex flex-1 flex-col overflow-hidden px-5 py-5', showApprovals && 'hidden'), children: _jsx("div", { className: "mx-auto flex h-full w-full min-h-0 max-w-7xl flex-col", children: false ? null : (_jsxs(_Fragment, { children: [!hideApprovals && approvalCount > 0 && (_jsxs("button", { type: "button", onClick: () => { setShowApprovals(true); }, className: "mb-4 flex w-full items-center gap-3 rounded-xl border border-orange-200 bg-orange-50 px-4 py-3 text-left transition hover:bg-orange-100 dark:border-orange-800 dark:bg-orange-950/30 dark:hover:bg-orange-950/50", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0 text-orange-500", strokeWidth: 1.75 }), _jsxs("span", { className: "flex-1 text-[13px] font-medium text-orange-800 dark:text-orange-300", children: [approvalCount, " workflow", approvalCount === 1 ? '' : 's', " waiting for approval"] }), _jsx("span", { className: "text-[12px] text-orange-600 dark:text-orange-400", children: "Review \u2192" })] })), _jsxs("div", { className: "mb-3 flex shrink-0 items-center justify-between gap-2", children: [_jsx("p", { className: "text-[12px] text-muted-foreground", children: countText }), _jsx(TagFilter, { tags: availableTags, selected: selectedTags, onChange: setSelectedTags })] }), _jsx("div", { className: "min-h-0 flex-1", children: entries.length === 0 && !loading ? (_jsx(EmptyPane, { isRoot: isAtRoot })) : view === 'grid' ? (_jsx(EntryGrid, { entries: entries, renderLeading: wfLeading, onOpen: openEntry, onOpenEditor: (e) => { onSelectWorkflow(e.id, breadcrumb); }, onEditTags: openTagEditor, onRename: (e, name) => { void handleRename(e, name); }, onDelete: (e) => { void handleDelete(e); }, onMove: (e) => { setMoveEntries([e]); }, selectedIds: selectedIds, onToggleSelect: toggleSelect, scrollParentRef: mainRef })) : (_jsx(EntryList, { entries: entries, columns: isAtRoot ? [] : WF_COLUMNS, renderLeading: wfLeading, onOpen: openEntry, onOpenEditor: (e) => { onSelectWorkflow(e.id, breadcrumb); }, onEditTags: openTagEditor, onRename: (e, name) => { void handleRename(e, name); }, onDelete: (e) => { void handleDelete(e); }, onMove: (e) => { setMoveEntries([e]); }, selectedIds: selectedIds, onToggleSelect: toggleSelect, scrollParentRef: mainRef })) })] })) }) }), _jsx(NameDialog, { open: dialog === 'folder', title: "New folder", description: currentFolderId
379
466
  ? 'Adds a subfolder inside the current folder.'
380
- : 'Adds a top-level folder for organising workflows.', label: "Folder name", placeholder: "e.g. Notifications", helper: "Up to 255 characters.", submitLabel: "Create folder", onSubmit: submitNewFolder, onClose: () => { setDialog(null); } }), showCreateDialog && (_jsx(CreateWorkflowDialog, { folders: allFolders, defaultFolderId: currentFolderId ?? undefined, onCreateFolder: handleCreateFolder, onCreated: handleWorkflowCreated, onClose: () => { setShowCreateDialog(false); } })), tagEditTarget && (_jsx(TagEditDialog, { target: tagEditTarget, suggestions: availableTags, onSave: (tags) => { void saveTags(tagEditTarget.id, tags); }, onClose: () => { setTagEditTarget(null); } })), runTarget && (_jsx(TriggerFormModal, { inputSchema: runTarget.inputSchema, workflowName: runTarget.name, onSubmit: (payload) => triggerWorkflow(runTarget.id, runTarget.name, payload), onClose: () => { setRunTarget(null); } })), moveEntries && moveEntries.length > 0 && (_jsx(MoveDialog, { entries: moveEntries, folders: allFolders, currentParentId: moveEntries.length === 1 && moveEntries[0].kind === 'folder'
467
+ : 'Adds a top-level folder for organising workflows.', label: "Folder name", placeholder: "e.g. Notifications", helper: "Up to 255 characters.", submitLabel: "Create folder", onSubmit: submitNewFolder, onClose: () => { setDialog(null); } }), showCreateDialog && (_jsx(CreateWorkflowDialog, { folders: allFolders, defaultFolderId: currentFolderId ?? undefined, onCreateFolder: handleCreateFolder, onCreated: handleWorkflowCreated, onClose: () => { setShowCreateDialog(false); } })), tagEditTarget && (_jsx(TagEditDialog, { target: tagEditTarget, suggestions: availableTags, onSave: (tags) => { void saveTags(tagEditTarget.id, tags); }, onClose: () => { setTagEditTarget(null); } })), deleteTarget && (_jsx(ConfirmDialog, { title: `Delete folder "${deleteTarget.name}"?`, message: "This permanently deletes the folder. This can't be undone.", confirmLabel: "Delete folder", danger: true, onConfirm: () => { void confirmDelete(); }, onClose: () => { setDeleteTarget(null); } })), runTarget && (_jsx(TriggerFormModal, { inputSchema: runTarget.inputSchema, workflowName: runTarget.name, onSubmit: (payload) => triggerWorkflow(runTarget.id, runTarget.name, payload), onClose: () => { setRunTarget(null); } })), moveEntries && moveEntries.length > 0 && (_jsx(MoveDialog, { entries: moveEntries, folders: allFolders, currentParentId: moveEntries.length === 1 && moveEntries[0].kind === 'folder'
381
468
  ? (allFolders.find((f) => f.id === moveEntries[0].id)?.parentId ?? null)
382
469
  : currentFolderId, onMove: (targetId) => { void handleMoveConfirm(moveEntries, targetId); }, onClose: () => { setMoveEntries(null); } }))] }));
383
470
  }
384
471
  // ─── Tag editor dialog ─────────────────────────────────────────────────────────
385
472
  function TagEditDialog({ target, suggestions, onSave, onClose, }) {
386
473
  const [tags, setTags] = useState(target.tags);
387
- return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 bg-black/30", onClick: onClose }), _jsxs("div", { className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-surface-elevated shadow-xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-5 py-3.5", children: [_jsxs("h3", { className: "truncate text-sm font-semibold text-foreground", title: target.name, children: ["Teams \u00B7 ", target.name] }), _jsx("button", { onClick: onClose, "aria-label": "Close", className: "grid h-6 w-6 place-items-center rounded-md text-muted-foreground hover:bg-secondary hover:text-foreground", children: _jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [_jsx("path", { d: "M18 6 6 18" }), _jsx("path", { d: "m6 6 12 12" })] }) })] }), _jsx("div", { className: "px-5 py-4", children: _jsx(TagInput, { value: tags, onChange: setTags, suggestions: suggestions, placeholder: "Add a team \u2014 Enter to confirm" }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-border px-5 py-3", children: [_jsx("button", { onClick: onClose, className: "rounded-md border border-border px-3.5 py-1.5 text-[13px] font-medium text-muted-foreground hover:bg-secondary", children: "Cancel" }), _jsx("button", { onClick: () => onSave(tags), className: "rounded-md bg-foreground px-3.5 py-1.5 text-[13px] font-semibold text-background hover:opacity-90", children: "Save tags" })] })] })] }));
474
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: onClose }), _jsxs("div", { className: "relative z-10 w-full max-w-md rounded-xl border border-[var(--wui-border)] bg-[var(--wui-surface)] shadow-xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-[var(--wui-border)] px-5 py-3.5", children: [_jsxs("h3", { className: "truncate text-sm font-semibold text-[var(--wui-fg)]", title: target.name, children: ["Teams \u00B7 ", target.name] }), _jsx("button", { onClick: onClose, "aria-label": "Close", className: "grid h-6 w-6 place-items-center rounded-md text-[var(--wui-fg-muted)] hover:bg-[var(--wui-bg-muted)] hover:text-[var(--wui-fg)]", children: _jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [_jsx("path", { d: "M18 6 6 18" }), _jsx("path", { d: "m6 6 12 12" })] }) })] }), _jsx("div", { className: "px-5 py-4", children: _jsx(TagInput, { value: tags, onChange: setTags, suggestions: suggestions, placeholder: "Add a team \u2014 Enter to confirm" }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-[var(--wui-border)] px-5 py-3", children: [_jsx("button", { onClick: onClose, className: "rounded-md border border-[var(--wui-border)] px-3.5 py-1.5 text-[13px] font-medium text-[var(--wui-fg-muted)] hover:bg-[var(--wui-bg-muted)]", children: "Cancel" }), _jsx("button", { onClick: () => onSave(tags), className: "rounded-md bg-[var(--wui-primary)] px-3.5 py-1.5 text-[13px] font-semibold text-[var(--wui-primary-fg)] hover:bg-[var(--wui-primary-hover)]", children: "Save tags" })] })] })] }));
475
+ }
476
+ // ─── Confirm dialog ───────────────────────────────────────────────────────────
477
+ function ConfirmDialog({ title, message, confirmLabel, danger, onConfirm, onClose, }) {
478
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: onClose }), _jsxs("div", { className: "relative z-10 w-full max-w-sm rounded-xl border border-[var(--wui-border)] bg-[var(--wui-surface)] shadow-xl", children: [_jsxs("div", { className: "px-5 py-4", children: [_jsx("h3", { className: "text-sm font-semibold text-[var(--wui-fg)]", children: title }), message ? (_jsx("p", { className: "mt-1.5 text-[13px] leading-relaxed text-[var(--wui-fg-muted)]", children: message })) : null] }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-[var(--wui-border)] px-5 py-3", children: [_jsx("button", { onClick: onClose, className: "rounded-md border border-[var(--wui-border)] px-3.5 py-1.5 text-[13px] font-medium text-[var(--wui-fg-muted)] transition-colors hover:bg-[var(--wui-bg-muted)]", children: "Cancel" }), _jsx("button", { onClick: onConfirm, className: cn('rounded-md px-3.5 py-1.5 text-[13px] font-semibold text-white transition-colors', danger
479
+ ? 'bg-[var(--wui-status-failed)] hover:opacity-90'
480
+ : 'bg-[var(--wui-primary)] hover:bg-[var(--wui-primary-hover)]'), children: confirmLabel })] })] })] }));
388
481
  }
389
482
  // ─── Empty state ──────────────────────────────────────────────────────────────
390
483
  function EmptyPane({ isRoot }) {