@burdenoff/microfe-vibecontrols 2026.527.14 → 2026.527.16

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 (35) hide show
  1. package/dist/components/audit/AuditLogDetail.js +42 -18
  2. package/dist/components/audit/AuditLogDetail.js.map +1 -1
  3. package/dist/components/audit/AuditLogTable.js +6 -5
  4. package/dist/components/audit/AuditLogTable.js.map +1 -1
  5. package/dist/pages/ActionsPage.js +11 -11
  6. package/dist/pages/ActionsPage.js.map +1 -1
  7. package/dist/pages/AgentDetailsPage.js +785 -785
  8. package/dist/pages/AgentDetailsPage.js.map +1 -1
  9. package/dist/pages/AgentGraphPage.js +36 -36
  10. package/dist/pages/AgentGraphPage.js.map +1 -1
  11. package/dist/pages/AgentsLandingPage.js +1 -1
  12. package/dist/pages/AgentsLandingPage.js.map +1 -1
  13. package/dist/pages/LogsPage.js +10 -5
  14. package/dist/pages/LogsPage.js.map +1 -1
  15. package/dist/pages/OverviewPage.js +192 -194
  16. package/dist/pages/OverviewPage.js.map +1 -1
  17. package/dist/pages/PluginStandalonePage.js +31 -25
  18. package/dist/pages/PluginStandalonePage.js.map +1 -1
  19. package/dist/pages/SessionDetailsPage.js +74 -74
  20. package/dist/pages/SessionDetailsPage.js.map +1 -1
  21. package/dist/pages/SessionsPage.js +5 -1
  22. package/dist/pages/SessionsPage.js.map +1 -1
  23. package/dist/pages/SettingsPage.js +30 -26
  24. package/dist/pages/SettingsPage.js.map +1 -1
  25. package/dist/pages/VibeAuditPage.js +50 -47
  26. package/dist/pages/VibeAuditPage.js.map +1 -1
  27. package/dist/pages/VibeCalendarPage.js +43 -42
  28. package/dist/pages/VibeCalendarPage.js.map +1 -1
  29. package/dist/pages/VibeDeckPage.js +199 -198
  30. package/dist/pages/VibeDeckPage.js.map +1 -1
  31. package/dist/pages/VibeTaskDetailPage.js +31 -31
  32. package/dist/pages/VibeTaskDetailPage.js.map +1 -1
  33. package/dist/pages/tunnels/ProvidersTab.js +1 -1
  34. package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
  35. package/package.json +1 -1
@@ -137,13 +137,26 @@ function h({ log: n, onClose: i }) {
137
137
  className: "relative flex h-full w-full max-w-[480px] flex-col border-l border-border-default bg-bg-surface shadow-xl",
138
138
  children: [/* @__PURE__ */ d("div", {
139
139
  className: "flex items-center justify-between px-4 py-3 border-b border-border-default",
140
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h3", {
141
- className: "text-sm font-semibold",
142
- children: "Audit Log Detail"
143
- }), /* @__PURE__ */ u("span", {
144
- className: "text-xs text-text-secondary font-mono",
145
- children: n.id
146
- })] }), /* @__PURE__ */ u("button", {
140
+ children: [/* @__PURE__ */ d("div", { children: [
141
+ /* @__PURE__ */ u("h3", {
142
+ className: "text-sm font-semibold",
143
+ children: n.action.replace(/_/g, " ")
144
+ }),
145
+ /* @__PURE__ */ d("p", {
146
+ className: "text-xs text-text-secondary",
147
+ children: [n.resourceType.replace(/_/g, " "), n.resourceName ? ` · ${n.resourceName}` : ""]
148
+ }),
149
+ /* @__PURE__ */ d("details", {
150
+ className: "mt-1",
151
+ children: [/* @__PURE__ */ u("summary", {
152
+ className: "cursor-pointer text-[10px] uppercase tracking-wider text-text-secondary hover:text-text-primary",
153
+ children: "Event ID"
154
+ }), /* @__PURE__ */ u("span", {
155
+ className: "mt-1 block break-all font-mono text-[11px] text-text-secondary",
156
+ children: n.id
157
+ })]
158
+ })
159
+ ] }), /* @__PURE__ */ u("button", {
147
160
  type: "button",
148
161
  "aria-label": o("audit.closeDetail", "Close audit log detail"),
149
162
  onClick: i,
@@ -201,17 +214,28 @@ function h({ log: n, onClose: i }) {
201
214
  children: n.description || "-"
202
215
  })]
203
216
  }),
204
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
205
- className: "text-text-secondary text-xs",
206
- children: "Actor"
207
- }), /* @__PURE__ */ u("div", {
208
- className: "font-mono text-xs",
209
- children: n.actorId
210
- })] }),
211
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
212
- className: "text-text-secondary text-xs",
213
- children: "Actor Type"
214
- }), /* @__PURE__ */ u("div", { children: n.actorType || "-" })] }),
217
+ /* @__PURE__ */ d("div", {
218
+ className: "col-span-2",
219
+ children: [/* @__PURE__ */ u("span", {
220
+ className: "text-text-secondary text-xs",
221
+ children: "Actor"
222
+ }), /* @__PURE__ */ d("div", {
223
+ className: "flex items-center gap-2",
224
+ children: [/* @__PURE__ */ u("span", {
225
+ className: "capitalize",
226
+ children: (n.actorType || "unknown").toLowerCase().replace(/_/g, " ")
227
+ }), /* @__PURE__ */ d("details", {
228
+ className: "text-xs text-text-secondary",
229
+ children: [/* @__PURE__ */ u("summary", {
230
+ className: "cursor-pointer hover:text-text-primary",
231
+ children: "ID"
232
+ }), /* @__PURE__ */ u("span", {
233
+ className: "ml-2 break-all font-mono text-[11px]",
234
+ children: n.actorId
235
+ })]
236
+ })]
237
+ })]
238
+ }),
215
239
  /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
216
240
  className: "text-text-secondary text-xs",
217
241
  children: "Timestamp"
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLogDetail.js","names":[],"sources":["../../../src/components/audit/AuditLogDetail.tsx"],"sourcesContent":["import { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useEffect, useState } from 'react';\nimport { X, ChevronDown, ChevronRight, Copy, Check, Terminal } from 'lucide-react';\nimport type { VibeAuditLogDetailFragment } from '@/generated/wspace-operations';\nimport { StatusBadge } from '@/components/shared';\n\ninterface AuditLogDetailProps {\n log: VibeAuditLogDetailFragment;\n onClose: () => void;\n}\n\nfunction JsonViewer({ data, label }: { data: unknown; label: string }) {\n const [expanded, setExpanded] = useState(false);\n if (!data) return null;\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium bg-bg-secondary/50 hover:bg-bg-secondary\"\n >\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n {label}\n </button>\n {expanded && (\n <pre className=\"px-3 py-2 text-xs overflow-auto max-h-64 bg-bg-sunken\">\n {JSON.stringify(data, null, 2)}\n </pre>\n )}\n </div>\n );\n}\n\nfunction CommandBlock({\n command,\n output,\n exitCode,\n}: {\n command?: string | null;\n output?: string | null;\n exitCode?: number | null;\n}) {\n const [copied, setCopied] = useState(false);\n if (!command && !output) return null;\n\n const handleCopy = () => {\n if (command) {\n navigator.clipboard.writeText(command);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <div className=\"flex items-center justify-between px-3 py-2 bg-bg-secondary/50\">\n <span className=\"flex items-center gap-2 text-sm font-medium\">\n <Terminal size={14} />\n Command Execution\n {exitCode !== null && exitCode !== undefined && (\n <span\n className={`px-1.5 py-0.5 rounded text-xs ${exitCode === 0 ? 'bg-status-success-bg text-status-success-text' : 'bg-status-error-bg text-status-error-text'}`}\n >\n exit {exitCode}\n </span>\n )}\n </span>\n {command && (\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"p-1 rounded hover:bg-bg-secondary text-text-secondary\"\n title=\"Copy command\"\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n )}\n </div>\n {command && (\n <div className=\"px-3 py-2 bg-bg-sunken text-text-secondary font-mono text-xs\">\n <span className=\"text-status-success-text\">$</span> {command}\n </div>\n )}\n {output && (\n <pre className=\"px-3 py-2 text-xs bg-bg-sunken text-text-tertiary font-mono overflow-auto max-h-48\">\n {output}\n </pre>\n )}\n </div>\n );\n}\n\nfunction ChangesetViewer({ changeset }: { changeset: Record<string, unknown> | null | undefined }) {\n const [expanded, setExpanded] = useState(false);\n if (!changeset || typeof changeset !== 'object') return null;\n\n const changes = Object.entries(changeset as Record<string, { from: unknown; to: unknown }>);\n if (changes.length === 0) return null;\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium bg-bg-secondary/50 hover:bg-bg-secondary\"\n >\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n Changes ({changes.length} field{changes.length !== 1 ? 's' : ''})\n </button>\n {expanded && (\n <div className=\"px-3 py-2 space-y-2\">\n {changes.map(([field, change]) => (\n <div key={field} className=\"text-xs\">\n <span className=\"font-medium text-text-primary\">{field}</span>\n <div className=\"ml-4 mt-1 space-y-0.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-status-error-text font-mono\">-</span>\n <span className=\"text-status-error-text\">\n {JSON.stringify((change as { from: unknown }).from)}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-status-success-text font-mono\">+</span>\n <span className=\"text-status-success-text\">\n {JSON.stringify((change as { to: unknown }).to)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function AuditLogDetail({ log, onClose }: AuditLogDetailProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onClose]);\n\n return (\n <div className=\"fixed inset-0 z-[1000] flex justify-end bg-bg-overlay/40\">\n <button\n type=\"button\"\n aria-label={tr('audit.closeDetailOverlay', 'Close audit log detail')}\n className=\"absolute inset-0 cursor-default\"\n onClick={onClose}\n />\n <aside className=\"relative flex h-full w-full max-w-[480px] flex-col border-l border-border-default bg-bg-surface shadow-xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <div>\n <h3 className=\"text-sm font-semibold\">Audit Log Detail</h3>\n <span className=\"text-xs text-text-secondary font-mono\">{log.id}</span>\n </div>\n <button\n type=\"button\"\n aria-label={tr('audit.closeDetail', 'Close audit log detail')}\n onClick={onClose}\n className=\"flex size-10 items-center justify-center rounded hover:bg-bg-secondary\"\n >\n <X size={16} />\n </button>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {/* Summary */}\n <div className=\"grid grid-cols-2 gap-3 text-sm\">\n <div>\n <span className=\"text-text-secondary text-xs\">Action</span>\n <div className=\"font-medium\">{log.action}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Status</span>\n <div>\n <StatusBadge status={log.status} size=\"sm\" />\n </div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Resource Type</span>\n <div className=\"font-medium\">{log.resourceType.replace(/_/g, ' ')}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Resource ID</span>\n <div className=\"font-mono text-xs truncate\">{log.resourceId || '-'}</div>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Resource Name</span>\n <div>{log.resourceName || '-'}</div>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Description</span>\n <div className=\"text-text-secondary\">{log.description || '-'}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Actor</span>\n <div className=\"font-mono text-xs\">{log.actorId}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Actor Type</span>\n <div>{log.actorType || '-'}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Timestamp</span>\n <div className=\"text-xs\">{new Date(log.createdAt).toLocaleString()}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">IP Address</span>\n <div className=\"font-mono text-xs\">{log.ipAddress || '-'}</div>\n </div>\n {log.expiresAt && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Expires At</span>\n <div className=\"text-xs text-status-warning-text\">\n {new Date(log.expiresAt).toLocaleString()}\n </div>\n </div>\n )}\n {log.errorMessage && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Error</span>\n <div className=\"text-status-error-text text-xs\">{log.errorMessage}</div>\n </div>\n )}\n {log.deleteReason && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Delete Reason</span>\n <div className=\"text-xs\">{log.deleteReason}</div>\n </div>\n )}\n </div>\n\n {/* Command execution */}\n <CommandBlock command={log.command} output={log.output} exitCode={log.exitCode} />\n\n {/* Changeset */}\n <ChangesetViewer changeset={log.changeset as Record<string, unknown> | null} />\n\n {/* State snapshots */}\n <JsonViewer data={log.previousState} label=\"Previous State\" />\n <JsonViewer data={log.newState} label=\"New State\" />\n <JsonViewer data={log.metadata} label=\"Metadata\" />\n </div>\n </aside>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuditLogDetail.js","names":[],"sources":["../../../src/components/audit/AuditLogDetail.tsx"],"sourcesContent":["import { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useEffect, useState } from 'react';\nimport { X, ChevronDown, ChevronRight, Copy, Check, Terminal } from 'lucide-react';\nimport type { VibeAuditLogDetailFragment } from '@/generated/wspace-operations';\nimport { StatusBadge } from '@/components/shared';\n\ninterface AuditLogDetailProps {\n log: VibeAuditLogDetailFragment;\n onClose: () => void;\n}\n\nfunction JsonViewer({ data, label }: { data: unknown; label: string }) {\n const [expanded, setExpanded] = useState(false);\n if (!data) return null;\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium bg-bg-secondary/50 hover:bg-bg-secondary\"\n >\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n {label}\n </button>\n {expanded && (\n <pre className=\"px-3 py-2 text-xs overflow-auto max-h-64 bg-bg-sunken\">\n {JSON.stringify(data, null, 2)}\n </pre>\n )}\n </div>\n );\n}\n\nfunction CommandBlock({\n command,\n output,\n exitCode,\n}: {\n command?: string | null;\n output?: string | null;\n exitCode?: number | null;\n}) {\n const [copied, setCopied] = useState(false);\n if (!command && !output) return null;\n\n const handleCopy = () => {\n if (command) {\n navigator.clipboard.writeText(command);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <div className=\"flex items-center justify-between px-3 py-2 bg-bg-secondary/50\">\n <span className=\"flex items-center gap-2 text-sm font-medium\">\n <Terminal size={14} />\n Command Execution\n {exitCode !== null && exitCode !== undefined && (\n <span\n className={`px-1.5 py-0.5 rounded text-xs ${exitCode === 0 ? 'bg-status-success-bg text-status-success-text' : 'bg-status-error-bg text-status-error-text'}`}\n >\n exit {exitCode}\n </span>\n )}\n </span>\n {command && (\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"p-1 rounded hover:bg-bg-secondary text-text-secondary\"\n title=\"Copy command\"\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n )}\n </div>\n {command && (\n <div className=\"px-3 py-2 bg-bg-sunken text-text-secondary font-mono text-xs\">\n <span className=\"text-status-success-text\">$</span> {command}\n </div>\n )}\n {output && (\n <pre className=\"px-3 py-2 text-xs bg-bg-sunken text-text-tertiary font-mono overflow-auto max-h-48\">\n {output}\n </pre>\n )}\n </div>\n );\n}\n\nfunction ChangesetViewer({ changeset }: { changeset: Record<string, unknown> | null | undefined }) {\n const [expanded, setExpanded] = useState(false);\n if (!changeset || typeof changeset !== 'object') return null;\n\n const changes = Object.entries(changeset as Record<string, { from: unknown; to: unknown }>);\n if (changes.length === 0) return null;\n\n return (\n <div className=\"border border-border-primary rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium bg-bg-secondary/50 hover:bg-bg-secondary\"\n >\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n Changes ({changes.length} field{changes.length !== 1 ? 's' : ''})\n </button>\n {expanded && (\n <div className=\"px-3 py-2 space-y-2\">\n {changes.map(([field, change]) => (\n <div key={field} className=\"text-xs\">\n <span className=\"font-medium text-text-primary\">{field}</span>\n <div className=\"ml-4 mt-1 space-y-0.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-status-error-text font-mono\">-</span>\n <span className=\"text-status-error-text\">\n {JSON.stringify((change as { from: unknown }).from)}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-status-success-text font-mono\">+</span>\n <span className=\"text-status-success-text\">\n {JSON.stringify((change as { to: unknown }).to)}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function AuditLogDetail({ log, onClose }: AuditLogDetailProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onClose]);\n\n return (\n <div className=\"fixed inset-0 z-[1000] flex justify-end bg-bg-overlay/40\">\n <button\n type=\"button\"\n aria-label={tr('audit.closeDetailOverlay', 'Close audit log detail')}\n className=\"absolute inset-0 cursor-default\"\n onClick={onClose}\n />\n <aside className=\"relative flex h-full w-full max-w-[480px] flex-col border-l border-border-default bg-bg-surface shadow-xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default\">\n <div>\n <h3 className=\"text-sm font-semibold\">\n {log.action.replace(/_/g, ' ')}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {log.resourceType.replace(/_/g, ' ')}\n {log.resourceName ? ` · ${log.resourceName}` : ''}\n </p>\n <details className=\"mt-1\">\n <summary className=\"cursor-pointer text-[10px] uppercase tracking-wider text-text-secondary hover:text-text-primary\">\n Event ID\n </summary>\n <span className=\"mt-1 block break-all font-mono text-[11px] text-text-secondary\">\n {log.id}\n </span>\n </details>\n </div>\n <button\n type=\"button\"\n aria-label={tr('audit.closeDetail', 'Close audit log detail')}\n onClick={onClose}\n className=\"flex size-10 items-center justify-center rounded hover:bg-bg-secondary\"\n >\n <X size={16} />\n </button>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {/* Summary */}\n <div className=\"grid grid-cols-2 gap-3 text-sm\">\n <div>\n <span className=\"text-text-secondary text-xs\">Action</span>\n <div className=\"font-medium\">{log.action}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Status</span>\n <div>\n <StatusBadge status={log.status} size=\"sm\" />\n </div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Resource Type</span>\n <div className=\"font-medium\">{log.resourceType.replace(/_/g, ' ')}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Resource ID</span>\n <div className=\"font-mono text-xs truncate\">{log.resourceId || '-'}</div>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Resource Name</span>\n <div>{log.resourceName || '-'}</div>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Description</span>\n <div className=\"text-text-secondary\">{log.description || '-'}</div>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Actor</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"capitalize\">\n {(log.actorType || 'unknown').toLowerCase().replace(/_/g, ' ')}\n </span>\n <details className=\"text-xs text-text-secondary\">\n <summary className=\"cursor-pointer hover:text-text-primary\">\n ID\n </summary>\n <span className=\"ml-2 break-all font-mono text-[11px]\">\n {log.actorId}\n </span>\n </details>\n </div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">Timestamp</span>\n <div className=\"text-xs\">{new Date(log.createdAt).toLocaleString()}</div>\n </div>\n <div>\n <span className=\"text-text-secondary text-xs\">IP Address</span>\n <div className=\"font-mono text-xs\">{log.ipAddress || '-'}</div>\n </div>\n {log.expiresAt && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Expires At</span>\n <div className=\"text-xs text-status-warning-text\">\n {new Date(log.expiresAt).toLocaleString()}\n </div>\n </div>\n )}\n {log.errorMessage && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Error</span>\n <div className=\"text-status-error-text text-xs\">{log.errorMessage}</div>\n </div>\n )}\n {log.deleteReason && (\n <div className=\"col-span-2\">\n <span className=\"text-text-secondary text-xs\">Delete Reason</span>\n <div className=\"text-xs\">{log.deleteReason}</div>\n </div>\n )}\n </div>\n\n {/* Command execution */}\n <CommandBlock command={log.command} output={log.output} exitCode={log.exitCode} />\n\n {/* Changeset */}\n <ChangesetViewer changeset={log.changeset as Record<string, unknown> | null} />\n\n {/* State snapshots */}\n <JsonViewer data={log.previousState} label=\"Previous State\" />\n <JsonViewer data={log.newState} label=\"New State\" />\n <JsonViewer data={log.metadata} label=\"Metadata\" />\n </div>\n </aside>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -79,9 +79,9 @@ function f({ items: f, total: p, hasMore: m, page: h, pageSize: g, onPageChange:
79
79
  }),
80
80
  /* @__PURE__ */ s("div", {
81
81
  className: "mt-3 flex items-center justify-between gap-3",
82
- children: [/* @__PURE__ */ o("p", {
83
- className: "min-w-0 truncate font-mono text-xs text-text-secondary",
84
- children: n.actorId
82
+ children: [/* @__PURE__ */ s("p", {
83
+ className: "min-w-0 truncate text-xs capitalize text-text-secondary",
84
+ children: [(n.actorType || "unknown").toLowerCase().replace(/_/g, " "), n.resourceName ? ` · ${n.resourceName}` : ""]
85
85
  }), /* @__PURE__ */ o(e, {
86
86
  status: n.status,
87
87
  variant: c[n.status],
@@ -186,8 +186,9 @@ function f({ items: f, total: p, hasMore: m, page: h, pageSize: g, onPageChange:
186
186
  children: n.resourceName || n.description || "-"
187
187
  }),
188
188
  /* @__PURE__ */ o("td", {
189
- className: "max-w-[120px] truncate px-4 py-3 font-mono text-xs text-text-secondary",
190
- children: n.actorId
189
+ className: "max-w-[140px] truncate px-4 py-3 text-xs capitalize text-text-secondary",
190
+ title: n.actorId,
191
+ children: (n.actorType || "unknown").toLowerCase().replace(/_/g, " ")
191
192
  }),
192
193
  /* @__PURE__ */ o("td", {
193
194
  className: "px-4 py-3",
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLogTable.js","names":[],"sources":["../../../src/components/audit/AuditLogTable.tsx"],"sourcesContent":["import { ChevronRight, Terminal, Trash2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { StatusBadge } from '@/components/shared';\nimport { SelectionCheckbox } from '@/components/shared/SelectionCheckbox';\nimport type { VibeAuditLogFieldsFragment } from '@/generated/wspace-operations';\n\ninterface AuditLogTableProps {\n items: VibeAuditLogFieldsFragment[];\n total: number;\n hasMore: boolean;\n page: number;\n pageSize: number;\n onPageChange: (page: number) => void;\n onSelectLog: (id: string) => void;\n onDeleteLog: (id: string) => void;\n selectedLogId: string | null;\n selectedLogIds: Set<string>;\n allVisibleSelected: boolean;\n partiallySelected: boolean;\n onToggleLogSelection: (id: string, checked: boolean) => void;\n onToggleAllVisible: (checked: boolean) => void;\n}\n\nconst statusVariantMap: Record<string, 'success' | 'error' | 'warning' | 'info'> = {\n SUCCESS: 'success',\n FAILURE: 'error',\n DENIED: 'warning',\n ERROR: 'error',\n};\n\nconst actionColors: Record<string, string> = {\n CREATE: 'bg-status-success-bg text-status-success-text',\n UPDATE: 'bg-status-info-bg text-status-info-text',\n DELETE: 'bg-status-error-bg text-status-error-text',\n EXECUTE: 'bg-action-primary-bg/15 text-action-primary-text',\n EXPORT: 'bg-status-warning-bg text-status-warning-text',\n SHARE: 'bg-status-success-bg text-status-success-text',\n REVOKE: 'bg-status-warning-bg text-status-warning-text',\n ARCHIVE: 'bg-bg-muted text-text-secondary',\n RESTORE: 'bg-status-info-bg text-status-info-text',\n};\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatResourceType(type: string): string {\n return type\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n}\n\nexport function AuditLogTable({\n items,\n total,\n hasMore,\n page,\n pageSize,\n onPageChange,\n onSelectLog,\n onDeleteLog,\n selectedLogId,\n selectedLogIds,\n allVisibleSelected,\n partiallySelected,\n onToggleLogSelection,\n onToggleAllVisible,\n}: AuditLogTableProps) {\n const { t } = useI18n();\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n const tr = (key: string, fallback: string) => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div>\n <div className=\"space-y-3 md:hidden\">\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <article\n key={item.id}\n className={`rounded-lg border border-border-primary p-4 transition-colors ${\n selectedLogId === item.id ? 'bg-bg-secondary/50' : 'bg-bg-surface'\n }`}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n className=\"mt-1\"\n />\n <div className=\"min-w-0\">\n <p className=\"text-xs text-text-secondary\">{formatDate(item.createdAt)}</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">\n {item.resourceName || item.description || '-'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </p>\n </div>\n </div>\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-secondary text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between gap-3\">\n <p className=\"min-w-0 truncate font-mono text-xs text-text-secondary\">\n {item.actorId}\n </p>\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </div>\n <div className=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-primary px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-secondary\"\n >\n View details\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </article>\n );\n })}\n </div>\n\n <div className=\"hidden overflow-x-auto rounded-lg border border-border-primary md:block\">\n <table className=\"w-full min-w-[860px] text-sm\">\n <thead>\n <tr className=\"border-b border-border-primary bg-bg-secondary/50\">\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={onToggleAllVisible}\n ariaLabel=\"Select all visible audit logs\"\n />\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.time', 'Time')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.action', 'Action')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.resource', 'Resource')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.name', 'Name')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.actor', 'Actor')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">\n {tr('audit.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <tr\n key={item.id}\n className={`border-b border-border-primary/50 transition-colors hover:bg-bg-secondary/30 ${\n selectedLogId === item.id ? 'bg-bg-secondary/50' : ''\n }`}\n >\n <td className=\"px-4 py-3 align-top\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n />\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-xs text-text-secondary\">\n {formatDate(item.createdAt)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-secondary text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </td>\n <td className=\"px-4 py-3 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </td>\n <td\n className=\"max-w-[220px] truncate px-4 py-3\"\n title={item.resourceName || item.description || ''}\n >\n {item.resourceName || item.description || '-'}\n </td>\n <td className=\"max-w-[120px] truncate px-4 py-3 font-mono text-xs text-text-secondary\">\n {item.actorId}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </td>\n <td className=\"px-4 py-3 text-right\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-bg-secondary hover:text-text-primary\"\n title={tr('audit.viewAuditLog', 'View details')}\n >\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-4 flex flex-col gap-3 text-sm text-text-secondary sm:flex-row sm:items-center sm:justify-between\">\n <span>\n {tr('audit.showing', 'Showing')} {page * pageSize + 1}-\n {Math.min((page + 1) * pageSize, total)} {tr('audit.of', 'of')} {total}\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n className=\"rounded border border-border-primary px-3 py-1 transition-colors hover:bg-bg-secondary disabled:opacity-50\"\n >\n {tr('audit.previous', 'Previous')}\n </button>\n <span>\n {tr('audit.page', 'Page')} {page + 1} {tr('audit.of', 'of')} {totalPages}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => onPageChange(page + 1)}\n className=\"rounded border border-border-primary px-3 py-1 transition-colors hover:bg-bg-secondary disabled:opacity-50\"\n >\n {tr('audit.next', 'Next')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AuditLogTable.js","names":[],"sources":["../../../src/components/audit/AuditLogTable.tsx"],"sourcesContent":["import { ChevronRight, Terminal, Trash2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { StatusBadge } from '@/components/shared';\nimport { SelectionCheckbox } from '@/components/shared/SelectionCheckbox';\nimport type { VibeAuditLogFieldsFragment } from '@/generated/wspace-operations';\n\ninterface AuditLogTableProps {\n items: VibeAuditLogFieldsFragment[];\n total: number;\n hasMore: boolean;\n page: number;\n pageSize: number;\n onPageChange: (page: number) => void;\n onSelectLog: (id: string) => void;\n onDeleteLog: (id: string) => void;\n selectedLogId: string | null;\n selectedLogIds: Set<string>;\n allVisibleSelected: boolean;\n partiallySelected: boolean;\n onToggleLogSelection: (id: string, checked: boolean) => void;\n onToggleAllVisible: (checked: boolean) => void;\n}\n\nconst statusVariantMap: Record<string, 'success' | 'error' | 'warning' | 'info'> = {\n SUCCESS: 'success',\n FAILURE: 'error',\n DENIED: 'warning',\n ERROR: 'error',\n};\n\nconst actionColors: Record<string, string> = {\n CREATE: 'bg-status-success-bg text-status-success-text',\n UPDATE: 'bg-status-info-bg text-status-info-text',\n DELETE: 'bg-status-error-bg text-status-error-text',\n EXECUTE: 'bg-action-primary-bg/15 text-action-primary-text',\n EXPORT: 'bg-status-warning-bg text-status-warning-text',\n SHARE: 'bg-status-success-bg text-status-success-text',\n REVOKE: 'bg-status-warning-bg text-status-warning-text',\n ARCHIVE: 'bg-bg-muted text-text-secondary',\n RESTORE: 'bg-status-info-bg text-status-info-text',\n};\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatResourceType(type: string): string {\n return type\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n}\n\nexport function AuditLogTable({\n items,\n total,\n hasMore,\n page,\n pageSize,\n onPageChange,\n onSelectLog,\n onDeleteLog,\n selectedLogId,\n selectedLogIds,\n allVisibleSelected,\n partiallySelected,\n onToggleLogSelection,\n onToggleAllVisible,\n}: AuditLogTableProps) {\n const { t } = useI18n();\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n const tr = (key: string, fallback: string) => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div>\n <div className=\"space-y-3 md:hidden\">\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <article\n key={item.id}\n className={`rounded-lg border border-border-primary p-4 transition-colors ${\n selectedLogId === item.id ? 'bg-bg-secondary/50' : 'bg-bg-surface'\n }`}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n className=\"mt-1\"\n />\n <div className=\"min-w-0\">\n <p className=\"text-xs text-text-secondary\">{formatDate(item.createdAt)}</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">\n {item.resourceName || item.description || '-'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </p>\n </div>\n </div>\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-secondary text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between gap-3\">\n <p className=\"min-w-0 truncate text-xs capitalize text-text-secondary\">\n {(item.actorType || 'unknown')\n .toLowerCase()\n .replace(/_/g, ' ')}\n {item.resourceName ? ` · ${item.resourceName}` : ''}\n </p>\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </div>\n <div className=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-primary px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-secondary\"\n >\n View details\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </article>\n );\n })}\n </div>\n\n <div className=\"hidden overflow-x-auto rounded-lg border border-border-primary md:block\">\n <table className=\"w-full min-w-[860px] text-sm\">\n <thead>\n <tr className=\"border-b border-border-primary bg-bg-secondary/50\">\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={onToggleAllVisible}\n ariaLabel=\"Select all visible audit logs\"\n />\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.time', 'Time')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.action', 'Action')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.resource', 'Resource')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.name', 'Name')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.actor', 'Actor')}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n {tr('audit.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">\n {tr('audit.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <tr\n key={item.id}\n className={`border-b border-border-primary/50 transition-colors hover:bg-bg-secondary/30 ${\n selectedLogId === item.id ? 'bg-bg-secondary/50' : ''\n }`}\n >\n <td className=\"px-4 py-3 align-top\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n />\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-xs text-text-secondary\">\n {formatDate(item.createdAt)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-secondary text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </td>\n <td className=\"px-4 py-3 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </td>\n <td\n className=\"max-w-[220px] truncate px-4 py-3\"\n title={item.resourceName || item.description || ''}\n >\n {item.resourceName || item.description || '-'}\n </td>\n <td\n className=\"max-w-[140px] truncate px-4 py-3 text-xs capitalize text-text-secondary\"\n title={item.actorId}\n >\n {(item.actorType || 'unknown')\n .toLowerCase()\n .replace(/_/g, ' ')}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </td>\n <td className=\"px-4 py-3 text-right\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-bg-secondary hover:text-text-primary\"\n title={tr('audit.viewAuditLog', 'View details')}\n >\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-4 flex flex-col gap-3 text-sm text-text-secondary sm:flex-row sm:items-center sm:justify-between\">\n <span>\n {tr('audit.showing', 'Showing')} {page * pageSize + 1}-\n {Math.min((page + 1) * pageSize, total)} {tr('audit.of', 'of')} {total}\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n className=\"rounded border border-border-primary px-3 py-1 transition-colors hover:bg-bg-secondary disabled:opacity-50\"\n >\n {tr('audit.previous', 'Previous')}\n </button>\n <span>\n {tr('audit.page', 'Page')} {page + 1} {tr('audit.of', 'of')} {totalPages}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => onPageChange(page + 1)}\n className=\"rounded border border-border-primary px-3 py-1 transition-colors hover:bg-bg-secondary disabled:opacity-50\"\n >\n {tr('audit.next', 'Next')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -4,11 +4,11 @@ import { getQuotaDialogContent as n, isQuotaExhaustedError as r, markQuotaHandle
4
4
  import { useCreateActionMutation as ee, useDeleteActionMutation as a, useDuplicateActionMutation as o, useExecuteActionMutation as te, useGetActionQuery as ne, useListActionsQuery as re, useListAgentsQuery as ie, useUpdateActionMutation as ae } from "../generated/wspace-operations.js";
5
5
  import { useVibeControls as oe } from "../providers/VibeControlsProvider.js";
6
6
  import { PageHeader as se } from "../components/shared/PageHeader.js";
7
- import { LoadingState as ce } from "../components/shared/LoadingState.js";
8
- import { ErrorState as le } from "../components/shared/ErrorState.js";
9
- import { EntityTagPicker as s } from "../components/shared/EntityTagPicker.js";
10
- import { useDraftEntityTags as ue } from "../hooks/useDraftEntityTags.js";
11
- import { isNative as c, nativeNotify as l } from "../utils/nativeBridge.js";
7
+ import { LoadingState as s } from "../components/shared/LoadingState.js";
8
+ import { ErrorState as ce } from "../components/shared/ErrorState.js";
9
+ import { EntityTagPicker as c } from "../components/shared/EntityTagPicker.js";
10
+ import { useDraftEntityTags as le } from "../hooks/useDraftEntityTags.js";
11
+ import { isNative as l, nativeNotify as ue } from "../utils/nativeBridge.js";
12
12
  import { EmptyState as de } from "../components/shared/EmptyState.js";
13
13
  import { SearchInput as fe } from "../components/shared/SearchInput.js";
14
14
  import { FilterDropdown as pe } from "../components/shared/FilterDropdown.js";
@@ -101,7 +101,7 @@ function v() {
101
101
  id: e.id,
102
102
  name: e.name,
103
103
  isActive: e.isActive
104
- })), [qe]), [Ye, { loading: Xe }] = ee({ refetchQueries: ["ListActions"] }), { setDraftTagIds: Ze, flushTags: Qe } = ue("VIBECONTROLS_ACTION"), [$e, { loading: et }] = ae({ refetchQueries: ["ListActions", "GetAction"] }), [q] = a({ refetchQueries: ["ListActions"] }), [J] = te({ refetchQueries: ["GetAction"] }), [Y] = o({ refetchQueries: ["ListActions"] }), tt = d(async (e) => {
104
+ })), [qe]), [Ye, { loading: Xe }] = ee({ refetchQueries: ["ListActions"] }), { setDraftTagIds: Ze, flushTags: Qe } = le("VIBECONTROLS_ACTION"), [$e, { loading: et }] = ae({ refetchQueries: ["ListActions", "GetAction"] }), [q] = a({ refetchQueries: ["ListActions"] }), [J] = te({ refetchQueries: ["GetAction"] }), [Y] = o({ refetchQueries: ["ListActions"] }), tt = d(async (e) => {
105
105
  try {
106
106
  let t = await Ye({ variables: { input: {
107
107
  name: e.name,
@@ -177,9 +177,9 @@ function v() {
177
177
  U
178
178
  ]), rt = d(async () => {
179
179
  if (D.type === "confirmDelete") try {
180
- await q({ variables: { id: D.id } }), P === D.id && F(null), O({ type: "none" }), U("Action deleted", "success"), c() && l("success");
180
+ await q({ variables: { id: D.id } }), P === D.id && F(null), O({ type: "none" }), U("Action deleted", "success"), l() && ue("success");
181
181
  } catch (e) {
182
- U(e instanceof Error ? e.message : "Failed to delete action", "error"), c() && l("error");
182
+ U(e instanceof Error ? e.message : "Failed to delete action", "error"), l() && ue("error");
183
183
  }
184
184
  }, [
185
185
  D,
@@ -325,7 +325,7 @@ function v() {
325
325
  P,
326
326
  W
327
327
  ]);
328
- return !x && S && S.permissionStrings?.length > 0 && !je ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(Oe, {}) }) : Ue ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(ce, { message: "Loading Actions..." }) }) : We ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(le, {
328
+ return x ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(s, { message: "Loading Actions..." }) }) : S && S.permissionStrings?.length > 0 && !je ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(Oe, {}) }) : Ue ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(s, { message: "Loading Actions..." }) }) : We ? /* @__PURE__ */ h(_, { children: /* @__PURE__ */ h(ce, {
329
329
  message: We.message,
330
330
  onRetry: () => W()
331
331
  }) }) : /* @__PURE__ */ g(_, {
@@ -540,7 +540,7 @@ function v() {
540
540
  extraSection: /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h3", {
541
541
  className: "text-sm font-medium text-text-secondary mb-2",
542
542
  children: C("actions.tags", "Tags")
543
- }), /* @__PURE__ */ h(s, {
543
+ }), /* @__PURE__ */ h(c, {
544
544
  entityType: "VIBECONTROLS_ACTION",
545
545
  onDraftChange: Ze
546
546
  })] })
@@ -576,7 +576,7 @@ function v() {
576
576
  extraSection: /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h3", {
577
577
  className: "text-sm font-medium text-text-secondary mb-2",
578
578
  children: C("actions.tags", "Tags")
579
- }), /* @__PURE__ */ h(s, {
579
+ }), /* @__PURE__ */ h(c, {
580
580
  entityType: "VIBECONTROLS_ACTION",
581
581
  entityId: Z.id
582
582
  })] })