@datum-cloud/activity-ui 0.5.1 → 0.6.0-dev.917556e

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 (74) hide show
  1. package/README.md +14 -0
  2. package/dist/components/ActionMultiSelect.d.ts.map +1 -1
  3. package/dist/components/ActivityDigestSummary.d.ts +15 -0
  4. package/dist/components/ActivityDigestSummary.d.ts.map +1 -0
  5. package/dist/components/ActivityFeed.d.ts +11 -2
  6. package/dist/components/ActivityFeed.d.ts.map +1 -1
  7. package/dist/components/ActivityFeedFilters.d.ts +9 -1
  8. package/dist/components/ActivityFeedFilters.d.ts.map +1 -1
  9. package/dist/components/ActivityFeedGroupItem.d.ts +23 -0
  10. package/dist/components/ActivityFeedGroupItem.d.ts.map +1 -0
  11. package/dist/components/ActivityFeedItem.d.ts +8 -1
  12. package/dist/components/ActivityFeedItem.d.ts.map +1 -1
  13. package/dist/components/AuditLogFeedItem.d.ts.map +1 -1
  14. package/dist/components/CelEditor.d.ts +1 -1
  15. package/dist/components/CelEditor.d.ts.map +1 -1
  16. package/dist/components/ChangeSourceToggle.d.ts.map +1 -1
  17. package/dist/components/DateTimeRangePicker.d.ts.map +1 -1
  18. package/dist/components/EventFeedItem.d.ts.map +1 -1
  19. package/dist/components/EventTypeToggle.d.ts.map +1 -1
  20. package/dist/components/FilterBuilder.d.ts.map +1 -1
  21. package/dist/components/FilterBuilderWithAutocomplete.d.ts.map +1 -1
  22. package/dist/components/PolicyDetailView.d.ts.map +1 -1
  23. package/dist/components/PolicyEditView.d.ts.map +1 -1
  24. package/dist/components/PolicyEditor.d.ts.map +1 -1
  25. package/dist/components/UserSelect.d.ts.map +1 -1
  26. package/dist/components/VerbToggle.d.ts.map +1 -1
  27. package/dist/components/ui/add-filter-dropdown.d.ts.map +1 -1
  28. package/dist/components/ui/combobox.d.ts +0 -4
  29. package/dist/components/ui/combobox.d.ts.map +1 -1
  30. package/dist/components/ui/filter-chip.d.ts.map +1 -1
  31. package/dist/components/ui/multi-combobox.d.ts +2 -5
  32. package/dist/components/ui/multi-combobox.d.ts.map +1 -1
  33. package/dist/components/ui/segmented-toggle.d.ts +26 -0
  34. package/dist/components/ui/segmented-toggle.d.ts.map +1 -0
  35. package/dist/components/ui/time-range-dropdown.d.ts +13 -4
  36. package/dist/components/ui/time-range-dropdown.d.ts.map +1 -1
  37. package/dist/hooks/useActivityFeed.d.ts.map +1 -1
  38. package/dist/hooks/useAuditLogQuery.d.ts +1 -1
  39. package/dist/hooks/useAuditLogQuery.d.ts.map +1 -1
  40. package/dist/index.d.ts +6 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.esm.js +1664 -1352
  43. package/dist/index.esm.js.map +1 -1
  44. package/dist/index.js +1597 -1282
  45. package/dist/index.js.map +1 -1
  46. package/dist/lib/groupActivities.d.ts +40 -0
  47. package/dist/lib/groupActivities.d.ts.map +1 -0
  48. package/dist/lib/verb.d.ts +22 -0
  49. package/dist/lib/verb.d.ts.map +1 -0
  50. package/package.json +7 -12
  51. package/dist/components/ui/alert.d.ts +0 -9
  52. package/dist/components/ui/alert.d.ts.map +0 -1
  53. package/dist/components/ui/button.d.ts +0 -12
  54. package/dist/components/ui/button.d.ts.map +0 -1
  55. package/dist/components/ui/card.d.ts +0 -9
  56. package/dist/components/ui/card.d.ts.map +0 -1
  57. package/dist/components/ui/checkbox.d.ts +0 -5
  58. package/dist/components/ui/checkbox.d.ts.map +0 -1
  59. package/dist/components/ui/input.d.ts +0 -6
  60. package/dist/components/ui/input.d.ts.map +0 -1
  61. package/dist/components/ui/label.d.ts +0 -8
  62. package/dist/components/ui/label.d.ts.map +0 -1
  63. package/dist/components/ui/select.d.ts +0 -14
  64. package/dist/components/ui/select.d.ts.map +0 -1
  65. package/dist/components/ui/separator.d.ts +0 -5
  66. package/dist/components/ui/separator.d.ts.map +0 -1
  67. package/dist/components/ui/sheet.d.ts +0 -23
  68. package/dist/components/ui/sheet.d.ts.map +0 -1
  69. package/dist/components/ui/skeleton.d.ts +0 -3
  70. package/dist/components/ui/skeleton.d.ts.map +0 -1
  71. package/dist/components/ui/tabs.d.ts +0 -8
  72. package/dist/components/ui/tabs.d.ts.map +0 -1
  73. package/dist/components/ui/textarea.d.ts +0 -6
  74. package/dist/components/ui/textarea.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -9,9 +9,12 @@ var label = require('@datum-cloud/datum-ui/label');
9
9
  var separator = require('@datum-cloud/datum-ui/separator');
10
10
  var textarea = require('@datum-cloud/datum-ui/textarea');
11
11
  var badge = require('@datum-cloud/datum-ui/badge');
12
- var cmdk = require('cmdk');
13
- var Popover = require('@radix-ui/react-popover');
12
+ var autocomplete = require('@datum-cloud/datum-ui/autocomplete');
14
13
  var checkbox = require('@datum-cloud/datum-ui/checkbox');
14
+ var picker = require('@datum-cloud/datum-ui/picker');
15
+ var command = require('@datum-cloud/datum-ui/command');
16
+ var popover = require('@datum-cloud/datum-ui/popover');
17
+ var buttonGroup = require('@datum-cloud/datum-ui/button-group');
15
18
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
16
19
  var table = require('@datum-cloud/datum-ui/table');
17
20
  var skeleton = require('@datum-cloud/datum-ui/skeleton');
@@ -20,6 +23,7 @@ var select = require('@datum-cloud/datum-ui/select');
20
23
  var sheet = require('@datum-cloud/datum-ui/sheet');
21
24
  var tabs = require('@datum-cloud/datum-ui/tabs');
22
25
  var dialog = require('@datum-cloud/datum-ui/dialog');
26
+ var multiSelect = require('@datum-cloud/datum-ui/multi-select');
23
27
 
24
28
  function _interopNamespaceDefault(e) {
25
29
  var n = Object.create(null);
@@ -39,7 +43,6 @@ function _interopNamespaceDefault(e) {
39
43
  }
40
44
 
41
45
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
42
- var Popover__namespace = /*#__PURE__*/_interopNamespaceDefault(Popover);
43
46
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TooltipPrimitive);
44
47
 
45
48
  /**
@@ -213,7 +216,7 @@ function FilterBuilder({ onFilterChange, initialFilter = '', initialLimit = 100,
213
216
  const newFilter = filter ? `${filter} && ${example}` : example;
214
217
  handleFilterChange(newFilter);
215
218
  };
216
- return (jsxRuntime.jsxs(card.Card, { className: `mb-6 ${className}`, children: [jsxRuntime.jsx(card.CardHeader, { className: "pb-4", children: jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsx("h3", { className: "m-0 text-2xl font-semibold text-foreground", children: "Build Your Query" }), jsxRuntime.jsxs(button.Button, { onClick: () => setShowHelp(!showHelp), type: "tertiary", theme: "outline", htmlType: "button", children: [showHelp ? 'Hide' : 'Show', " Help"] })] }) }), jsxRuntime.jsx(separator.Separator, {}), jsxRuntime.jsxs(card.CardContent, { className: "pt-6", children: [showHelp && (jsxRuntime.jsxs("div", { className: "bg-muted p-6 rounded-lg mb-6 max-h-[400px] overflow-y-auto border border-border", children: [jsxRuntime.jsx("h4", { className: "text-base font-semibold text-foreground", children: "Available Filter Fields" }), jsxRuntime.jsx("div", { className: "mt-4", children: FILTER_FIELDS.map((field) => (jsxRuntime.jsxs("div", { className: "mb-6 pb-4 border-b border-border last:border-b-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: field.name }), jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground italic", children: field.type })] }), jsxRuntime.jsx("p", { className: "my-2 text-muted-foreground", children: field.description }), field.examples && field.examples.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Examples:" }), field.examples.map((example, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 my-2", children: [jsxRuntime.jsx("code", { className: "flex-1 px-2 py-1 bg-background rounded text-sm font-mono", children: example }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample(example), type: "primary", theme: "solid", size: "small", className: "bg-green-600 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-600", htmlType: "button", children: "Insert" })] }, idx)))] }))] }, field.name))) }), jsxRuntime.jsxs("div", { className: "mt-4", children: [jsxRuntime.jsx("h4", { className: "mb-2 text-base font-semibold text-foreground", children: "Common Operators" }), jsxRuntime.jsxs("ul", { className: "m-0 pl-6 text-muted-foreground", children: [jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "==" }), " - Equals"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "!=" }), " - Not equals"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "&&" }), " - And"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "||" }), " - Or"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "in" }), " - In list (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "verb in [\"create\", \"delete\"]" }), ")"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: ".startsWith()" }), " - String starts with"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: ".contains()" }), " - String contains"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "timestamp()" }), " - Parse timestamp (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "timestamp(\"2024-01-01T00:00:00Z\")" }), ")"] })] })] })] })), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx(label.Label, { htmlFor: "filter-input", className: "block mb-2", children: "CEL Filter Expression" }), jsxRuntime.jsx(textarea.Textarea, { id: "filter-input", value: filter, onChange: (e) => handleFilterChange(e.target.value), placeholder: 'e.g., verb == "delete" && ns == "production"', rows: 4, className: "font-mono text-sm resize-y" })] }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx(label.Label, { htmlFor: "limit-input", className: "block mb-2", children: "Result Limit (max 1,000)" }), jsxRuntime.jsx(input.Input, { id: "limit-input", type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-44" })] }), jsxRuntime.jsx(separator.Separator, { className: "my-6" }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h4", { className: "mb-3 text-base font-semibold text-foreground", children: "Quick Filters" }), jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [jsxRuntime.jsx(button.Button, { onClick: () => insertExample('verb == "delete"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Delete Operations" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('resource == "secrets"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Secret Access" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('user.startsWith("system:")'), htmlType: "button", type: "tertiary", theme: "outline", children: "System Users" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('stage == "ResponseComplete"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Completed Requests" })] })] })] })] }));
219
+ return (jsxRuntime.jsxs(card.Card, { className: `mb-6 ${className}`, children: [jsxRuntime.jsx(card.CardHeader, { className: "pb-4", children: jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsx("h3", { className: "m-0 text-2xl font-semibold text-foreground", children: "Build Your Query" }), jsxRuntime.jsxs(button.Button, { onClick: () => setShowHelp(!showHelp), type: "tertiary", theme: "outline", htmlType: "button", children: [showHelp ? 'Hide' : 'Show', " Help"] })] }) }), jsxRuntime.jsx(separator.Separator, {}), jsxRuntime.jsxs(card.CardContent, { className: "pt-6", children: [showHelp && (jsxRuntime.jsxs("div", { className: "bg-muted p-6 rounded-lg mb-6 max-h-[400px] overflow-y-auto border border-border", children: [jsxRuntime.jsx("h4", { className: "text-base font-semibold text-foreground", children: "Available Filter Fields" }), jsxRuntime.jsx("div", { className: "mt-4", children: FILTER_FIELDS.map((field) => (jsxRuntime.jsxs("div", { className: "mb-6 pb-4 border-b border-border last:border-b-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: field.name }), jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground italic", children: field.type })] }), jsxRuntime.jsx("p", { className: "my-2 text-muted-foreground", children: field.description }), field.examples && field.examples.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Examples:" }), field.examples.map((example, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 my-2", children: [jsxRuntime.jsx("code", { className: "flex-1 px-2 py-1 bg-background rounded text-sm font-mono", children: example }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample(example), type: "success", theme: "solid", size: "small", htmlType: "button", children: "Insert" })] }, idx)))] }))] }, field.name))) }), jsxRuntime.jsxs("div", { className: "mt-4", children: [jsxRuntime.jsx("h4", { className: "mb-2 text-base font-semibold text-foreground", children: "Common Operators" }), jsxRuntime.jsxs("ul", { className: "m-0 pl-6 text-muted-foreground", children: [jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "==" }), " - Equals"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "!=" }), " - Not equals"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "&&" }), " - And"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "||" }), " - Or"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "in" }), " - In list (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "verb in [\"create\", \"delete\"]" }), ")"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: ".startsWith()" }), " - String starts with"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: ".contains()" }), " - String contains"] }), jsxRuntime.jsxs("li", { className: "my-1", children: [jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "timestamp()" }), " - Parse timestamp (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-background rounded text-sm font-mono", children: "timestamp(\"2024-01-01T00:00:00Z\")" }), ")"] })] })] })] })), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx(label.Label, { htmlFor: "filter-input", className: "block mb-2", children: "CEL Filter Expression" }), jsxRuntime.jsx(textarea.Textarea, { id: "filter-input", value: filter, onChange: (e) => handleFilterChange(e.target.value), placeholder: 'e.g., verb == "delete" && ns == "production"', rows: 4, className: "font-mono text-sm resize-y" })] }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx(label.Label, { htmlFor: "limit-input", className: "block mb-2", children: "Result Limit (max 1,000)" }), jsxRuntime.jsx(input.Input, { id: "limit-input", type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-44" })] }), jsxRuntime.jsx(separator.Separator, { className: "my-6" }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h4", { className: "mb-3 text-base font-semibold text-foreground", children: "Quick Filters" }), jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [jsxRuntime.jsx(button.Button, { onClick: () => insertExample('verb == "delete"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Delete Operations" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('resource == "secrets"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Secret Access" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('user.startsWith("system:")'), htmlType: "button", type: "tertiary", theme: "outline", children: "System Users" }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample('stage == "ResponseComplete"'), htmlType: "button", type: "tertiary", theme: "outline", children: "Completed Requests" })] })] })] })] }));
217
220
  }
218
221
 
219
222
  function mapVariant(variant) {
@@ -322,7 +325,7 @@ function FilterBuilderWithAutocomplete({ onFilterChange, initialFilter = '', ini
322
325
  // Suggest logical operators to continue
323
326
  const completedValuePattern = /["'][^"']*["']\s*$/;
324
327
  const completedNumberPattern = /\d+\s*$/;
325
- const afterLogicalOp = /(\&\&|\|\|)\s*$/;
328
+ const afterLogicalOp = /(&&|\|\|)\s*$/;
326
329
  if ((completedValuePattern.test(textBeforeCursor) || completedNumberPattern.test(textBeforeCursor)) && !afterLogicalOp.test(textBeforeCursor)) {
327
330
  // After a complete value, suggest logical operators
328
331
  newSuggestions.push({ text: ' && ', description: 'Logical AND - add another condition', type: 'operator' }, { text: ' || ', description: 'Logical OR - add alternative condition', type: 'operator' });
@@ -447,7 +450,7 @@ function FilterBuilderWithAutocomplete({ onFilterChange, initialFilter = '', ini
447
450
  return 'outline';
448
451
  }
449
452
  };
450
- return (jsxRuntime.jsxs(card.Card, { className: `p-8 rounded-xl mb-6 ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-0 mb-6 pb-4 border-b border-border", children: [jsxRuntime.jsx("h3", { className: "m-0 text-2xl font-semibold text-foreground", children: "Search Audit Logs" }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [jsxRuntime.jsx(button.Button, { onClick: () => setShowShortcuts(!showShortcuts), type: "tertiary", theme: "outline", size: "small", htmlType: "button", title: "View keyboard shortcuts", children: "Shortcuts" }), jsxRuntime.jsx(button.Button, { onClick: () => setShowHelp(!showHelp), type: "tertiary", theme: "outline", size: "small", htmlType: "button", title: "View available filter fields and examples", children: "Field Guide" })] })] }), jsxRuntime.jsxs(card.CardContent, { className: "p-0", children: [showShortcuts && (jsxRuntime.jsxs("div", { className: "bg-blue-50 border border-blue-500 dark:bg-blue-950/50 dark:border-blue-700 p-6 rounded-lg mb-6 max-h-96 overflow-y-auto", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-4 text-lg font-semibold text-foreground", children: "Keyboard Shortcuts" }), jsxRuntime.jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-x-6 gap-y-3 items-start", children: [jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Ctrl+Space" }), jsxRuntime.jsx("span", { children: "Trigger autocomplete suggestions at cursor position" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "\u2191 / \u2193" }), jsxRuntime.jsx("span", { children: "Navigate through autocomplete suggestions" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Tab" }), jsxRuntime.jsx("span", { children: "Accept the selected suggestion" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Enter" }), jsxRuntime.jsx("span", { children: "Accept the selected suggestion" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Esc" }), jsxRuntime.jsx("span", { children: "Close autocomplete suggestions" })] }), jsxRuntime.jsxs("div", { className: "mt-4 p-3 bg-background rounded text-sm", children: [jsxRuntime.jsx("strong", { children: "Pro Tips:" }), jsxRuntime.jsxs("ul", { className: "mt-2 mb-0 pl-6", children: [jsxRuntime.jsx("li", { children: "Autocomplete appears automatically as you type" }), jsxRuntime.jsxs("li", { children: ["After completing a value (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "\"get\"" }), "), suggestions show logical operators (", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "&&" }), ", ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "||" }), ")"] }), jsxRuntime.jsxs("li", { children: ["After typing ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "&&" }), " or ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "||" }), ", all field names are suggested"] }), jsxRuntime.jsxs("li", { children: ["Type ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "." }), " after a field name to see available string functions"] })] })] })] })), showHelp && (jsxRuntime.jsxs("div", { className: "bg-muted p-6 rounded-lg mb-6 max-h-96 overflow-y-auto", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-4 text-lg font-semibold text-foreground", children: "Available Fields & Examples" }), jsxRuntime.jsx("p", { className: "mb-4 text-muted-foreground text-sm", children: "Click \"Insert\" to add an example to your query" }), jsxRuntime.jsx("div", { className: "mt-4", children: FILTER_FIELDS.map((field) => (jsxRuntime.jsxs("div", { className: "mb-6 pb-4 border-b border-border last:border-b-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: field.name }), jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground italic", children: field.type })] }), jsxRuntime.jsx("p", { className: "my-2 text-muted-foreground", children: field.description }), field.examples && field.examples.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2", children: [jsxRuntime.jsx("strong", { className: "text-sm text-foreground", children: "Examples:" }), field.examples.map((example, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 my-2", children: [jsxRuntime.jsx("code", { className: "flex-1 px-2 py-1 bg-background rounded text-sm font-mono", children: example }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample(example), type: "primary", theme: "solid", size: "small", htmlType: "button", className: "bg-green-600 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-600", children: "Insert" })] }, idx)))] }))] }, field.name))) })] })), jsxRuntime.jsxs("div", { className: "relative mb-4", children: [jsxRuntime.jsxs(label.Label, { htmlFor: "filter-input", className: "block mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Filter Expression" }), jsxRuntime.jsx("span", { className: "ml-2 text-sm text-muted-foreground font-normal", children: "Press Ctrl+Space for suggestions" })] }), jsxRuntime.jsx("p", { className: "m-0 mb-3 text-sm text-muted-foreground", children: "Use autocomplete to build your query, or type field names directly (e.g., verb, objectRef.resource)" }), jsxRuntime.jsx(textarea.Textarea, { ref: textareaRef, id: "filter-input", value: filter, onChange: (e) => handleFilterChange(e.target.value), onKeyDown: handleKeyDown, onFocus: () => updateSuggestions(filter), placeholder: 'Example: verb == "delete" && objectRef.namespace == "production"', rows: 4, className: "font-mono text-sm bg-muted resize-y focus:bg-background" }), showSuggestions && suggestions.length > 0 && (jsxRuntime.jsx("div", { className: "absolute top-full left-0 right-0 max-h-72 overflow-y-auto bg-background border border-input border-t-0 rounded-b shadow-md z-50 -mt-1", children: suggestions.map((suggestion, idx) => (jsxRuntime.jsxs("div", { className: `px-4 py-3 cursor-pointer flex items-center gap-3 border-b border-border transition-colors ${idx === selectedSuggestion ? 'bg-pink-100' : 'hover:bg-muted'}`, onClick: () => insertSuggestion(suggestion), onMouseEnter: () => setSelectedSuggestion(idx), children: [jsxRuntime.jsx("span", { className: "font-mono font-semibold text-foreground min-w-[120px]", children: suggestion.text }), jsxRuntime.jsx("span", { className: "flex-1 text-muted-foreground text-sm", children: suggestion.description }), jsxRuntime.jsx(Badge, { variant: getBadgeVariant(suggestion.type), className: "uppercase", children: suggestion.type })] }, idx))) }))] }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsxs(label.Label, { htmlFor: "limit-input", className: "block mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Number of results" }), jsxRuntime.jsx("span", { className: "ml-2 text-sm text-muted-foreground font-normal", children: "(1 to 1,000 events)" })] }), jsxRuntime.jsx(input.Input, { id: "limit-input", type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-44 bg-muted focus:bg-background" })] })] })] }));
453
+ return (jsxRuntime.jsxs(card.Card, { className: `p-8 rounded-xl mb-6 ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-0 mb-6 pb-4 border-b border-border", children: [jsxRuntime.jsx("h3", { className: "m-0 text-2xl font-semibold text-foreground", children: "Search Audit Logs" }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [jsxRuntime.jsx(button.Button, { onClick: () => setShowShortcuts(!showShortcuts), type: "tertiary", theme: "outline", size: "small", htmlType: "button", title: "View keyboard shortcuts", children: "Shortcuts" }), jsxRuntime.jsx(button.Button, { onClick: () => setShowHelp(!showHelp), type: "tertiary", theme: "outline", size: "small", htmlType: "button", title: "View available filter fields and examples", children: "Field Guide" })] })] }), jsxRuntime.jsxs(card.CardContent, { className: "p-0", children: [showShortcuts && (jsxRuntime.jsxs("div", { className: "bg-[var(--info-100)] border border-[var(--info-300)] p-6 rounded-lg mb-6 max-h-96 overflow-y-auto", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-4 text-lg font-semibold text-foreground", children: "Keyboard Shortcuts" }), jsxRuntime.jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-x-6 gap-y-3 items-start", children: [jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Ctrl+Space" }), jsxRuntime.jsx("span", { children: "Trigger autocomplete suggestions at cursor position" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "\u2191 / \u2193" }), jsxRuntime.jsx("span", { children: "Navigate through autocomplete suggestions" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Tab" }), jsxRuntime.jsx("span", { children: "Accept the selected suggestion" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Enter" }), jsxRuntime.jsx("span", { children: "Accept the selected suggestion" }), jsxRuntime.jsx("kbd", { className: "px-2 py-1 bg-background border border-input rounded font-mono text-sm", children: "Esc" }), jsxRuntime.jsx("span", { children: "Close autocomplete suggestions" })] }), jsxRuntime.jsxs("div", { className: "mt-4 p-3 bg-background rounded text-sm", children: [jsxRuntime.jsx("strong", { children: "Pro Tips:" }), jsxRuntime.jsxs("ul", { className: "mt-2 mb-0 pl-6", children: [jsxRuntime.jsx("li", { children: "Autocomplete appears automatically as you type" }), jsxRuntime.jsxs("li", { children: ["After completing a value (e.g., ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "\"get\"" }), "), suggestions show logical operators (", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "&&" }), ", ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "||" }), ")"] }), jsxRuntime.jsxs("li", { children: ["After typing ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "&&" }), " or ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "||" }), ", all field names are suggested"] }), jsxRuntime.jsxs("li", { children: ["Type ", jsxRuntime.jsx("code", { className: "px-1 py-0.5 bg-muted rounded text-sm", children: "." }), " after a field name to see available string functions"] })] })] })] })), showHelp && (jsxRuntime.jsxs("div", { className: "bg-muted p-6 rounded-lg mb-6 max-h-96 overflow-y-auto", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-4 text-lg font-semibold text-foreground", children: "Available Fields & Examples" }), jsxRuntime.jsx("p", { className: "mb-4 text-muted-foreground text-sm", children: "Click \"Insert\" to add an example to your query" }), jsxRuntime.jsx("div", { className: "mt-4", children: FILTER_FIELDS.map((field) => (jsxRuntime.jsxs("div", { className: "mb-6 pb-4 border-b border-border last:border-b-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: field.name }), jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground italic", children: field.type })] }), jsxRuntime.jsx("p", { className: "my-2 text-muted-foreground", children: field.description }), field.examples && field.examples.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2", children: [jsxRuntime.jsx("strong", { className: "text-sm text-foreground", children: "Examples:" }), field.examples.map((example, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 my-2", children: [jsxRuntime.jsx("code", { className: "flex-1 px-2 py-1 bg-background rounded text-sm font-mono", children: example }), jsxRuntime.jsx(button.Button, { onClick: () => insertExample(example), type: "success", theme: "solid", size: "small", htmlType: "button", children: "Insert" })] }, idx)))] }))] }, field.name))) })] })), jsxRuntime.jsxs("div", { className: "relative mb-4", children: [jsxRuntime.jsxs(label.Label, { htmlFor: "filter-input", className: "block mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Filter Expression" }), jsxRuntime.jsx("span", { className: "ml-2 text-sm text-muted-foreground font-normal", children: "Press Ctrl+Space for suggestions" })] }), jsxRuntime.jsx("p", { className: "m-0 mb-3 text-sm text-muted-foreground", children: "Use autocomplete to build your query, or type field names directly (e.g., verb, objectRef.resource)" }), jsxRuntime.jsx(textarea.Textarea, { ref: textareaRef, id: "filter-input", value: filter, onChange: (e) => handleFilterChange(e.target.value), onKeyDown: handleKeyDown, onFocus: () => updateSuggestions(filter), placeholder: 'Example: verb == "delete" && objectRef.namespace == "production"', rows: 4, className: "font-mono text-sm bg-muted resize-y focus:bg-background" }), showSuggestions && suggestions.length > 0 && (jsxRuntime.jsx("div", { className: "absolute top-full left-0 right-0 max-h-72 overflow-y-auto bg-background border border-input border-t-0 rounded-b shadow-md z-50 -mt-1", children: suggestions.map((suggestion, idx) => (jsxRuntime.jsxs("div", { className: `px-4 py-3 cursor-pointer flex items-center gap-3 border-b border-border transition-colors ${idx === selectedSuggestion ? 'bg-accent' : 'hover:bg-muted'}`, onClick: () => insertSuggestion(suggestion), onMouseEnter: () => setSelectedSuggestion(idx), children: [jsxRuntime.jsx("span", { className: "font-mono font-semibold text-foreground min-w-[120px]", children: suggestion.text }), jsxRuntime.jsx("span", { className: "flex-1 text-muted-foreground text-sm", children: suggestion.description }), jsxRuntime.jsx(Badge, { variant: getBadgeVariant(suggestion.type), className: "uppercase", children: suggestion.type })] }, idx))) }))] }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsxs(label.Label, { htmlFor: "limit-input", className: "block mb-2", children: [jsxRuntime.jsx("strong", { className: "text-foreground", children: "Number of results" }), jsxRuntime.jsx("span", { className: "ml-2 text-sm text-muted-foreground font-normal", children: "(1 to 1,000 events)" })] }), jsxRuntime.jsx(input.Input, { id: "limit-input", type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-44 bg-muted focus:bg-background" })] })] })] }));
451
454
  }
452
455
 
453
456
  /**
@@ -1195,6 +1198,48 @@ function constructNow(date) {
1195
1198
  return constructFrom(date, Date.now());
1196
1199
  }
1197
1200
 
1201
+ /**
1202
+ * The {@link isSameDay} function options.
1203
+ */
1204
+
1205
+ /**
1206
+ * @name isSameDay
1207
+ * @category Day Helpers
1208
+ * @summary Are the given dates in the same day (and year and month)?
1209
+ *
1210
+ * @description
1211
+ * Are the given dates in the same day (and year and month)?
1212
+ *
1213
+ * @param laterDate - The first date to check
1214
+ * @param earlierDate - The second date to check
1215
+ * @param options - An object with options
1216
+ *
1217
+ * @returns The dates are in the same day (and year and month)
1218
+ *
1219
+ * @example
1220
+ * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?
1221
+ * const result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))
1222
+ * //=> true
1223
+ *
1224
+ * @example
1225
+ * // Are 4 September and 4 October in the same day?
1226
+ * const result = isSameDay(new Date(2014, 8, 4), new Date(2014, 9, 4))
1227
+ * //=> false
1228
+ *
1229
+ * @example
1230
+ * // Are 4 September, 2014 and 4 September, 2015 in the same day?
1231
+ * const result = isSameDay(new Date(2014, 8, 4), new Date(2015, 8, 4))
1232
+ * //=> false
1233
+ */
1234
+ function isSameDay(laterDate, earlierDate, options) {
1235
+ const [dateLeft_, dateRight_] = normalizeDates(
1236
+ options?.in,
1237
+ laterDate,
1238
+ earlierDate,
1239
+ );
1240
+ return +startOfDay(dateLeft_) === +startOfDay(dateRight_);
1241
+ }
1242
+
1198
1243
  /**
1199
1244
  * @name isDate
1200
1245
  * @category Common Helpers
@@ -3931,6 +3976,36 @@ function formatISO(date, options) {
3931
3976
  return result;
3932
3977
  }
3933
3978
 
3979
+ /**
3980
+ * The {@link isToday} function options.
3981
+ */
3982
+
3983
+ /**
3984
+ * @name isToday
3985
+ * @category Day Helpers
3986
+ * @summary Is the given date today?
3987
+ * @pure false
3988
+ *
3989
+ * @description
3990
+ * Is the given date today?
3991
+ *
3992
+ * @param date - The date to check
3993
+ * @param options - An object with options
3994
+ *
3995
+ * @returns The date is today
3996
+ *
3997
+ * @example
3998
+ * // If today is 6 October 2014, is 6 October 14:00:00 today?
3999
+ * const result = isToday(new Date(2014, 9, 6, 14, 0))
4000
+ * //=> true
4001
+ */
4002
+ function isToday(date, options) {
4003
+ return isSameDay(
4004
+ constructFrom(date, date),
4005
+ constructNow(date),
4006
+ );
4007
+ }
4008
+
3934
4009
  /**
3935
4010
  * The {@link subDays} function options.
3936
4011
  */
@@ -3958,6 +4033,36 @@ function subDays(date, amount, options) {
3958
4033
  return addDays(date, -amount, options);
3959
4034
  }
3960
4035
 
4036
+ /**
4037
+ * The {@link isYesterday} function options.
4038
+ */
4039
+
4040
+ /**
4041
+ * @name isYesterday
4042
+ * @category Day Helpers
4043
+ * @summary Is the given date yesterday?
4044
+ * @pure false
4045
+ *
4046
+ * @description
4047
+ * Is the given date yesterday?
4048
+ *
4049
+ * @param date - The date to check
4050
+ * @param options - An object with options
4051
+ *
4052
+ * @returns The date is yesterday
4053
+ *
4054
+ * @example
4055
+ * // If today is 6 October 2014, is 5 October 14:00:00 yesterday?
4056
+ * const result = isYesterday(new Date(2014, 9, 5, 14, 0))
4057
+ * //=> true
4058
+ */
4059
+ function isYesterday(date, options) {
4060
+ return isSameDay(
4061
+ constructFrom(date, date),
4062
+ subDays(constructNow(date), 1),
4063
+ );
4064
+ }
4065
+
3961
4066
  /**
3962
4067
  * The {@link subHours} function options.
3963
4068
  */
@@ -4018,559 +4123,323 @@ function subMinutes(date, amount, options) {
4018
4123
  return addMinutes(date, -15, options);
4019
4124
  }
4020
4125
 
4021
- /**
4022
- * @license lucide-react v0.577.0 - ISC
4023
- *
4024
- * This source code is licensed under the ISC license.
4025
- * See the LICENSE file in the root directory of this source tree.
4026
- */
4027
-
4028
- const mergeClasses = (...classes) => classes.filter((className, index, array) => {
4029
- return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
4030
- }).join(" ").trim();
4031
-
4032
- /**
4033
- * @license lucide-react v0.577.0 - ISC
4034
- *
4035
- * This source code is licensed under the ISC license.
4036
- * See the LICENSE file in the root directory of this source tree.
4037
- */
4038
-
4039
- const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
4040
-
4041
- /**
4042
- * @license lucide-react v0.577.0 - ISC
4043
- *
4044
- * This source code is licensed under the ISC license.
4045
- * See the LICENSE file in the root directory of this source tree.
4046
- */
4047
-
4048
- const toCamelCase = (string) => string.replace(
4049
- /^([A-Z])|[\s-_]+(\w)/g,
4050
- (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
4051
- );
4052
-
4053
- /**
4054
- * @license lucide-react v0.577.0 - ISC
4055
- *
4056
- * This source code is licensed under the ISC license.
4057
- * See the LICENSE file in the root directory of this source tree.
4058
- */
4059
-
4060
-
4061
- const toPascalCase = (string) => {
4062
- const camelCase = toCamelCase(string);
4063
- return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
4064
- };
4065
-
4066
- /**
4067
- * @license lucide-react v0.577.0 - ISC
4068
- *
4069
- * This source code is licensed under the ISC license.
4070
- * See the LICENSE file in the root directory of this source tree.
4071
- */
4072
-
4073
- var defaultAttributes = {
4074
- xmlns: "http://www.w3.org/2000/svg",
4075
- width: 24,
4076
- height: 24,
4077
- viewBox: "0 0 24 24",
4078
- fill: "none",
4079
- stroke: "currentColor",
4080
- strokeWidth: 2,
4081
- strokeLinecap: "round",
4082
- strokeLinejoin: "round"
4083
- };
4084
-
4085
- /**
4086
- * @license lucide-react v0.577.0 - ISC
4087
- *
4088
- * This source code is licensed under the ISC license.
4089
- * See the LICENSE file in the root directory of this source tree.
4090
- */
4091
-
4092
- const hasA11yProp = (props) => {
4093
- for (const prop in props) {
4094
- if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
4095
- return true;
4096
- }
4097
- }
4098
- return false;
4099
- };
4126
+ /** Sentinel for the "All" item; the public value stays '' for "no filter". */
4127
+ const ALL_VALUE = '__all__';
4128
+ function Combobox({ options, value, onValueChange, placeholder = 'Select…', searchPlaceholder = 'Search…', emptyMessage = 'No results', disabled, loading, className, clearable = false, showAllOption = true, allOptionLabel = 'All', }) {
4129
+ const items = React__namespace.useMemo(() => {
4130
+ const base = options.map((o) => ({ value: o.value, label: o.label, count: o.count }));
4131
+ return showAllOption ? [{ value: ALL_VALUE, label: allOptionLabel }, ...base] : base;
4132
+ }, [options, showAllOption, allOptionLabel]);
4133
+ // An empty value selects the "All" item so the trigger reads its label.
4134
+ const selectedValue = value === '' && showAllOption ? ALL_VALUE : value;
4135
+ return (jsxRuntime.jsx(autocomplete.Autocomplete, { className: className, options: items, value: selectedValue, onValueChange: (next) => onValueChange(next === ALL_VALUE ? '' : next), placeholder: placeholder, searchPlaceholder: searchPlaceholder, emptyContent: emptyMessage, disabled: disabled, loading: loading, footer: clearable && value ? (jsxRuntime.jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground w-full px-2 py-1.5 text-left text-xs", onClick: () => onValueChange(''), children: "Clear selection" })) : undefined, renderValue: (option) => (jsxRuntime.jsx("span", { className: "truncate", children: option.count !== undefined ? `${option.label} (${option.count})` : option.label })), renderOption: (option) => (jsxRuntime.jsxs("span", { className: "flex w-full items-center justify-between gap-2", children: [jsxRuntime.jsx("span", { className: "truncate", children: option.label }), 'count' in option && option.count !== undefined && (jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: option.count }))] })) }));
4136
+ }
4100
4137
 
4138
+ const RELATIVE_KEY = /^now-(\d+)([mhd])$/;
4139
+ /** Resolve a relative key such as `now-7d` to a `{ from, to }` window ending now. */
4140
+ function relativeKeyToRange(key, now = new Date()) {
4141
+ const match = RELATIVE_KEY.exec(key);
4142
+ if (!match)
4143
+ return null;
4144
+ const amount = Number(match[1]);
4145
+ const unitMs = { m: 60000, h: 3600000, d: 86400000 }[match[2]];
4146
+ return { from: new Date(now.getTime() - amount * unitMs), to: now };
4147
+ }
4148
+ /** `YYYY-MM-DDTHH:mm` in local time, the format the filter components store. */
4149
+ function toDatetimeLocal(iso) {
4150
+ const d = new Date(iso);
4151
+ const pad = (n) => String(n).padStart(2, '0');
4152
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
4153
+ }
4154
+ function toPickerPresets(presets) {
4155
+ return presets
4156
+ .filter((p) => RELATIVE_KEY.test(p.key))
4157
+ .map((p) => ({
4158
+ key: p.key,
4159
+ label: p.label,
4160
+ getRange: () => relativeKeyToRange(p.key),
4161
+ }));
4162
+ }
4101
4163
  /**
4102
- * @license lucide-react v0.577.0 - ISC
4103
- *
4104
- * This source code is licensed under the ISC license.
4105
- * See the LICENSE file in the root directory of this source tree.
4164
+ * TimeRangeDropdown - relative presets plus an absolute range, on datum-ui's
4165
+ * DateTimeRangePicker. The emitted value carries `preset` when a preset was
4166
+ * clicked, which keeps `start=now-7d` style URL state intact.
4106
4167
  */
4168
+ function TimeRangeDropdown({ presets, selectedPreset, onPresetSelect, onCustomRangeApply, customStart, customEnd, disabled = false, className, displayLabel, }) {
4169
+ const pickerPresets = React__namespace.useMemo(() => toPickerPresets(presets), [presets]);
4170
+ const value = React__namespace.useMemo(() => {
4171
+ if (selectedPreset !== 'custom') {
4172
+ const range = relativeKeyToRange(selectedPreset);
4173
+ return range
4174
+ ? { from: range.from.toISOString(), to: range.to.toISOString(), preset: selectedPreset }
4175
+ : null;
4176
+ }
4177
+ if (customStart && customEnd) {
4178
+ return { from: new Date(customStart).toISOString(), to: new Date(customEnd).toISOString() };
4179
+ }
4180
+ return null;
4181
+ }, [selectedPreset, customStart, customEnd]);
4182
+ const handleChange = (next) => {
4183
+ if (!next)
4184
+ return;
4185
+ const preset = next.preset;
4186
+ if (preset) {
4187
+ onPresetSelect(preset);
4188
+ return;
4189
+ }
4190
+ onCustomRangeApply(toDatetimeLocal(next.from), toDatetimeLocal(next.to));
4191
+ };
4192
+ return (jsxRuntime.jsx(picker.DateTimeRangePicker, { className: className, triggerClassName: "h-9 rounded-lg px-3 text-xs", value: value, onChange: handleChange, presets: pickerPresets, disableFuture: true, clearable: false, disabled: disabled, placeholder: displayLabel ?? 'Select time range', triggerLabel: displayLabel ? () => displayLabel : undefined }));
4193
+ }
4107
4194
 
4108
-
4109
- const Icon = React.forwardRef(
4110
- ({
4111
- color = "currentColor",
4112
- size = 24,
4113
- strokeWidth = 2,
4114
- absoluteStrokeWidth,
4115
- className = "",
4116
- children,
4117
- iconNode,
4118
- ...rest
4119
- }, ref) => React.createElement(
4120
- "svg",
4195
+ const TIME_PRESETS$3 = [
4121
4196
  {
4122
- ref,
4123
- ...defaultAttributes,
4124
- width: size,
4125
- height: size,
4126
- stroke: color,
4127
- strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
4128
- className: mergeClasses("lucide", className),
4129
- ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
4130
- ...rest
4197
+ key: 'last15min',
4198
+ label: 'Last 15 min',
4199
+ getValue: () => ({
4200
+ start: formatISO(subMinutes(new Date())),
4201
+ end: formatISO(new Date()),
4202
+ }),
4131
4203
  },
4132
- [
4133
- ...iconNode.map(([tag, attrs]) => React.createElement(tag, attrs)),
4134
- ...Array.isArray(children) ? children : [children]
4135
- ]
4136
- )
4137
- );
4138
-
4204
+ {
4205
+ key: 'last1hour',
4206
+ label: 'Last hour',
4207
+ getValue: () => ({
4208
+ start: formatISO(subHours(new Date(), 1)),
4209
+ end: formatISO(new Date()),
4210
+ }),
4211
+ },
4212
+ {
4213
+ key: 'last6hours',
4214
+ label: 'Last 6 hours',
4215
+ getValue: () => ({
4216
+ start: formatISO(subHours(new Date(), 6)),
4217
+ end: formatISO(new Date()),
4218
+ }),
4219
+ },
4220
+ {
4221
+ key: 'last24hours',
4222
+ label: 'Last 24 hours',
4223
+ getValue: () => ({
4224
+ start: formatISO(subHours(new Date(), 24)),
4225
+ end: formatISO(new Date()),
4226
+ }),
4227
+ },
4228
+ {
4229
+ key: 'last7days',
4230
+ label: 'Last 7 days',
4231
+ getValue: () => ({
4232
+ start: formatISO(subDays(new Date(), 7)),
4233
+ end: formatISO(new Date()),
4234
+ }),
4235
+ },
4236
+ {
4237
+ key: 'last30days',
4238
+ label: 'Last 30 days',
4239
+ getValue: () => ({
4240
+ start: formatISO(subDays(new Date(), 30)),
4241
+ end: formatISO(new Date()),
4242
+ }),
4243
+ },
4244
+ ];
4245
+ /** Debounce delay for text inputs (ms) */
4246
+ const DEBOUNCE_DELAY = 300;
4139
4247
  /**
4140
- * @license lucide-react v0.577.0 - ISC
4141
- *
4142
- * This source code is licensed under the ISC license.
4143
- * See the LICENSE file in the root directory of this source tree.
4248
+ * Helper function to convert ISO string to datetime-local format
4144
4249
  */
4145
-
4146
-
4147
- const createLucideIcon = (iconName, iconNode) => {
4148
- const Component = React.forwardRef(
4149
- ({ className, ...props }, ref) => React.createElement(Icon, {
4150
- ref,
4151
- iconNode,
4152
- className: mergeClasses(
4153
- `lucide-${toKebabCase(toPascalCase(iconName))}`,
4154
- `lucide-${iconName}`,
4155
- className
4156
- ),
4157
- ...props
4158
- })
4159
- );
4160
- Component.displayName = toPascalCase(iconName);
4161
- return Component;
4250
+ const formatDatetimeLocal$4 = (isoString) => {
4251
+ const date = new Date(isoString);
4252
+ const year = date.getFullYear();
4253
+ const month = String(date.getMonth() + 1).padStart(2, '0');
4254
+ const day = String(date.getDate()).padStart(2, '0');
4255
+ const hours = String(date.getHours()).padStart(2, '0');
4256
+ const minutes = String(date.getMinutes()).padStart(2, '0');
4257
+ return `${year}-${month}-${day}T${hours}:${minutes}`;
4162
4258
  };
4163
-
4164
- /**
4165
- * @license lucide-react v0.577.0 - ISC
4166
- *
4167
- * This source code is licensed under the ISC license.
4168
- * See the LICENSE file in the root directory of this source tree.
4169
- */
4170
-
4171
-
4172
- const __iconNode$p = [
4173
- [
4174
- "path",
4175
- {
4176
- d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",
4177
- key: "169zse"
4178
- }
4179
- ]
4180
- ];
4181
- const Activity = createLucideIcon("activity", __iconNode$p);
4182
-
4183
- /**
4184
- * @license lucide-react v0.577.0 - ISC
4185
- *
4186
- * This source code is licensed under the ISC license.
4187
- * See the LICENSE file in the root directory of this source tree.
4188
- */
4189
-
4190
-
4191
- const __iconNode$o = [
4192
- ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
4193
- [
4194
- "path",
4195
- {
4196
- d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",
4197
- key: "11g9vi"
4259
+ function SimpleQueryBuilder({ client, onFilterChange, initialLimit = 100, className = '', disabled = false, }) {
4260
+ const [isAdvancedExpanded, setIsAdvancedExpanded] = React.useState(false);
4261
+ const [filters, setFilters] = React.useState({
4262
+ verb: '',
4263
+ resourceType: '',
4264
+ namespace: '',
4265
+ resourceName: '',
4266
+ username: '',
4267
+ });
4268
+ const [limit, setLimit] = React.useState(initialLimit);
4269
+ const [advancedFilter, setAdvancedFilter] = React.useState('');
4270
+ const [useAdvancedFilter, setUseAdvancedFilter] = React.useState(false);
4271
+ // Time range state
4272
+ const [selectedPreset, setSelectedPreset] = React.useState('last24hours');
4273
+ const [timeRange, setTimeRange] = React.useState(null);
4274
+ const [customStart, setCustomStart] = React.useState(() => formatDatetimeLocal$4(formatISO(subDays(new Date(), 1))));
4275
+ const [customEnd, setCustomEnd] = React.useState(() => formatDatetimeLocal$4(formatISO(new Date())));
4276
+ // Fetch facets for dynamic filter options
4277
+ const { verbs, resources, namespaces, usernames, isLoading: facetsLoading, error: facetsError } = useAuditLogFacets(client, timeRange);
4278
+ // Log facets error for debugging
4279
+ if (facetsError) {
4280
+ console.error('Failed to load audit log facets:', facetsError);
4198
4281
  }
4199
- ]
4200
- ];
4201
- const Bell = createLucideIcon("bell", __iconNode$o);
4202
-
4203
- /**
4204
- * @license lucide-react v0.577.0 - ISC
4205
- *
4206
- * This source code is licensed under the ISC license.
4207
- * See the LICENSE file in the root directory of this source tree.
4208
- */
4209
-
4210
-
4211
- const __iconNode$n = [
4212
- ["path", { d: "M8 2v4", key: "1cmpym" }],
4213
- ["path", { d: "M16 2v4", key: "4m81vk" }],
4214
- ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
4215
- ["path", { d: "M3 10h18", key: "8toen8" }]
4216
- ];
4217
- const Calendar = createLucideIcon("calendar", __iconNode$n);
4218
-
4219
- /**
4220
- * @license lucide-react v0.577.0 - ISC
4221
- *
4222
- * This source code is licensed under the ISC license.
4223
- * See the LICENSE file in the root directory of this source tree.
4224
- */
4225
-
4282
+ // Refs for debouncing
4283
+ const debounceTimerRef = React.useRef(null);
4284
+ const isInitialMount = React.useRef(true);
4285
+ // Initialize with default time range and trigger initial query
4286
+ React.useEffect(() => {
4287
+ const defaultRange = TIME_PRESETS$3.find(p => p.key === 'last24hours')?.getValue();
4288
+ if (defaultRange) {
4289
+ setTimeRange(defaultRange);
4290
+ }
4291
+ }, []);
4292
+ const generateCEL = React.useCallback(() => {
4293
+ const parts = [];
4294
+ if (filters.verb) {
4295
+ parts.push(`verb == "${filters.verb}"`);
4296
+ }
4297
+ if (filters.resourceType) {
4298
+ parts.push(`objectRef.resource == "${filters.resourceType}"`);
4299
+ }
4300
+ if (filters.namespace) {
4301
+ parts.push(`objectRef.namespace == "${filters.namespace}"`);
4302
+ }
4303
+ if (filters.resourceName) {
4304
+ parts.push(`objectRef.name.contains("${filters.resourceName}")`);
4305
+ }
4306
+ if (filters.username) {
4307
+ parts.push(`user.username.contains("${filters.username}")`);
4308
+ }
4309
+ return parts.join(' && ');
4310
+ }, [filters]);
4311
+ // Execute query when filters change (with debouncing for text inputs)
4312
+ const executeQuery = React.useCallback(() => {
4313
+ if (!timeRange || disabled)
4314
+ return;
4315
+ const filter = useAdvancedFilter ? advancedFilter : generateCEL();
4316
+ onFilterChange({
4317
+ filter,
4318
+ limit,
4319
+ startTime: timeRange.start,
4320
+ endTime: timeRange.end
4321
+ });
4322
+ }, [useAdvancedFilter, advancedFilter, generateCEL, onFilterChange, limit, timeRange, disabled]);
4323
+ // Auto-execute query when dropdown filters or time range change (immediate)
4324
+ React.useEffect(() => {
4325
+ // Skip the initial mount - we want to wait for timeRange to be set
4326
+ if (isInitialMount.current) {
4327
+ isInitialMount.current = false;
4328
+ return;
4329
+ }
4330
+ // Clear any pending debounced query
4331
+ if (debounceTimerRef.current) {
4332
+ clearTimeout(debounceTimerRef.current);
4333
+ }
4334
+ executeQuery();
4335
+ }, [filters.verb, filters.resourceType, timeRange, limit, useAdvancedFilter]);
4336
+ // Auto-execute query when text filters change (debounced)
4337
+ React.useEffect(() => {
4338
+ if (isInitialMount.current || !timeRange)
4339
+ return;
4340
+ // Clear previous timer
4341
+ if (debounceTimerRef.current) {
4342
+ clearTimeout(debounceTimerRef.current);
4343
+ }
4344
+ // Set new debounced timer
4345
+ debounceTimerRef.current = setTimeout(() => {
4346
+ executeQuery();
4347
+ }, DEBOUNCE_DELAY);
4348
+ return () => {
4349
+ if (debounceTimerRef.current) {
4350
+ clearTimeout(debounceTimerRef.current);
4351
+ }
4352
+ };
4353
+ }, [filters.namespace, filters.resourceName, filters.username, advancedFilter]);
4354
+ const handleFilterChange = React.useCallback((field, value) => {
4355
+ setFilters(prev => ({ ...prev, [field]: value }));
4356
+ }, []);
4357
+ const handleTimePresetSelect = React.useCallback((presetKey) => {
4358
+ const preset = TIME_PRESETS$3.find(p => p.key === presetKey);
4359
+ if (preset) {
4360
+ setSelectedPreset(presetKey);
4361
+ setTimeRange(preset.getValue());
4362
+ }
4363
+ }, []);
4364
+ const handleCustomRangeApply = React.useCallback((start, end) => {
4365
+ setSelectedPreset('custom');
4366
+ setCustomStart(start);
4367
+ setCustomEnd(end);
4368
+ setTimeRange({
4369
+ start: new Date(start).toISOString(),
4370
+ end: new Date(end).toISOString(),
4371
+ });
4372
+ }, []);
4373
+ const handleLimitChange = React.useCallback((newLimit) => {
4374
+ const validLimit = Math.min(Math.max(1, newLimit), 1000);
4375
+ setLimit(validLimit);
4376
+ }, []);
4377
+ const handleAdvancedToggle = React.useCallback(() => {
4378
+ if (!isAdvancedExpanded) {
4379
+ // When expanding, populate advanced filter with generated CEL
4380
+ setAdvancedFilter(generateCEL());
4381
+ }
4382
+ setIsAdvancedExpanded(!isAdvancedExpanded);
4383
+ }, [isAdvancedExpanded, generateCEL]);
4384
+ const handleUseAdvancedChange = React.useCallback((checked) => {
4385
+ setUseAdvancedFilter(checked === true);
4386
+ }, []);
4387
+ // Get display label for time range
4388
+ const getTimeRangeLabel = () => {
4389
+ if (selectedPreset === 'custom') {
4390
+ if (timeRange?.start && timeRange?.end) {
4391
+ const start = new Date(timeRange.start);
4392
+ const end = new Date(timeRange.end);
4393
+ return `${start.toLocaleDateString()} - ${end.toLocaleDateString()}`;
4394
+ }
4395
+ return 'Custom';
4396
+ }
4397
+ const preset = TIME_PRESETS$3.find(p => p.key === selectedPreset);
4398
+ return preset?.label || 'Select time range';
4399
+ };
4400
+ return (jsxRuntime.jsxs("div", { className: `mb-6 pb-6 border-b border-border ${className}`, children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-4 items-end", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Action" }), jsxRuntime.jsx(Combobox, { options: verbs
4401
+ .filter(facet => facet.value)
4402
+ .map(facet => ({
4403
+ value: facet.value,
4404
+ label: facet.value,
4405
+ count: facet.count,
4406
+ })), value: filters.verb, onValueChange: (value) => handleFilterChange('verb', value), placeholder: "All", searchPlaceholder: "Search actions...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Resource" }), jsxRuntime.jsx(Combobox, { options: resources
4407
+ .filter(facet => facet.value)
4408
+ .map(facet => ({
4409
+ value: facet.value,
4410
+ label: facet.value,
4411
+ count: facet.count,
4412
+ })), value: filters.resourceType, onValueChange: (value) => handleFilterChange('resourceType', value), placeholder: "All", searchPlaceholder: "Search resources...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Namespace" }), jsxRuntime.jsx(Combobox, { options: namespaces
4413
+ .filter(facet => facet.value)
4414
+ .map(facet => ({
4415
+ value: facet.value,
4416
+ label: facet.value,
4417
+ count: facet.count,
4418
+ })), value: filters.namespace, onValueChange: (value) => handleFilterChange('namespace', value), placeholder: "All", searchPlaceholder: "Search namespaces...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "User" }), jsxRuntime.jsx(Combobox, { options: usernames
4419
+ .filter(facet => facet.value)
4420
+ .map(facet => ({
4421
+ value: facet.value,
4422
+ label: facet.value,
4423
+ count: facet.count,
4424
+ })), value: filters.username, onValueChange: (value) => handleFilterChange('username', value), placeholder: "All", searchPlaceholder: "Search users...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Name" }), jsxRuntime.jsx(input.Input, { type: "text", value: filters.resourceName, onChange: (e) => handleFilterChange('resourceName', e.target.value), placeholder: "Filter by name...", className: "min-w-[140px]", disabled: disabled || useAdvancedFilter })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Limit" }), jsxRuntime.jsx(input.Input, { type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-[80px]", disabled: disabled })] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "small", className: "whitespace-nowrap text-muted-foreground hover:text-foreground", onClick: handleAdvancedToggle, "aria-expanded": isAdvancedExpanded, children: isAdvancedExpanded ? '- CEL' : '+ CEL' }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 ml-auto", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Time Range" }), jsxRuntime.jsx(TimeRangeDropdown, { presets: TIME_PRESETS$3.map(p => ({ key: p.key, label: p.label })), selectedPreset: selectedPreset, onPresetSelect: handleTimePresetSelect, onCustomRangeApply: handleCustomRangeApply, customStart: customStart, customEnd: customEnd, disabled: disabled, displayLabel: getTimeRangeLabel() })] })] }), isAdvancedExpanded && (jsxRuntime.jsxs("div", { className: "mt-4 pt-4", children: [jsxRuntime.jsx(separator.Separator, { className: "mb-4" }), jsxRuntime.jsx("div", { className: "mb-3", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(checkbox.Checkbox, { id: "use-cel-expression", checked: useAdvancedFilter, onCheckedChange: handleUseAdvancedChange, disabled: disabled }), jsxRuntime.jsx(label.Label, { htmlFor: "use-cel-expression", className: "text-sm font-medium text-foreground cursor-pointer", children: "Use CEL Expression" })] }) }), useAdvancedFilter && (jsxRuntime.jsxs("div", { className: "mt-3", children: [jsxRuntime.jsx("p", { className: "m-0 mb-2 text-sm text-muted-foreground", children: "Write your query using CEL syntax for complex filters" }), jsxRuntime.jsx(textarea.Textarea, { value: advancedFilter, onChange: (e) => setAdvancedFilter(e.target.value), placeholder: 'Example: verb == "delete" && objectRef.namespace == "production"', rows: 3, className: "w-full font-mono resize-y", disabled: disabled })] }))] }))] }));
4425
+ }
4226
4426
 
4227
- const __iconNode$m = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
4228
- const Check = createLucideIcon("check", __iconNode$m);
4427
+ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
4229
4428
 
4230
4429
  /**
4231
- * @license lucide-react v0.577.0 - ISC
4232
- *
4233
- * This source code is licensed under the ISC license.
4234
- * See the LICENSE file in the root directory of this source tree.
4430
+ * Concatenates two arrays faster than the array spread operator.
4235
4431
  */
4236
-
4237
-
4238
- const __iconNode$l = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
4239
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$l);
4240
-
4241
- /**
4242
- * @license lucide-react v0.577.0 - ISC
4243
- *
4244
- * This source code is licensed under the ISC license.
4245
- * See the LICENSE file in the root directory of this source tree.
4246
- */
4247
-
4248
-
4249
- const __iconNode$k = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
4250
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$k);
4251
-
4252
- /**
4253
- * @license lucide-react v0.577.0 - ISC
4254
- *
4255
- * This source code is licensed under the ISC license.
4256
- * See the LICENSE file in the root directory of this source tree.
4257
- */
4258
-
4259
-
4260
- const __iconNode$j = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
4261
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$j);
4262
-
4263
- /**
4264
- * @license lucide-react v0.577.0 - ISC
4265
- *
4266
- * This source code is licensed under the ISC license.
4267
- * See the LICENSE file in the root directory of this source tree.
4268
- */
4269
-
4270
-
4271
- const __iconNode$i = [
4272
- ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
4273
- ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
4274
- ];
4275
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$i);
4276
-
4277
- /**
4278
- * @license lucide-react v0.577.0 - ISC
4279
- *
4280
- * This source code is licensed under the ISC license.
4281
- * See the LICENSE file in the root directory of this source tree.
4282
- */
4283
-
4284
-
4285
- const __iconNode$h = [
4286
- ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
4287
- ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
4288
- ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
4289
- ];
4290
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$h);
4291
-
4292
- /**
4293
- * @license lucide-react v0.577.0 - ISC
4294
- *
4295
- * This source code is licensed under the ISC license.
4296
- * See the LICENSE file in the root directory of this source tree.
4297
- */
4298
-
4299
-
4300
- const __iconNode$g = [
4301
- ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
4302
- ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
4303
- ];
4304
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$g);
4305
-
4306
- /**
4307
- * @license lucide-react v0.577.0 - ISC
4308
- *
4309
- * This source code is licensed under the ISC license.
4310
- * See the LICENSE file in the root directory of this source tree.
4311
- */
4312
-
4313
-
4314
- const __iconNode$f = [
4315
- ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
4316
- ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
4317
- ];
4318
- const CircleCheck = createLucideIcon("circle-check", __iconNode$f);
4319
-
4320
- /**
4321
- * @license lucide-react v0.577.0 - ISC
4322
- *
4323
- * This source code is licensed under the ISC license.
4324
- * See the LICENSE file in the root directory of this source tree.
4325
- */
4326
-
4327
-
4328
- const __iconNode$e = [
4329
- ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
4330
- ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
4331
- ["path", { d: "m9 9 6 6", key: "z0biqf" }]
4332
- ];
4333
- const CircleX = createLucideIcon("circle-x", __iconNode$e);
4334
-
4335
- /**
4336
- * @license lucide-react v0.577.0 - ISC
4337
- *
4338
- * This source code is licensed under the ISC license.
4339
- * See the LICENSE file in the root directory of this source tree.
4340
- */
4341
-
4342
-
4343
- const __iconNode$d = [
4344
- ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
4345
- ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
4346
- ];
4347
- const Clock = createLucideIcon("clock", __iconNode$d);
4348
-
4349
- /**
4350
- * @license lucide-react v0.577.0 - ISC
4351
- *
4352
- * This source code is licensed under the ISC license.
4353
- * See the LICENSE file in the root directory of this source tree.
4354
- */
4355
-
4356
-
4357
- const __iconNode$c = [
4358
- ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
4359
- ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
4360
- ];
4361
- const Copy = createLucideIcon("copy", __iconNode$c);
4362
-
4363
- /**
4364
- * @license lucide-react v0.577.0 - ISC
4365
- *
4366
- * This source code is licensed under the ISC license.
4367
- * See the LICENSE file in the root directory of this source tree.
4368
- */
4369
-
4370
-
4371
- const __iconNode$b = [
4372
- [
4373
- "path",
4374
- {
4375
- d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",
4376
- key: "1nclc0"
4377
- }
4378
- ],
4379
- ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
4380
- ];
4381
- const Eye = createLucideIcon("eye", __iconNode$b);
4382
-
4383
- /**
4384
- * @license lucide-react v0.577.0 - ISC
4385
- *
4386
- * This source code is licensed under the ISC license.
4387
- * See the LICENSE file in the root directory of this source tree.
4388
- */
4389
-
4390
-
4391
- const __iconNode$a = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
4392
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$a);
4393
-
4394
- /**
4395
- * @license lucide-react v0.577.0 - ISC
4396
- *
4397
- * This source code is licensed under the ISC license.
4398
- * See the LICENSE file in the root directory of this source tree.
4399
- */
4400
-
4401
-
4402
- const __iconNode$9 = [
4403
- [
4404
- "path",
4405
- {
4406
- d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
4407
- key: "1a8usu"
4408
- }
4409
- ],
4410
- ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
4411
- ];
4412
- const Pencil = createLucideIcon("pencil", __iconNode$9);
4413
-
4414
- /**
4415
- * @license lucide-react v0.577.0 - ISC
4416
- *
4417
- * This source code is licensed under the ISC license.
4418
- * See the LICENSE file in the root directory of this source tree.
4419
- */
4420
-
4421
-
4422
- const __iconNode$8 = [
4423
- ["path", { d: "M5 12h14", key: "1ays0h" }],
4424
- ["path", { d: "M12 5v14", key: "s699le" }]
4425
- ];
4426
- const Plus = createLucideIcon("plus", __iconNode$8);
4427
-
4428
- /**
4429
- * @license lucide-react v0.577.0 - ISC
4430
- *
4431
- * This source code is licensed under the ISC license.
4432
- * See the LICENSE file in the root directory of this source tree.
4433
- */
4434
-
4435
-
4436
- const __iconNode$7 = [
4437
- ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
4438
- ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
4439
- ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
4440
- ["path", { d: "M8 16H3v5", key: "1cv678" }]
4441
- ];
4442
- const RefreshCw = createLucideIcon("refresh-cw", __iconNode$7);
4443
-
4444
- /**
4445
- * @license lucide-react v0.577.0 - ISC
4446
- *
4447
- * This source code is licensed under the ISC license.
4448
- * See the LICENSE file in the root directory of this source tree.
4449
- */
4450
-
4451
-
4452
- const __iconNode$6 = [
4453
- ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
4454
- ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
4455
- ];
4456
- const RotateCw = createLucideIcon("rotate-cw", __iconNode$6);
4457
-
4458
- /**
4459
- * @license lucide-react v0.577.0 - ISC
4460
- *
4461
- * This source code is licensed under the ISC license.
4462
- * See the LICENSE file in the root directory of this source tree.
4463
- */
4464
-
4465
-
4466
- const __iconNode$5 = [
4467
- ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
4468
- ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
4469
- ];
4470
- const Search = createLucideIcon("search", __iconNode$5);
4471
-
4472
- /**
4473
- * @license lucide-react v0.577.0 - ISC
4474
- *
4475
- * This source code is licensed under the ISC license.
4476
- * See the LICENSE file in the root directory of this source tree.
4477
- */
4478
-
4479
-
4480
- const __iconNode$4 = [
4481
- ["path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1m0v6g" }],
4482
- [
4483
- "path",
4484
- {
4485
- d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",
4486
- key: "ohrbg2"
4487
- }
4488
- ]
4489
- ];
4490
- const SquarePen = createLucideIcon("square-pen", __iconNode$4);
4491
-
4492
- /**
4493
- * @license lucide-react v0.577.0 - ISC
4494
- *
4495
- * This source code is licensed under the ISC license.
4496
- * See the LICENSE file in the root directory of this source tree.
4497
- */
4498
-
4499
-
4500
- const __iconNode$3 = [
4501
- ["path", { d: "M10 11v6", key: "nco0om" }],
4502
- ["path", { d: "M14 11v6", key: "outv1u" }],
4503
- ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
4504
- ["path", { d: "M3 6h18", key: "d0wm0j" }],
4505
- ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
4506
- ];
4507
- const Trash2 = createLucideIcon("trash-2", __iconNode$3);
4508
-
4509
- /**
4510
- * @license lucide-react v0.577.0 - ISC
4511
- *
4512
- * This source code is licensed under the ISC license.
4513
- * See the LICENSE file in the root directory of this source tree.
4514
- */
4515
-
4516
-
4517
- const __iconNode$2 = [
4518
- [
4519
- "path",
4520
- {
4521
- d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
4522
- key: "wmoenq"
4523
- }
4524
- ],
4525
- ["path", { d: "M12 9v4", key: "juzpu7" }],
4526
- ["path", { d: "M12 17h.01", key: "p32p05" }]
4527
- ];
4528
- const TriangleAlert = createLucideIcon("triangle-alert", __iconNode$2);
4529
-
4530
- /**
4531
- * @license lucide-react v0.577.0 - ISC
4532
- *
4533
- * This source code is licensed under the ISC license.
4534
- * See the LICENSE file in the root directory of this source tree.
4535
- */
4536
-
4537
-
4538
- const __iconNode$1 = [
4539
- ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
4540
- ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
4541
- ];
4542
- const User = createLucideIcon("user", __iconNode$1);
4543
-
4544
- /**
4545
- * @license lucide-react v0.577.0 - ISC
4546
- *
4547
- * This source code is licensed under the ISC license.
4548
- * See the LICENSE file in the root directory of this source tree.
4549
- */
4550
-
4551
-
4552
- const __iconNode = [
4553
- ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
4554
- ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
4555
- ];
4556
- const X = createLucideIcon("x", __iconNode);
4557
-
4558
- function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
4559
-
4560
- /**
4561
- * Concatenates two arrays faster than the array spread operator.
4562
- */
4563
- const concatArrays = (array1, array2) => {
4564
- // Pre-allocate for better V8 optimization
4565
- const combinedArray = new Array(array1.length + array2.length);
4566
- for (let i = 0; i < array1.length; i++) {
4567
- combinedArray[i] = array1[i];
4568
- }
4569
- for (let i = 0; i < array2.length; i++) {
4570
- combinedArray[array1.length + i] = array2[i];
4571
- }
4572
- return combinedArray;
4573
- };
4432
+ const concatArrays = (array1, array2) => {
4433
+ // Pre-allocate for better V8 optimization
4434
+ const combinedArray = new Array(array1.length + array2.length);
4435
+ for (let i = 0; i < array1.length; i++) {
4436
+ combinedArray[i] = array1[i];
4437
+ }
4438
+ for (let i = 0; i < array2.length; i++) {
4439
+ combinedArray[array1.length + i] = array2[i];
4440
+ }
4441
+ return combinedArray;
4442
+ };
4574
4443
 
4575
4444
  // Factory function ensures consistent object shapes
4576
4445
  const createClassValidatorObject = (classGroupId, validator) => ({
@@ -4904,15 +4773,27 @@ const createConfigUtils = config => ({
4904
4773
  cache: createLruCache(config.cacheSize),
4905
4774
  parseClassName: createParseClassName(config),
4906
4775
  sortModifiers: createSortModifiers(config),
4776
+ postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),
4907
4777
  ...createClassGroupUtils(config)
4908
4778
  });
4779
+ const createPostfixLookupClassGroupIds = config => {
4780
+ const lookup = Object.create(null);
4781
+ const classGroupIds = config.postfixLookupClassGroups;
4782
+ if (classGroupIds) {
4783
+ for (let i = 0; i < classGroupIds.length; i++) {
4784
+ lookup[classGroupIds[i]] = true;
4785
+ }
4786
+ }
4787
+ return lookup;
4788
+ };
4909
4789
  const SPLIT_CLASSES_REGEX = /\s+/;
4910
4790
  const mergeClassList = (classList, configUtils) => {
4911
4791
  const {
4912
4792
  parseClassName,
4913
4793
  getClassGroupId,
4914
4794
  getConflictingClassGroupIds,
4915
- sortModifiers
4795
+ sortModifiers,
4796
+ postfixLookupClassGroupIds
4916
4797
  } = configUtils;
4917
4798
  /**
4918
4799
  * Set of classGroupIds in following format:
@@ -4938,7 +4819,18 @@ const mergeClassList = (classList, configUtils) => {
4938
4819
  continue;
4939
4820
  }
4940
4821
  let hasPostfixModifier = !!maybePostfixModifierPosition;
4941
- let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
4822
+ let classGroupId;
4823
+ if (hasPostfixModifier) {
4824
+ const baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
4825
+ classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
4826
+ const classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
4827
+ if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
4828
+ classGroupId = classGroupIdWithPostfix;
4829
+ hasPostfixModifier = false;
4830
+ }
4831
+ } else {
4832
+ classGroupId = getClassGroupId(baseClassName);
4833
+ }
4942
4834
  if (!classGroupId) {
4943
4835
  if (!hasPostfixModifier) {
4944
4836
  // Not a Tailwind class
@@ -5043,6 +4935,7 @@ const fallbackThemeArr = [];
5043
4935
  const fromTheme = key => {
5044
4936
  const themeGetter = theme => theme[key] || fallbackThemeArr;
5045
4937
  themeGetter.isThemeGetter = true;
4938
+ themeGetter.themeKey = key;
5046
4939
  return themeGetter;
5047
4940
  };
5048
4941
  const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
@@ -5050,7 +4943,7 @@ const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
5050
4943
  const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
5051
4944
  const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
5052
4945
  const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
5053
- const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
4946
+ const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix|color|light-dark)\(.+\)$/;
5054
4947
  // Shadow always begins with x and y offset separated by underscore optionally prepended by inset
5055
4948
  const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
5056
4949
  const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
@@ -5069,6 +4962,7 @@ const isNever = () => false;
5069
4962
  const isShadow = value => shadowRegex.test(value);
5070
4963
  const isImage = value => imageRegex.test(value);
5071
4964
  const isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);
4965
+ const isNamedContainerQuery = value => value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));
5072
4966
  const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);
5073
4967
  const isArbitraryValue = value => arbitraryValueRegex.test(value);
5074
4968
  const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
@@ -5173,7 +5067,7 @@ const getDefaultConfig = () => {
5173
5067
  const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
5174
5068
  const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
5175
5069
  const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5176
- const scaleSizingInline = () => [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5070
+ const scaleSizingInline = () => [themeContainer, isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5177
5071
  const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5178
5072
  const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
5179
5073
  const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
@@ -5240,12 +5134,24 @@ const getDefaultConfig = () => {
5240
5134
  * @deprecated since Tailwind CSS v4.0.0
5241
5135
  */
5242
5136
  container: ['container'],
5137
+ /**
5138
+ * Container Type
5139
+ * @see https://tailwindcss.com/docs/responsive-design#container-queries
5140
+ */
5141
+ 'container-type': [{
5142
+ '@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
5143
+ }],
5144
+ /**
5145
+ * Container Name
5146
+ * @see https://tailwindcss.com/docs/responsive-design#named-containers
5147
+ */
5148
+ 'container-named': [isNamedContainerQuery],
5243
5149
  /**
5244
5150
  * Columns
5245
5151
  * @see https://tailwindcss.com/docs/columns
5246
5152
  */
5247
5153
  columns: [{
5248
- columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer]
5154
+ columns: [isNumber, 'auto', isArbitraryValue, isArbitraryVariable, themeContainer]
5249
5155
  }],
5250
5156
  /**
5251
5157
  * Break After
@@ -5881,42 +5787,42 @@ const getDefaultConfig = () => {
5881
5787
  }],
5882
5788
  /**
5883
5789
  * Inline Size
5884
- * @see https://tailwindcss.com/docs/width
5790
+ * @see https://tailwindcss.com/docs/inline-size
5885
5791
  */
5886
5792
  'inline-size': [{
5887
5793
  inline: ['auto', ...scaleSizingInline()]
5888
5794
  }],
5889
5795
  /**
5890
5796
  * Min-Inline Size
5891
- * @see https://tailwindcss.com/docs/min-width
5797
+ * @see https://tailwindcss.com/docs/min-inline-size
5892
5798
  */
5893
5799
  'min-inline-size': [{
5894
5800
  'min-inline': ['auto', ...scaleSizingInline()]
5895
5801
  }],
5896
5802
  /**
5897
5803
  * Max-Inline Size
5898
- * @see https://tailwindcss.com/docs/max-width
5804
+ * @see https://tailwindcss.com/docs/max-inline-size
5899
5805
  */
5900
5806
  'max-inline-size': [{
5901
5807
  'max-inline': ['none', ...scaleSizingInline()]
5902
5808
  }],
5903
5809
  /**
5904
5810
  * Block Size
5905
- * @see https://tailwindcss.com/docs/height
5811
+ * @see https://tailwindcss.com/docs/block-size
5906
5812
  */
5907
5813
  'block-size': [{
5908
5814
  block: ['auto', ...scaleSizingBlock()]
5909
5815
  }],
5910
5816
  /**
5911
5817
  * Min-Block Size
5912
- * @see https://tailwindcss.com/docs/min-height
5818
+ * @see https://tailwindcss.com/docs/min-block-size
5913
5819
  */
5914
5820
  'min-block-size': [{
5915
5821
  'min-block': ['auto', ...scaleSizingBlock()]
5916
5822
  }],
5917
5823
  /**
5918
5824
  * Max-Block Size
5919
- * @see https://tailwindcss.com/docs/max-height
5825
+ * @see https://tailwindcss.com/docs/max-block-size
5920
5826
  */
5921
5827
  'max-block-size': [{
5922
5828
  'max-block': ['none', ...scaleSizingBlock()]
@@ -5966,7 +5872,7 @@ const getDefaultConfig = () => {
5966
5872
  * @see https://tailwindcss.com/docs/max-height
5967
5873
  */
5968
5874
  'max-h': [{
5969
- 'max-h': ['screen', 'lh', ...scaleSizing()]
5875
+ 'max-h': ['screen', 'lh', 'none', ...scaleSizing()]
5970
5876
  }],
5971
5877
  // ------------------
5972
5878
  // --- Typography ---
@@ -6065,7 +5971,7 @@ const getDefaultConfig = () => {
6065
5971
  * @see https://tailwindcss.com/docs/line-height
6066
5972
  */
6067
5973
  leading: [{
6068
- leading: [/** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
5974
+ leading: ['none', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
6069
5975
  themeLeading, ...scaleUnambiguousSpacing()]
6070
5976
  }],
6071
5977
  /**
@@ -6168,6 +6074,13 @@ const getDefaultConfig = () => {
6168
6074
  indent: [{
6169
6075
  indent: scaleUnambiguousSpacing()
6170
6076
  }],
6077
+ /**
6078
+ * Tab Size
6079
+ * @see https://tailwindcss.com/docs/tab-size
6080
+ */
6081
+ 'tab-size': [{
6082
+ tab: [isInteger, isArbitraryVariable, isArbitraryValue]
6083
+ }],
6171
6084
  /**
6172
6085
  * Vertical Alignment
6173
6086
  * @see https://tailwindcss.com/docs/vertical-align
@@ -6265,7 +6178,7 @@ const getDefaultConfig = () => {
6265
6178
  to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']
6266
6179
  }, isInteger, isArbitraryVariable, isArbitraryValue],
6267
6180
  radial: ['', isArbitraryVariable, isArbitraryValue],
6268
- conic: [isInteger, isArbitraryVariable, isArbitraryValue]
6181
+ conic: ['', isInteger, isArbitraryVariable, isArbitraryValue]
6269
6182
  }, isArbitraryVariableImage, isArbitraryImage]
6270
6183
  }],
6271
6184
  /**
@@ -6662,7 +6575,9 @@ const getDefaultConfig = () => {
6662
6575
  shadow: [{
6663
6576
  shadow: [
6664
6577
  // Deprecated since Tailwind CSS v4.0.0
6665
- '', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]
6578
+ '',
6579
+ // Deprecated since Tailwind CSS v4.0.0
6580
+ 'inner', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]
6666
6581
  }],
6667
6582
  /**
6668
6583
  * Box Shadow Color
@@ -7375,6 +7290,13 @@ const getDefaultConfig = () => {
7375
7290
  * @see https://tailwindcss.com/docs/translate
7376
7291
  */
7377
7292
  'translate-none': ['translate-none'],
7293
+ /**
7294
+ * Zoom
7295
+ * @see https://tailwindcss.com/docs/zoom
7296
+ */
7297
+ zoom: [{
7298
+ zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
7299
+ }],
7378
7300
  // ---------------------
7379
7301
  // --- Interactivity ---
7380
7302
  // ---------------------
@@ -7441,6 +7363,34 @@ const getDefaultConfig = () => {
7441
7363
  'scroll-behavior': [{
7442
7364
  scroll: ['auto', 'smooth']
7443
7365
  }],
7366
+ /**
7367
+ * Scrollbar Thumb Color
7368
+ * @see https://tailwindcss.com/docs/scrollbar-color
7369
+ */
7370
+ 'scrollbar-thumb-color': [{
7371
+ 'scrollbar-thumb': scaleColor()
7372
+ }],
7373
+ /**
7374
+ * Scrollbar Track Color
7375
+ * @see https://tailwindcss.com/docs/scrollbar-color
7376
+ */
7377
+ 'scrollbar-track-color': [{
7378
+ 'scrollbar-track': scaleColor()
7379
+ }],
7380
+ /**
7381
+ * Scrollbar Gutter
7382
+ * @see https://tailwindcss.com/docs/scrollbar-gutter
7383
+ */
7384
+ 'scrollbar-gutter': [{
7385
+ 'scrollbar-gutter': ['auto', 'stable', 'both']
7386
+ }],
7387
+ /**
7388
+ * Scrollbar Width
7389
+ * @see https://tailwindcss.com/docs/scrollbar-width
7390
+ */
7391
+ 'scrollbar-w': [{
7392
+ scrollbar: ['auto', 'thin', 'none']
7393
+ }],
7444
7394
  /**
7445
7395
  * Scroll Margin
7446
7396
  * @see https://tailwindcss.com/docs/scroll-margin
@@ -7699,19 +7649,20 @@ const getDefaultConfig = () => {
7699
7649
  }]
7700
7650
  },
7701
7651
  conflictingClassGroups: {
7652
+ 'container-named': ['container-type'],
7702
7653
  overflow: ['overflow-x', 'overflow-y'],
7703
7654
  overscroll: ['overscroll-x', 'overscroll-y'],
7704
7655
  inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
7705
- 'inset-x': ['right', 'left'],
7706
- 'inset-y': ['top', 'bottom'],
7656
+ 'inset-x': ['start', 'end', 'right', 'left'],
7657
+ 'inset-y': ['inset-bs', 'inset-be', 'top', 'bottom'],
7707
7658
  flex: ['basis', 'grow', 'shrink'],
7708
7659
  gap: ['gap-x', 'gap-y'],
7709
7660
  p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
7710
- px: ['pr', 'pl'],
7711
- py: ['pt', 'pb'],
7661
+ px: ['ps', 'pe', 'pr', 'pl'],
7662
+ py: ['pbs', 'pbe', 'pt', 'pb'],
7712
7663
  m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
7713
- mx: ['mr', 'ml'],
7714
- my: ['mt', 'mb'],
7664
+ mx: ['ms', 'me', 'mr', 'ml'],
7665
+ my: ['mbs', 'mbe', 'mt', 'mb'],
7715
7666
  size: ['w', 'h'],
7716
7667
  'font-size': ['leading'],
7717
7668
  'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],
@@ -7730,19 +7681,19 @@ const getDefaultConfig = () => {
7730
7681
  'rounded-l': ['rounded-tl', 'rounded-bl'],
7731
7682
  'border-spacing': ['border-spacing-x', 'border-spacing-y'],
7732
7683
  'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
7733
- 'border-w-x': ['border-w-r', 'border-w-l'],
7734
- 'border-w-y': ['border-w-t', 'border-w-b'],
7684
+ 'border-w-x': ['border-w-s', 'border-w-e', 'border-w-r', 'border-w-l'],
7685
+ 'border-w-y': ['border-w-bs', 'border-w-be', 'border-w-t', 'border-w-b'],
7735
7686
  'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
7736
- 'border-color-x': ['border-color-r', 'border-color-l'],
7737
- 'border-color-y': ['border-color-t', 'border-color-b'],
7687
+ 'border-color-x': ['border-color-s', 'border-color-e', 'border-color-r', 'border-color-l'],
7688
+ 'border-color-y': ['border-color-bs', 'border-color-be', 'border-color-t', 'border-color-b'],
7738
7689
  translate: ['translate-x', 'translate-y', 'translate-none'],
7739
7690
  'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
7740
7691
  'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
7741
- 'scroll-mx': ['scroll-mr', 'scroll-ml'],
7742
- 'scroll-my': ['scroll-mt', 'scroll-mb'],
7692
+ 'scroll-mx': ['scroll-ms', 'scroll-me', 'scroll-mr', 'scroll-ml'],
7693
+ 'scroll-my': ['scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mb'],
7743
7694
  'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
7744
- 'scroll-px': ['scroll-pr', 'scroll-pl'],
7745
- 'scroll-py': ['scroll-pt', 'scroll-pb'],
7695
+ 'scroll-px': ['scroll-ps', 'scroll-pe', 'scroll-pr', 'scroll-pl'],
7696
+ 'scroll-py': ['scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pb'],
7746
7697
  touch: ['touch-x', 'touch-y', 'touch-pz'],
7747
7698
  'touch-x': ['touch'],
7748
7699
  'touch-y': ['touch'],
@@ -7751,485 +7702,684 @@ const getDefaultConfig = () => {
7751
7702
  conflictingClassGroupModifiers: {
7752
7703
  'font-size': ['leading']
7753
7704
  },
7754
- orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
7755
- };
7705
+ postfixLookupClassGroups: ['container-type'],
7706
+ orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
7707
+ };
7708
+ };
7709
+ const twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);
7710
+
7711
+ function cn(...inputs) {
7712
+ return twMerge(clsx(inputs));
7713
+ }
7714
+
7715
+ /**
7716
+ * Get icon for tenant type
7717
+ */
7718
+ function getTenantIcon(type) {
7719
+ switch (type) {
7720
+ case "organization":
7721
+ return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" }) }));
7722
+ case "project":
7723
+ return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" }) }));
7724
+ case "user":
7725
+ return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }));
7726
+ case "platform":
7727
+ return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }));
7728
+ default:
7729
+ return null;
7730
+ }
7731
+ }
7732
+ /**
7733
+ * Get badge variant based on tenant type
7734
+ */
7735
+ function getTenantBadgeVariant(type) {
7736
+ switch (type) {
7737
+ case "organization":
7738
+ return "default";
7739
+ case "project":
7740
+ return "secondary";
7741
+ case "user":
7742
+ return "default";
7743
+ case "platform":
7744
+ return "default";
7745
+ default:
7746
+ return "secondary";
7747
+ }
7748
+ }
7749
+ /**
7750
+ * TenantBadge displays tenant information in a compact badge format
7751
+ * Renders as a clickable link if tenantLinkResolver is provided and returns a URL
7752
+ */
7753
+ function TenantBadge({ tenant, tenantLinkResolver, className = "", size = "default", }) {
7754
+ const icon = getTenantIcon(tenant.type);
7755
+ const variant = getTenantBadgeVariant(tenant.type);
7756
+ const url = tenantLinkResolver?.(tenant);
7757
+ const badgeContent = (jsxRuntime.jsxs(Badge, { variant: variant, className: cn("inline-flex items-center gap-1 whitespace-nowrap", size === "compact" ? "text-xs h-4 py-0 px-1.5" : "text-xs h-5 px-2", url && "cursor-pointer hover:opacity-80 transition-opacity", className), children: [icon, jsxRuntime.jsx("span", { className: "font-medium capitalize", children: tenant.type }), tenant.type !== "platform" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "/" }), jsxRuntime.jsx("span", { children: tenant.name })] }))] }));
7758
+ if (url) {
7759
+ return (jsxRuntime.jsx("a", { href: url, className: "no-underline", onClick: (e) => e.stopPropagation(), title: `View ${tenant.type}: ${tenant.name}`, children: badgeContent }));
7760
+ }
7761
+ return badgeContent;
7762
+ }
7763
+
7764
+ /**
7765
+ * Extract tenant information from audit event annotations if present
7766
+ * Expected annotations: tenant.type and tenant.name
7767
+ */
7768
+ function extractTenantFromAnnotations(event) {
7769
+ const annotations = event.annotations;
7770
+ if (!annotations)
7771
+ return undefined;
7772
+ const tenantType = annotations["tenant.type"];
7773
+ const tenantName = annotations["tenant.name"];
7774
+ if (tenantType && tenantName) {
7775
+ const validTypes = [
7776
+ "platform",
7777
+ "organization",
7778
+ "project",
7779
+ "user",
7780
+ ];
7781
+ if (validTypes.includes(tenantType)) {
7782
+ return {
7783
+ type: tenantType,
7784
+ name: tenantName,
7785
+ };
7786
+ }
7787
+ }
7788
+ return undefined;
7789
+ }
7790
+ /**
7791
+ * AuditEventViewer displays a list of audit events with details
7792
+ */
7793
+ function AuditEventViewer({ events, className = "", onEventSelect, tenantLinkResolver, }) {
7794
+ const [selectedEvent, setSelectedEvent] = React.useState(null);
7795
+ const [expandedEvents, setExpandedEvents] = React.useState(new Set());
7796
+ const toggleEventExpansion = (auditId) => {
7797
+ const newExpanded = new Set(expandedEvents);
7798
+ if (expandedEvents.has(auditId)) {
7799
+ newExpanded.delete(auditId);
7800
+ }
7801
+ else {
7802
+ newExpanded.add(auditId);
7803
+ }
7804
+ setExpandedEvents(newExpanded);
7805
+ };
7806
+ const handleEventClick = (event) => {
7807
+ setSelectedEvent(event);
7808
+ if (onEventSelect) {
7809
+ onEventSelect(event);
7810
+ }
7811
+ };
7812
+ const formatTimestamp = (timestamp) => {
7813
+ if (!timestamp)
7814
+ return "N/A";
7815
+ try {
7816
+ return format(new Date(timestamp), "yyyy-MM-dd HH:mm:ss");
7817
+ }
7818
+ catch {
7819
+ return timestamp;
7820
+ }
7821
+ };
7822
+ const getVerbBadgeVariant = (verb) => {
7823
+ switch (verb?.toLowerCase()) {
7824
+ case "create":
7825
+ return "success";
7826
+ case "update":
7827
+ case "patch":
7828
+ return "warning";
7829
+ case "delete":
7830
+ return "destructive";
7831
+ case "get":
7832
+ case "list":
7833
+ case "watch":
7834
+ return "default";
7835
+ default:
7836
+ return "secondary";
7837
+ }
7838
+ };
7839
+ if (events.length === 0) {
7840
+ return (jsxRuntime.jsx("div", { className: `bg-muted rounded-lg border border-border ${className}`, children: jsxRuntime.jsx("div", { className: "p-12 text-center text-muted-foreground text-sm", children: "No events found" }) }));
7841
+ }
7842
+ return (jsxRuntime.jsx("div", { className: `bg-muted rounded-lg border border-border ${className}`, children: jsxRuntime.jsx("div", { className: "p-4", children: events.map((event) => {
7843
+ const auditId = event.auditID || "";
7844
+ const isExpanded = expandedEvents.has(auditId);
7845
+ const tenant = extractTenantFromAnnotations(event);
7846
+ return (jsxRuntime.jsxs(card.Card, { className: `p-5 mb-3 cursor-pointer transition-all hover:border-primary/50 hover:shadow-sm hover:-translate-y-px ${selectedEvent?.auditID === auditId
7847
+ ? "border-primary bg-primary/5 shadow-md"
7848
+ : ""}`, onClick: () => handleEventClick(event), children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsxs("div", { className: "flex gap-3 items-center flex-1", children: [jsxRuntime.jsx(Badge, { variant: getVerbBadgeVariant(event.verb), className: "px-3 py-1", children: event.verb?.toUpperCase() || "UNKNOWN" }), jsxRuntime.jsx("span", { className: "font-semibold", children: event.objectRef?.resource || "N/A" }), event.objectRef?.namespace && (jsxRuntime.jsxs("span", { className: "text-muted-foreground text-sm", children: ["ns: ", event.objectRef.namespace] })), event.objectRef?.name && (jsxRuntime.jsx("span", { className: "text-foreground/80 text-sm", children: event.objectRef.name })), tenant && (jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver, size: "compact" }))] }), jsxRuntime.jsxs("div", { className: "flex gap-4 items-center", children: [jsxRuntime.jsx("span", { className: "text-foreground/80 text-sm", children: event.user?.username || "N/A" }), jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm font-mono", children: formatTimestamp(event.stageTimestamp) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", onClick: (e) => {
7849
+ e.stopPropagation();
7850
+ toggleEventExpansion(auditId);
7851
+ }, className: "text-primary", children: isExpanded ? "▼" : "▶" })] })] }), isExpanded && (jsxRuntime.jsxs("div", { className: "mt-4 pt-4 border-t border-border", children: [jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Event Information" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Audit ID:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.auditID || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Stage:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.stage || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Level:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.level || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Request URI:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground font-mono text-sm break-all", children: event.requestURI || "N/A" }), event.userAgent && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "User Agent:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground font-mono text-sm break-all", children: event.userAgent })] })), event.sourceIPs && event.sourceIPs.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Source IPs:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.sourceIPs.join(", ") })] }))] })] }), tenant && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Tenant" }), jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver })] })), event.user && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "User Information" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Username:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.username || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "UID:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.uid || "N/A" }), event.user.groups && event.user.groups.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Groups:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.groups.join(", ") })] }))] })] })), event.responseStatus && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Response Status" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Code:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.code || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Status:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.status || "N/A" }), event.responseStatus.message && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Message:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.message })] }))] })] })), event.annotations &&
7852
+ Object.keys(event.annotations).length > 0 && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Annotations" }), jsxRuntime.jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: Object.entries(event.annotations).map(([key, value]) => (jsxRuntime.jsxs("div", { className: "contents", children: [jsxRuntime.jsxs("dt", { className: "font-semibold text-foreground/80", children: [key, ":"] }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: value })] }, key))) })] })), event.requestObject || event.responseObject ? (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Request/Response Data" }), event.requestObject ? (jsxRuntime.jsxs("details", { className: "mt-2", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer font-semibold p-2 bg-muted rounded", children: "Request Object" }), jsxRuntime.jsx("pre", { className: "mt-2 p-4 bg-muted rounded overflow-x-auto text-sm", children: JSON.stringify(event.requestObject, null, 2) })] })) : null, event.responseObject ? (jsxRuntime.jsxs("details", { className: "mt-2", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer font-semibold p-2 bg-muted rounded", children: "Response Object" }), jsxRuntime.jsx("pre", { className: "mt-2 p-4 bg-muted rounded overflow-x-auto text-sm", children: JSON.stringify(event.responseObject, null, 2) })] })) : null] })) : null] }))] }, auditId));
7853
+ }) }) }));
7854
+ }
7855
+
7856
+ /**
7857
+ * @license lucide-react v0.577.0 - ISC
7858
+ *
7859
+ * This source code is licensed under the ISC license.
7860
+ * See the LICENSE file in the root directory of this source tree.
7861
+ */
7862
+
7863
+ const mergeClasses = (...classes) => classes.filter((className, index, array) => {
7864
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
7865
+ }).join(" ").trim();
7866
+
7867
+ /**
7868
+ * @license lucide-react v0.577.0 - ISC
7869
+ *
7870
+ * This source code is licensed under the ISC license.
7871
+ * See the LICENSE file in the root directory of this source tree.
7872
+ */
7873
+
7874
+ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
7875
+
7876
+ /**
7877
+ * @license lucide-react v0.577.0 - ISC
7878
+ *
7879
+ * This source code is licensed under the ISC license.
7880
+ * See the LICENSE file in the root directory of this source tree.
7881
+ */
7882
+
7883
+ const toCamelCase = (string) => string.replace(
7884
+ /^([A-Z])|[\s-_]+(\w)/g,
7885
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
7886
+ );
7887
+
7888
+ /**
7889
+ * @license lucide-react v0.577.0 - ISC
7890
+ *
7891
+ * This source code is licensed under the ISC license.
7892
+ * See the LICENSE file in the root directory of this source tree.
7893
+ */
7894
+
7895
+
7896
+ const toPascalCase = (string) => {
7897
+ const camelCase = toCamelCase(string);
7898
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
7899
+ };
7900
+
7901
+ /**
7902
+ * @license lucide-react v0.577.0 - ISC
7903
+ *
7904
+ * This source code is licensed under the ISC license.
7905
+ * See the LICENSE file in the root directory of this source tree.
7906
+ */
7907
+
7908
+ var defaultAttributes = {
7909
+ xmlns: "http://www.w3.org/2000/svg",
7910
+ width: 24,
7911
+ height: 24,
7912
+ viewBox: "0 0 24 24",
7913
+ fill: "none",
7914
+ stroke: "currentColor",
7915
+ strokeWidth: 2,
7916
+ strokeLinecap: "round",
7917
+ strokeLinejoin: "round"
7918
+ };
7919
+
7920
+ /**
7921
+ * @license lucide-react v0.577.0 - ISC
7922
+ *
7923
+ * This source code is licensed under the ISC license.
7924
+ * See the LICENSE file in the root directory of this source tree.
7925
+ */
7926
+
7927
+ const hasA11yProp = (props) => {
7928
+ for (const prop in props) {
7929
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
7930
+ return true;
7931
+ }
7932
+ }
7933
+ return false;
7934
+ };
7935
+
7936
+ /**
7937
+ * @license lucide-react v0.577.0 - ISC
7938
+ *
7939
+ * This source code is licensed under the ISC license.
7940
+ * See the LICENSE file in the root directory of this source tree.
7941
+ */
7942
+
7943
+
7944
+ const Icon = React.forwardRef(
7945
+ ({
7946
+ color = "currentColor",
7947
+ size = 24,
7948
+ strokeWidth = 2,
7949
+ absoluteStrokeWidth,
7950
+ className = "",
7951
+ children,
7952
+ iconNode,
7953
+ ...rest
7954
+ }, ref) => React.createElement(
7955
+ "svg",
7956
+ {
7957
+ ref,
7958
+ ...defaultAttributes,
7959
+ width: size,
7960
+ height: size,
7961
+ stroke: color,
7962
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
7963
+ className: mergeClasses("lucide", className),
7964
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
7965
+ ...rest
7966
+ },
7967
+ [
7968
+ ...iconNode.map(([tag, attrs]) => React.createElement(tag, attrs)),
7969
+ ...Array.isArray(children) ? children : [children]
7970
+ ]
7971
+ )
7972
+ );
7973
+
7974
+ /**
7975
+ * @license lucide-react v0.577.0 - ISC
7976
+ *
7977
+ * This source code is licensed under the ISC license.
7978
+ * See the LICENSE file in the root directory of this source tree.
7979
+ */
7980
+
7981
+
7982
+ const createLucideIcon = (iconName, iconNode) => {
7983
+ const Component = React.forwardRef(
7984
+ ({ className, ...props }, ref) => React.createElement(Icon, {
7985
+ ref,
7986
+ iconNode,
7987
+ className: mergeClasses(
7988
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
7989
+ `lucide-${iconName}`,
7990
+ className
7991
+ ),
7992
+ ...props
7993
+ })
7994
+ );
7995
+ Component.displayName = toPascalCase(iconName);
7996
+ return Component;
7756
7997
  };
7757
- const twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);
7758
7998
 
7759
- function cn(...inputs) {
7760
- return twMerge(clsx(inputs));
7761
- }
7999
+ /**
8000
+ * @license lucide-react v0.577.0 - ISC
8001
+ *
8002
+ * This source code is licensed under the ISC license.
8003
+ * See the LICENSE file in the root directory of this source tree.
8004
+ */
8005
+
8006
+
8007
+ const __iconNode$o = [
8008
+ [
8009
+ "path",
8010
+ {
8011
+ d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",
8012
+ key: "169zse"
8013
+ }
8014
+ ]
8015
+ ];
8016
+ const Activity = createLucideIcon("activity", __iconNode$o);
7762
8017
 
7763
8018
  /**
7764
- * Combobox component with type-ahead search and fuzzy matching.
7765
- * Built on cmdk for search functionality and Radix Popover for positioning.
8019
+ * @license lucide-react v0.577.0 - ISC
8020
+ *
8021
+ * This source code is licensed under the ISC license.
8022
+ * See the LICENSE file in the root directory of this source tree.
7766
8023
  */
7767
- function Combobox({ options, value, onValueChange, placeholder = 'Select...', searchPlaceholder = 'Search...', emptyMessage = 'No results found.', disabled = false, loading = false, className, clearable = false, showAllOption = true, allOptionLabel = 'All', }) {
7768
- const [open, setOpen] = React__namespace.useState(false);
7769
- const [search, setSearch] = React__namespace.useState('');
7770
- // Find current selected option for display
7771
- const selectedOption = options.find((opt) => opt.value === value);
7772
- const displayValue = selectedOption
7773
- ? selectedOption.count !== undefined
7774
- ? `${selectedOption.label} (${selectedOption.count})`
7775
- : selectedOption.label
7776
- : value === '' && showAllOption
7777
- ? allOptionLabel
7778
- : placeholder;
7779
- const handleSelect = React__namespace.useCallback((selectedValue) => {
7780
- onValueChange(selectedValue === value ? '' : selectedValue);
7781
- setOpen(false);
7782
- setSearch('');
7783
- }, [onValueChange, value]);
7784
- const handleClear = React__namespace.useCallback((e) => {
7785
- e.stopPropagation();
7786
- onValueChange('');
7787
- }, [onValueChange]);
7788
- // Custom fuzzy filter function
7789
- const filterOptions = React__namespace.useCallback((optionValue, searchQuery) => {
7790
- if (!searchQuery)
7791
- return 1;
7792
- const option = options.find((o) => o.value === optionValue);
7793
- const label = option?.label || optionValue;
7794
- const lowerLabel = label.toLowerCase();
7795
- const lowerSearch = searchQuery.toLowerCase();
7796
- // Exact match
7797
- if (lowerLabel === lowerSearch)
7798
- return 1;
7799
- // Starts with
7800
- if (lowerLabel.startsWith(lowerSearch))
7801
- return 0.9;
7802
- // Contains
7803
- if (lowerLabel.includes(lowerSearch))
7804
- return 0.8;
7805
- // Fuzzy match - check if all search chars appear in order
7806
- let searchIdx = 0;
7807
- for (let i = 0; i < lowerLabel.length && searchIdx < lowerSearch.length; i++) {
7808
- if (lowerLabel[i] === lowerSearch[searchIdx]) {
7809
- searchIdx++;
7810
- }
7811
- }
7812
- if (searchIdx === lowerSearch.length)
7813
- return 0.6;
7814
- return 0;
7815
- }, [options]);
7816
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", disabled: disabled || loading, className: cn('flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background', 'placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', className), children: [jsxRuntime.jsx("span", { className: "truncate text-left flex-1", children: loading ? 'Loading...' : displayValue }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-2", children: [clearable && value && !disabled && (jsxRuntime.jsx("span", { role: "button", tabIndex: 0, onClick: handleClear, onKeyDown: (e) => {
7817
- if (e.key === 'Enter' || e.key === ' ') {
7818
- handleClear(e);
7819
- }
7820
- }, className: "rounded-sm opacity-50 hover:opacity-100 cursor-pointer", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) })), jsxRuntime.jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })] })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[var(--radix-popover-trigger-width)] overflow-hidden rounded-md border shadow-md', 'bg-white dark:bg-slate-900 text-foreground', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "start", children: jsxRuntime.jsxs(cmdk.Command, { filter: filterOptions, className: "w-full", children: [jsxRuntime.jsx("div", { className: "flex items-center border-b px-3", children: jsxRuntime.jsx(cmdk.CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch, className: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" }) }), jsxRuntime.jsxs(cmdk.CommandList, { className: "max-h-[300px] overflow-y-auto p-1", children: [jsxRuntime.jsx(cmdk.CommandEmpty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }), jsxRuntime.jsxs(cmdk.CommandGroup, { children: [showAllOption && (jsxRuntime.jsxs(cmdk.CommandItem, { value: "_all", onSelect: () => handleSelect(''), className: cn('relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none', 'data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground', 'hover:bg-accent hover:text-accent-foreground'), children: [jsxRuntime.jsx(Check, { className: cn('mr-2 h-4 w-4', value === '' ? 'opacity-100' : 'opacity-0') }), allOptionLabel] })), options.map((option) => (jsxRuntime.jsxs(cmdk.CommandItem, { value: option.value, onSelect: () => handleSelect(option.value), className: cn('relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none', 'data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground', 'hover:bg-accent hover:text-accent-foreground'), children: [jsxRuntime.jsx(Check, { className: cn('mr-2 h-4 w-4', value === option.value ? 'opacity-100' : 'opacity-0') }), jsxRuntime.jsx("span", { className: "flex-1 truncate", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value)))] })] })] }) }) })] }));
7821
- }
8024
+
8025
+
8026
+ const __iconNode$n = [
8027
+ ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
8028
+ [
8029
+ "path",
8030
+ {
8031
+ d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",
8032
+ key: "11g9vi"
8033
+ }
8034
+ ]
8035
+ ];
8036
+ const Bell = createLucideIcon("bell", __iconNode$n);
8037
+
8038
+ /**
8039
+ * @license lucide-react v0.577.0 - ISC
8040
+ *
8041
+ * This source code is licensed under the ISC license.
8042
+ * See the LICENSE file in the root directory of this source tree.
8043
+ */
8044
+
8045
+
8046
+ const __iconNode$m = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
8047
+ const Check = createLucideIcon("check", __iconNode$m);
8048
+
8049
+ /**
8050
+ * @license lucide-react v0.577.0 - ISC
8051
+ *
8052
+ * This source code is licensed under the ISC license.
8053
+ * See the LICENSE file in the root directory of this source tree.
8054
+ */
8055
+
8056
+
8057
+ const __iconNode$l = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
8058
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$l);
8059
+
8060
+ /**
8061
+ * @license lucide-react v0.577.0 - ISC
8062
+ *
8063
+ * This source code is licensed under the ISC license.
8064
+ * See the LICENSE file in the root directory of this source tree.
8065
+ */
8066
+
8067
+
8068
+ const __iconNode$k = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
8069
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$k);
8070
+
8071
+ /**
8072
+ * @license lucide-react v0.577.0 - ISC
8073
+ *
8074
+ * This source code is licensed under the ISC license.
8075
+ * See the LICENSE file in the root directory of this source tree.
8076
+ */
8077
+
8078
+
8079
+ const __iconNode$j = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
8080
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$j);
8081
+
8082
+ /**
8083
+ * @license lucide-react v0.577.0 - ISC
8084
+ *
8085
+ * This source code is licensed under the ISC license.
8086
+ * See the LICENSE file in the root directory of this source tree.
8087
+ */
8088
+
8089
+
8090
+ const __iconNode$i = [
8091
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8092
+ ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
8093
+ ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
8094
+ ];
8095
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$i);
8096
+
8097
+ /**
8098
+ * @license lucide-react v0.577.0 - ISC
8099
+ *
8100
+ * This source code is licensed under the ISC license.
8101
+ * See the LICENSE file in the root directory of this source tree.
8102
+ */
8103
+
8104
+
8105
+ const __iconNode$h = [
8106
+ ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
8107
+ ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
8108
+ ];
8109
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$h);
8110
+
8111
+ /**
8112
+ * @license lucide-react v0.577.0 - ISC
8113
+ *
8114
+ * This source code is licensed under the ISC license.
8115
+ * See the LICENSE file in the root directory of this source tree.
8116
+ */
8117
+
8118
+
8119
+ const __iconNode$g = [
8120
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8121
+ ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
8122
+ ];
8123
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$g);
7822
8124
 
7823
8125
  /**
7824
- * TimeRangeDropdown - A compact dropdown for selecting time ranges
8126
+ * @license lucide-react v0.577.0 - ISC
8127
+ *
8128
+ * This source code is licensed under the ISC license.
8129
+ * See the LICENSE file in the root directory of this source tree.
7825
8130
  */
7826
- function TimeRangeDropdown({ presets, selectedPreset, onPresetSelect, onCustomRangeApply, customStart: initialCustomStart, customEnd: initialCustomEnd, disabled = false, className, displayLabel, }) {
7827
- const [open, setOpen] = React__namespace.useState(false);
7828
- const [showCustomInputs, setShowCustomInputs] = React__namespace.useState(false);
7829
- const [customStart, setCustomStart] = React__namespace.useState(initialCustomStart || '');
7830
- const [customEnd, setCustomEnd] = React__namespace.useState(initialCustomEnd || '');
7831
- // Update custom values when props change
7832
- React__namespace.useEffect(() => {
7833
- if (initialCustomStart)
7834
- setCustomStart(initialCustomStart);
7835
- if (initialCustomEnd)
7836
- setCustomEnd(initialCustomEnd);
7837
- }, [initialCustomStart, initialCustomEnd]);
7838
- const selectedPresetObj = presets.find((p) => p.key === selectedPreset);
7839
- const label$1 = displayLabel || selectedPresetObj?.label || 'Select time range';
7840
- const handlePresetClick = (presetKey) => {
7841
- onPresetSelect(presetKey);
7842
- setShowCustomInputs(false);
7843
- setOpen(false);
7844
- };
7845
- const handleCustomClick = () => {
7846
- setShowCustomInputs(true);
7847
- };
7848
- const handleCustomApply = () => {
7849
- if (customStart && customEnd) {
7850
- onCustomRangeApply(customStart, customEnd);
7851
- setShowCustomInputs(false);
7852
- setOpen(false);
7853
- }
7854
- };
7855
- const handleCustomCancel = () => {
7856
- setShowCustomInputs(false);
7857
- };
7858
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", disabled: disabled, className: cn('flex h-7 items-center gap-2 rounded-md border border-input bg-background px-2 text-xs ring-offset-background', 'hover:bg-accent hover:text-accent-foreground', 'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', className), children: [jsxRuntime.jsx(Calendar, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: label$1 }), jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[200px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "end", children: !showCustomInputs ? (jsxRuntime.jsxs("div", { className: "p-1", children: [presets.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: () => handlePresetClick(preset.key), className: cn('relative flex w-full cursor-pointer select-none items-center rounded-sm px-3 py-2 text-sm outline-none', 'hover:bg-accent hover:text-accent-foreground', selectedPreset === preset.key && 'bg-accent text-accent-foreground font-medium'), children: preset.label }, preset.key))), jsxRuntime.jsx("div", { className: "my-1 h-px bg-border" }), jsxRuntime.jsx("button", { type: "button", onClick: handleCustomClick, className: cn('relative flex w-full cursor-pointer select-none items-center rounded-sm px-3 py-2 text-sm outline-none', 'hover:bg-accent hover:text-accent-foreground', selectedPreset === 'custom' && 'bg-accent text-accent-foreground font-medium'), children: "Custom range..." })] })) : (jsxRuntime.jsxs("div", { className: "p-4 min-w-[280px]", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [jsxRuntime.jsx(label.Label, { htmlFor: "time-range-start", className: "text-xs text-muted-foreground font-semibold uppercase tracking-tight", children: "Start" }), jsxRuntime.jsx(input.Input, { id: "time-range-start", type: "datetime-local", value: customStart, onChange: (e) => setCustomStart(e.target.value), className: "w-full", disabled: disabled })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [jsxRuntime.jsx(label.Label, { htmlFor: "time-range-end", className: "text-xs text-muted-foreground font-semibold uppercase tracking-tight", children: "End" }), jsxRuntime.jsx(input.Input, { id: "time-range-end", type: "datetime-local", value: customEnd, onChange: (e) => setCustomEnd(e.target.value), className: "w-full", disabled: disabled })] })] }), jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 mt-4 pt-3 border-t border-border", children: [jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "small", onClick: handleCustomCancel, children: "Back" }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", onClick: handleCustomApply, disabled: !customStart || !customEnd, children: "Apply" })] })] })) }) })] }));
7859
- }
7860
8131
 
7861
- const TIME_PRESETS$3 = [
7862
- {
7863
- key: 'last15min',
7864
- label: 'Last 15 min',
7865
- getValue: () => ({
7866
- start: formatISO(subMinutes(new Date())),
7867
- end: formatISO(new Date()),
7868
- }),
7869
- },
7870
- {
7871
- key: 'last1hour',
7872
- label: 'Last hour',
7873
- getValue: () => ({
7874
- start: formatISO(subHours(new Date(), 1)),
7875
- end: formatISO(new Date()),
7876
- }),
7877
- },
7878
- {
7879
- key: 'last6hours',
7880
- label: 'Last 6 hours',
7881
- getValue: () => ({
7882
- start: formatISO(subHours(new Date(), 6)),
7883
- end: formatISO(new Date()),
7884
- }),
7885
- },
7886
- {
7887
- key: 'last24hours',
7888
- label: 'Last 24 hours',
7889
- getValue: () => ({
7890
- start: formatISO(subHours(new Date(), 24)),
7891
- end: formatISO(new Date()),
7892
- }),
7893
- },
7894
- {
7895
- key: 'last7days',
7896
- label: 'Last 7 days',
7897
- getValue: () => ({
7898
- start: formatISO(subDays(new Date(), 7)),
7899
- end: formatISO(new Date()),
7900
- }),
7901
- },
7902
- {
7903
- key: 'last30days',
7904
- label: 'Last 30 days',
7905
- getValue: () => ({
7906
- start: formatISO(subDays(new Date(), 30)),
7907
- end: formatISO(new Date()),
7908
- }),
7909
- },
8132
+
8133
+ const __iconNode$f = [
8134
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8135
+ ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
8136
+ ["path", { d: "m9 9 6 6", key: "z0biqf" }]
7910
8137
  ];
7911
- /** Debounce delay for text inputs (ms) */
7912
- const DEBOUNCE_DELAY = 300;
8138
+ const CircleX = createLucideIcon("circle-x", __iconNode$f);
8139
+
7913
8140
  /**
7914
- * Helper function to convert ISO string to datetime-local format
8141
+ * @license lucide-react v0.577.0 - ISC
8142
+ *
8143
+ * This source code is licensed under the ISC license.
8144
+ * See the LICENSE file in the root directory of this source tree.
7915
8145
  */
7916
- const formatDatetimeLocal$4 = (isoString) => {
7917
- const date = new Date(isoString);
7918
- const year = date.getFullYear();
7919
- const month = String(date.getMonth() + 1).padStart(2, '0');
7920
- const day = String(date.getDate()).padStart(2, '0');
7921
- const hours = String(date.getHours()).padStart(2, '0');
7922
- const minutes = String(date.getMinutes()).padStart(2, '0');
7923
- return `${year}-${month}-${day}T${hours}:${minutes}`;
7924
- };
7925
- function SimpleQueryBuilder({ client, onFilterChange, initialLimit = 100, className = '', disabled = false, }) {
7926
- const [isAdvancedExpanded, setIsAdvancedExpanded] = React.useState(false);
7927
- const [filters, setFilters] = React.useState({
7928
- verb: '',
7929
- resourceType: '',
7930
- namespace: '',
7931
- resourceName: '',
7932
- username: '',
7933
- });
7934
- const [limit, setLimit] = React.useState(initialLimit);
7935
- const [advancedFilter, setAdvancedFilter] = React.useState('');
7936
- const [useAdvancedFilter, setUseAdvancedFilter] = React.useState(false);
7937
- // Time range state
7938
- const [selectedPreset, setSelectedPreset] = React.useState('last24hours');
7939
- const [timeRange, setTimeRange] = React.useState(null);
7940
- const [customStart, setCustomStart] = React.useState(() => formatDatetimeLocal$4(formatISO(subDays(new Date(), 1))));
7941
- const [customEnd, setCustomEnd] = React.useState(() => formatDatetimeLocal$4(formatISO(new Date())));
7942
- // Fetch facets for dynamic filter options
7943
- const { verbs, resources, namespaces, usernames, isLoading: facetsLoading, error: facetsError } = useAuditLogFacets(client, timeRange);
7944
- // Log facets error for debugging
7945
- if (facetsError) {
7946
- console.error('Failed to load audit log facets:', facetsError);
7947
- }
7948
- // Refs for debouncing
7949
- const debounceTimerRef = React.useRef(null);
7950
- const isInitialMount = React.useRef(true);
7951
- // Initialize with default time range and trigger initial query
7952
- React.useEffect(() => {
7953
- const defaultRange = TIME_PRESETS$3.find(p => p.key === 'last24hours')?.getValue();
7954
- if (defaultRange) {
7955
- setTimeRange(defaultRange);
7956
- }
7957
- }, []);
7958
- const generateCEL = React.useCallback(() => {
7959
- const parts = [];
7960
- if (filters.verb) {
7961
- parts.push(`verb == "${filters.verb}"`);
7962
- }
7963
- if (filters.resourceType) {
7964
- parts.push(`objectRef.resource == "${filters.resourceType}"`);
7965
- }
7966
- if (filters.namespace) {
7967
- parts.push(`objectRef.namespace == "${filters.namespace}"`);
7968
- }
7969
- if (filters.resourceName) {
7970
- parts.push(`objectRef.name.contains("${filters.resourceName}")`);
7971
- }
7972
- if (filters.username) {
7973
- parts.push(`user.username.contains("${filters.username}")`);
7974
- }
7975
- return parts.join(' && ');
7976
- }, [filters]);
7977
- // Execute query when filters change (with debouncing for text inputs)
7978
- const executeQuery = React.useCallback(() => {
7979
- if (!timeRange || disabled)
7980
- return;
7981
- const filter = useAdvancedFilter ? advancedFilter : generateCEL();
7982
- onFilterChange({
7983
- filter,
7984
- limit,
7985
- startTime: timeRange.start,
7986
- endTime: timeRange.end
7987
- });
7988
- }, [useAdvancedFilter, advancedFilter, generateCEL, onFilterChange, limit, timeRange, disabled]);
7989
- // Auto-execute query when dropdown filters or time range change (immediate)
7990
- React.useEffect(() => {
7991
- // Skip the initial mount - we want to wait for timeRange to be set
7992
- if (isInitialMount.current) {
7993
- isInitialMount.current = false;
7994
- return;
7995
- }
7996
- // Clear any pending debounced query
7997
- if (debounceTimerRef.current) {
7998
- clearTimeout(debounceTimerRef.current);
7999
- }
8000
- executeQuery();
8001
- }, [filters.verb, filters.resourceType, timeRange, limit, useAdvancedFilter]);
8002
- // Auto-execute query when text filters change (debounced)
8003
- React.useEffect(() => {
8004
- if (isInitialMount.current || !timeRange)
8005
- return;
8006
- // Clear previous timer
8007
- if (debounceTimerRef.current) {
8008
- clearTimeout(debounceTimerRef.current);
8009
- }
8010
- // Set new debounced timer
8011
- debounceTimerRef.current = setTimeout(() => {
8012
- executeQuery();
8013
- }, DEBOUNCE_DELAY);
8014
- return () => {
8015
- if (debounceTimerRef.current) {
8016
- clearTimeout(debounceTimerRef.current);
8017
- }
8018
- };
8019
- }, [filters.namespace, filters.resourceName, filters.username, advancedFilter]);
8020
- const handleFilterChange = React.useCallback((field, value) => {
8021
- setFilters(prev => ({ ...prev, [field]: value }));
8022
- }, []);
8023
- const handleTimePresetSelect = React.useCallback((presetKey) => {
8024
- const preset = TIME_PRESETS$3.find(p => p.key === presetKey);
8025
- if (preset) {
8026
- setSelectedPreset(presetKey);
8027
- setTimeRange(preset.getValue());
8028
- }
8029
- }, []);
8030
- const handleCustomRangeApply = React.useCallback((start, end) => {
8031
- setSelectedPreset('custom');
8032
- setCustomStart(start);
8033
- setCustomEnd(end);
8034
- setTimeRange({
8035
- start: new Date(start).toISOString(),
8036
- end: new Date(end).toISOString(),
8037
- });
8038
- }, []);
8039
- const handleLimitChange = React.useCallback((newLimit) => {
8040
- const validLimit = Math.min(Math.max(1, newLimit), 1000);
8041
- setLimit(validLimit);
8042
- }, []);
8043
- const handleAdvancedToggle = React.useCallback(() => {
8044
- if (!isAdvancedExpanded) {
8045
- // When expanding, populate advanced filter with generated CEL
8046
- setAdvancedFilter(generateCEL());
8047
- }
8048
- setIsAdvancedExpanded(!isAdvancedExpanded);
8049
- }, [isAdvancedExpanded, generateCEL]);
8050
- const handleUseAdvancedChange = React.useCallback((checked) => {
8051
- setUseAdvancedFilter(checked === true);
8052
- }, []);
8053
- // Get display label for time range
8054
- const getTimeRangeLabel = () => {
8055
- if (selectedPreset === 'custom') {
8056
- if (timeRange?.start && timeRange?.end) {
8057
- const start = new Date(timeRange.start);
8058
- const end = new Date(timeRange.end);
8059
- return `${start.toLocaleDateString()} - ${end.toLocaleDateString()}`;
8060
- }
8061
- return 'Custom';
8062
- }
8063
- const preset = TIME_PRESETS$3.find(p => p.key === selectedPreset);
8064
- return preset?.label || 'Select time range';
8065
- };
8066
- return (jsxRuntime.jsxs("div", { className: `mb-6 pb-6 border-b border-border ${className}`, children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-4 items-end", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Action" }), jsxRuntime.jsx(Combobox, { options: verbs
8067
- .filter(facet => facet.value)
8068
- .map(facet => ({
8069
- value: facet.value,
8070
- label: facet.value,
8071
- count: facet.count,
8072
- })), value: filters.verb, onValueChange: (value) => handleFilterChange('verb', value), placeholder: "All", searchPlaceholder: "Search actions...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Resource" }), jsxRuntime.jsx(Combobox, { options: resources
8073
- .filter(facet => facet.value)
8074
- .map(facet => ({
8075
- value: facet.value,
8076
- label: facet.value,
8077
- count: facet.count,
8078
- })), value: filters.resourceType, onValueChange: (value) => handleFilterChange('resourceType', value), placeholder: "All", searchPlaceholder: "Search resources...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Namespace" }), jsxRuntime.jsx(Combobox, { options: namespaces
8079
- .filter(facet => facet.value)
8080
- .map(facet => ({
8081
- value: facet.value,
8082
- label: facet.value,
8083
- count: facet.count,
8084
- })), value: filters.namespace, onValueChange: (value) => handleFilterChange('namespace', value), placeholder: "All", searchPlaceholder: "Search namespaces...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "User" }), jsxRuntime.jsx(Combobox, { options: usernames
8085
- .filter(facet => facet.value)
8086
- .map(facet => ({
8087
- value: facet.value,
8088
- label: facet.value,
8089
- count: facet.count,
8090
- })), value: filters.username, onValueChange: (value) => handleFilterChange('username', value), placeholder: "All", searchPlaceholder: "Search users...", allOptionLabel: "All", disabled: disabled || useAdvancedFilter, loading: facetsLoading, className: "min-w-[130px]" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Name" }), jsxRuntime.jsx(input.Input, { type: "text", value: filters.resourceName, onChange: (e) => handleFilterChange('resourceName', e.target.value), placeholder: "Filter by name...", className: "min-w-[140px]", disabled: disabled || useAdvancedFilter })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Limit" }), jsxRuntime.jsx(input.Input, { type: "number", value: limit, onChange: (e) => handleLimitChange(parseInt(e.target.value) || 100), min: 1, max: 1000, className: "w-[80px]", disabled: disabled })] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "small", className: "whitespace-nowrap text-muted-foreground hover:text-foreground", onClick: handleAdvancedToggle, "aria-expanded": isAdvancedExpanded, children: isAdvancedExpanded ? '- CEL' : '+ CEL' }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 ml-auto", children: [jsxRuntime.jsx(label.Label, { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: "Time Range" }), jsxRuntime.jsx(TimeRangeDropdown, { presets: TIME_PRESETS$3.map(p => ({ key: p.key, label: p.label })), selectedPreset: selectedPreset, onPresetSelect: handleTimePresetSelect, onCustomRangeApply: handleCustomRangeApply, customStart: customStart, customEnd: customEnd, disabled: disabled, displayLabel: getTimeRangeLabel() })] })] }), isAdvancedExpanded && (jsxRuntime.jsxs("div", { className: "mt-4 pt-4", children: [jsxRuntime.jsx(separator.Separator, { className: "mb-4" }), jsxRuntime.jsx("div", { className: "mb-3", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(checkbox.Checkbox, { id: "use-cel-expression", checked: useAdvancedFilter, onCheckedChange: handleUseAdvancedChange, disabled: disabled }), jsxRuntime.jsx(label.Label, { htmlFor: "use-cel-expression", className: "text-sm font-medium text-foreground cursor-pointer", children: "Use CEL Expression" })] }) }), useAdvancedFilter && (jsxRuntime.jsxs("div", { className: "mt-3", children: [jsxRuntime.jsx("p", { className: "m-0 mb-2 text-sm text-muted-foreground", children: "Write your query using CEL syntax for complex filters" }), jsxRuntime.jsx(textarea.Textarea, { value: advancedFilter, onChange: (e) => setAdvancedFilter(e.target.value), placeholder: 'Example: verb == "delete" && objectRef.namespace == "production"', rows: 3, className: "w-full font-mono resize-y", disabled: disabled })] }))] }))] }));
8091
- }
8146
+
8147
+
8148
+ const __iconNode$e = [
8149
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8150
+ ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
8151
+ ];
8152
+ const Clock = createLucideIcon("clock", __iconNode$e);
8092
8153
 
8093
8154
  /**
8094
- * Get icon for tenant type
8155
+ * @license lucide-react v0.577.0 - ISC
8156
+ *
8157
+ * This source code is licensed under the ISC license.
8158
+ * See the LICENSE file in the root directory of this source tree.
8095
8159
  */
8096
- function getTenantIcon(type) {
8097
- switch (type) {
8098
- case "organization":
8099
- return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" }) }));
8100
- case "project":
8101
- return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" }) }));
8102
- case "user":
8103
- return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }));
8104
- case "platform":
8105
- return (jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }));
8106
- default:
8107
- return null;
8108
- }
8109
- }
8160
+
8161
+
8162
+ const __iconNode$d = [
8163
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
8164
+ ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
8165
+ ];
8166
+ const Copy = createLucideIcon("copy", __iconNode$d);
8167
+
8110
8168
  /**
8111
- * Get badge variant based on tenant type
8169
+ * @license lucide-react v0.577.0 - ISC
8170
+ *
8171
+ * This source code is licensed under the ISC license.
8172
+ * See the LICENSE file in the root directory of this source tree.
8112
8173
  */
8113
- function getTenantBadgeVariant(type) {
8114
- switch (type) {
8115
- case "organization":
8116
- return "default";
8117
- case "project":
8118
- return "secondary";
8119
- case "user":
8120
- return "default";
8121
- case "platform":
8122
- return "default";
8123
- default:
8124
- return "secondary";
8174
+
8175
+
8176
+ const __iconNode$c = [
8177
+ [
8178
+ "path",
8179
+ {
8180
+ d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",
8181
+ key: "1nclc0"
8125
8182
  }
8126
- }
8183
+ ],
8184
+ ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
8185
+ ];
8186
+ const Eye = createLucideIcon("eye", __iconNode$c);
8187
+
8127
8188
  /**
8128
- * TenantBadge displays tenant information in a compact badge format
8129
- * Renders as a clickable link if tenantLinkResolver is provided and returns a URL
8189
+ * @license lucide-react v0.577.0 - ISC
8190
+ *
8191
+ * This source code is licensed under the ISC license.
8192
+ * See the LICENSE file in the root directory of this source tree.
8130
8193
  */
8131
- function TenantBadge({ tenant, tenantLinkResolver, className = "", size = "default", }) {
8132
- const icon = getTenantIcon(tenant.type);
8133
- const variant = getTenantBadgeVariant(tenant.type);
8134
- const url = tenantLinkResolver?.(tenant);
8135
- const badgeContent = (jsxRuntime.jsxs(Badge, { variant: variant, className: cn("inline-flex items-center gap-1 whitespace-nowrap", size === "compact" ? "text-xs h-4 py-0 px-1.5" : "text-xs h-5 px-2", url && "cursor-pointer hover:opacity-80 transition-opacity", className), children: [icon, jsxRuntime.jsx("span", { className: "font-medium capitalize", children: tenant.type }), tenant.type !== "platform" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "/" }), jsxRuntime.jsx("span", { children: tenant.name })] }))] }));
8136
- if (url) {
8137
- return (jsxRuntime.jsx("a", { href: url, className: "no-underline", onClick: (e) => e.stopPropagation(), title: `View ${tenant.type}: ${tenant.name}`, children: badgeContent }));
8194
+
8195
+
8196
+ const __iconNode$b = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
8197
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$b);
8198
+
8199
+ /**
8200
+ * @license lucide-react v0.577.0 - ISC
8201
+ *
8202
+ * This source code is licensed under the ISC license.
8203
+ * See the LICENSE file in the root directory of this source tree.
8204
+ */
8205
+
8206
+
8207
+ const __iconNode$a = [
8208
+ [
8209
+ "path",
8210
+ {
8211
+ d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
8212
+ key: "1a8usu"
8138
8213
  }
8139
- return badgeContent;
8140
- }
8214
+ ],
8215
+ ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
8216
+ ];
8217
+ const Pencil = createLucideIcon("pencil", __iconNode$a);
8141
8218
 
8142
8219
  /**
8143
- * Extract tenant information from audit event annotations if present
8144
- * Expected annotations: tenant.type and tenant.name
8220
+ * @license lucide-react v0.577.0 - ISC
8221
+ *
8222
+ * This source code is licensed under the ISC license.
8223
+ * See the LICENSE file in the root directory of this source tree.
8145
8224
  */
8146
- function extractTenantFromAnnotations(event) {
8147
- const annotations = event.annotations;
8148
- if (!annotations)
8149
- return undefined;
8150
- const tenantType = annotations["tenant.type"];
8151
- const tenantName = annotations["tenant.name"];
8152
- if (tenantType && tenantName) {
8153
- const validTypes = [
8154
- "platform",
8155
- "organization",
8156
- "project",
8157
- "user",
8158
- ];
8159
- if (validTypes.includes(tenantType)) {
8160
- return {
8161
- type: tenantType,
8162
- name: tenantName,
8163
- };
8164
- }
8225
+
8226
+
8227
+ const __iconNode$9 = [
8228
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
8229
+ ["path", { d: "M12 5v14", key: "s699le" }]
8230
+ ];
8231
+ const Plus = createLucideIcon("plus", __iconNode$9);
8232
+
8233
+ /**
8234
+ * @license lucide-react v0.577.0 - ISC
8235
+ *
8236
+ * This source code is licensed under the ISC license.
8237
+ * See the LICENSE file in the root directory of this source tree.
8238
+ */
8239
+
8240
+
8241
+ const __iconNode$8 = [
8242
+ ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
8243
+ ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
8244
+ ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
8245
+ ["path", { d: "M8 16H3v5", key: "1cv678" }]
8246
+ ];
8247
+ const RefreshCw = createLucideIcon("refresh-cw", __iconNode$8);
8248
+
8249
+ /**
8250
+ * @license lucide-react v0.577.0 - ISC
8251
+ *
8252
+ * This source code is licensed under the ISC license.
8253
+ * See the LICENSE file in the root directory of this source tree.
8254
+ */
8255
+
8256
+
8257
+ const __iconNode$7 = [
8258
+ ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
8259
+ ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
8260
+ ];
8261
+ const RotateCw = createLucideIcon("rotate-cw", __iconNode$7);
8262
+
8263
+ /**
8264
+ * @license lucide-react v0.577.0 - ISC
8265
+ *
8266
+ * This source code is licensed under the ISC license.
8267
+ * See the LICENSE file in the root directory of this source tree.
8268
+ */
8269
+
8270
+
8271
+ const __iconNode$6 = [
8272
+ ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
8273
+ ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
8274
+ ];
8275
+ const Search = createLucideIcon("search", __iconNode$6);
8276
+
8277
+ /**
8278
+ * @license lucide-react v0.577.0 - ISC
8279
+ *
8280
+ * This source code is licensed under the ISC license.
8281
+ * See the LICENSE file in the root directory of this source tree.
8282
+ */
8283
+
8284
+
8285
+ const __iconNode$5 = [
8286
+ ["path", { d: "M10 5H3", key: "1qgfaw" }],
8287
+ ["path", { d: "M12 19H3", key: "yhmn1j" }],
8288
+ ["path", { d: "M14 3v4", key: "1sua03" }],
8289
+ ["path", { d: "M16 17v4", key: "1q0r14" }],
8290
+ ["path", { d: "M21 12h-9", key: "1o4lsq" }],
8291
+ ["path", { d: "M21 19h-5", key: "1rlt1p" }],
8292
+ ["path", { d: "M21 5h-7", key: "1oszz2" }],
8293
+ ["path", { d: "M8 10v4", key: "tgpxqk" }],
8294
+ ["path", { d: "M8 12H3", key: "a7s4jb" }]
8295
+ ];
8296
+ const SlidersHorizontal = createLucideIcon("sliders-horizontal", __iconNode$5);
8297
+
8298
+ /**
8299
+ * @license lucide-react v0.577.0 - ISC
8300
+ *
8301
+ * This source code is licensed under the ISC license.
8302
+ * See the LICENSE file in the root directory of this source tree.
8303
+ */
8304
+
8305
+
8306
+ const __iconNode$4 = [
8307
+ ["path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1m0v6g" }],
8308
+ [
8309
+ "path",
8310
+ {
8311
+ d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",
8312
+ key: "ohrbg2"
8165
8313
  }
8166
- return undefined;
8167
- }
8314
+ ]
8315
+ ];
8316
+ const SquarePen = createLucideIcon("square-pen", __iconNode$4);
8317
+
8168
8318
  /**
8169
- * AuditEventViewer displays a list of audit events with details
8319
+ * @license lucide-react v0.577.0 - ISC
8320
+ *
8321
+ * This source code is licensed under the ISC license.
8322
+ * See the LICENSE file in the root directory of this source tree.
8170
8323
  */
8171
- function AuditEventViewer({ events, className = "", onEventSelect, tenantLinkResolver, }) {
8172
- const [selectedEvent, setSelectedEvent] = React.useState(null);
8173
- const [expandedEvents, setExpandedEvents] = React.useState(new Set());
8174
- const toggleEventExpansion = (auditId) => {
8175
- const newExpanded = new Set(expandedEvents);
8176
- if (expandedEvents.has(auditId)) {
8177
- newExpanded.delete(auditId);
8178
- }
8179
- else {
8180
- newExpanded.add(auditId);
8181
- }
8182
- setExpandedEvents(newExpanded);
8183
- };
8184
- const handleEventClick = (event) => {
8185
- setSelectedEvent(event);
8186
- if (onEventSelect) {
8187
- onEventSelect(event);
8188
- }
8189
- };
8190
- const formatTimestamp = (timestamp) => {
8191
- if (!timestamp)
8192
- return "N/A";
8193
- try {
8194
- return format(new Date(timestamp), "yyyy-MM-dd HH:mm:ss");
8195
- }
8196
- catch {
8197
- return timestamp;
8198
- }
8199
- };
8200
- const getVerbBadgeVariant = (verb) => {
8201
- switch (verb?.toLowerCase()) {
8202
- case "create":
8203
- return "success";
8204
- case "update":
8205
- case "patch":
8206
- return "warning";
8207
- case "delete":
8208
- return "destructive";
8209
- case "get":
8210
- case "list":
8211
- case "watch":
8212
- return "default";
8213
- default:
8214
- return "secondary";
8215
- }
8216
- };
8217
- if (events.length === 0) {
8218
- return (jsxRuntime.jsx("div", { className: `bg-muted rounded-lg border border-border ${className}`, children: jsxRuntime.jsx("div", { className: "p-12 text-center text-muted-foreground text-sm", children: "No events found" }) }));
8324
+
8325
+
8326
+ const __iconNode$3 = [
8327
+ ["path", { d: "M10 11v6", key: "nco0om" }],
8328
+ ["path", { d: "M14 11v6", key: "outv1u" }],
8329
+ ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
8330
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
8331
+ ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
8332
+ ];
8333
+ const Trash2 = createLucideIcon("trash-2", __iconNode$3);
8334
+
8335
+ /**
8336
+ * @license lucide-react v0.577.0 - ISC
8337
+ *
8338
+ * This source code is licensed under the ISC license.
8339
+ * See the LICENSE file in the root directory of this source tree.
8340
+ */
8341
+
8342
+
8343
+ const __iconNode$2 = [
8344
+ [
8345
+ "path",
8346
+ {
8347
+ d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
8348
+ key: "wmoenq"
8219
8349
  }
8220
- return (jsxRuntime.jsx("div", { className: `bg-muted rounded-lg border border-border ${className}`, children: jsxRuntime.jsx("div", { className: "p-4", children: events.map((event) => {
8221
- const auditId = event.auditID || "";
8222
- const isExpanded = expandedEvents.has(auditId);
8223
- const tenant = extractTenantFromAnnotations(event);
8224
- return (jsxRuntime.jsxs(card.Card, { className: `p-5 mb-3 cursor-pointer transition-all hover:border-primary/50 hover:shadow-sm hover:-translate-y-px ${selectedEvent?.auditID === auditId
8225
- ? "border-primary bg-primary/5 shadow-md"
8226
- : ""}`, onClick: () => handleEventClick(event), children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsxs("div", { className: "flex gap-3 items-center flex-1", children: [jsxRuntime.jsx(Badge, { variant: getVerbBadgeVariant(event.verb), className: "px-3 py-1", children: event.verb?.toUpperCase() || "UNKNOWN" }), jsxRuntime.jsx("span", { className: "font-semibold", children: event.objectRef?.resource || "N/A" }), event.objectRef?.namespace && (jsxRuntime.jsxs("span", { className: "text-muted-foreground text-sm", children: ["ns: ", event.objectRef.namespace] })), event.objectRef?.name && (jsxRuntime.jsx("span", { className: "text-foreground/80 text-sm", children: event.objectRef.name })), tenant && (jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver, size: "compact" }))] }), jsxRuntime.jsxs("div", { className: "flex gap-4 items-center", children: [jsxRuntime.jsx("span", { className: "text-foreground/80 text-sm", children: event.user?.username || "N/A" }), jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm font-mono", children: formatTimestamp(event.stageTimestamp) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", onClick: (e) => {
8227
- e.stopPropagation();
8228
- toggleEventExpansion(auditId);
8229
- }, className: "text-primary", children: isExpanded ? "▼" : "▶" })] })] }), isExpanded && (jsxRuntime.jsxs("div", { className: "mt-4 pt-4 border-t border-border", children: [jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Event Information" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Audit ID:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.auditID || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Stage:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.stage || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Level:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.level || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Request URI:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground font-mono text-sm break-all", children: event.requestURI || "N/A" }), event.userAgent && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "User Agent:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground font-mono text-sm break-all", children: event.userAgent })] })), event.sourceIPs && event.sourceIPs.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Source IPs:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.sourceIPs.join(", ") })] }))] })] }), tenant && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Tenant" }), jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver })] })), event.user && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "User Information" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Username:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.username || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "UID:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.uid || "N/A" }), event.user.groups && event.user.groups.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Groups:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.user.groups.join(", ") })] }))] })] })), event.responseStatus && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Response Status" }), jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Code:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.code || "N/A" }), jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Status:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.status || "N/A" }), event.responseStatus.message && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dt", { className: "font-semibold text-foreground/80", children: "Message:" }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: event.responseStatus.message })] }))] })] })), event.annotations &&
8230
- Object.keys(event.annotations).length > 0 && (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Annotations" }), jsxRuntime.jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-2 m-0", children: Object.entries(event.annotations).map(([key, value]) => (jsxRuntime.jsxs("div", { className: "contents", children: [jsxRuntime.jsxs("dt", { className: "font-semibold text-foreground/80", children: [key, ":"] }), jsxRuntime.jsx("dd", { className: "m-0 text-foreground", children: value })] }, key))) })] })), event.requestObject || event.responseObject ? (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "mt-0 mb-2 text-base text-foreground/80", children: "Request/Response Data" }), event.requestObject ? (jsxRuntime.jsxs("details", { className: "mt-2", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer font-semibold p-2 bg-muted rounded", children: "Request Object" }), jsxRuntime.jsx("pre", { className: "mt-2 p-4 bg-muted rounded overflow-x-auto text-sm", children: JSON.stringify(event.requestObject, null, 2) })] })) : null, event.responseObject ? (jsxRuntime.jsxs("details", { className: "mt-2", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer font-semibold p-2 bg-muted rounded", children: "Response Object" }), jsxRuntime.jsx("pre", { className: "mt-2 p-4 bg-muted rounded overflow-x-auto text-sm", children: JSON.stringify(event.responseObject, null, 2) })] })) : null] })) : null] }))] }, auditId));
8231
- }) }) }));
8232
- }
8350
+ ],
8351
+ ["path", { d: "M12 9v4", key: "juzpu7" }],
8352
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
8353
+ ];
8354
+ const TriangleAlert = createLucideIcon("triangle-alert", __iconNode$2);
8355
+
8356
+ /**
8357
+ * @license lucide-react v0.577.0 - ISC
8358
+ *
8359
+ * This source code is licensed under the ISC license.
8360
+ * See the LICENSE file in the root directory of this source tree.
8361
+ */
8362
+
8363
+
8364
+ const __iconNode$1 = [
8365
+ ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
8366
+ ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
8367
+ ];
8368
+ const User = createLucideIcon("user", __iconNode$1);
8369
+
8370
+ /**
8371
+ * @license lucide-react v0.577.0 - ISC
8372
+ *
8373
+ * This source code is licensed under the ISC license.
8374
+ * See the LICENSE file in the root directory of this source tree.
8375
+ */
8376
+
8377
+
8378
+ const __iconNode = [
8379
+ ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
8380
+ ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
8381
+ ];
8382
+ const X = createLucideIcon("x", __iconNode);
8233
8383
 
8234
8384
  /**
8235
8385
  * FilterChip - A compact pill/chip showing "Label: Values" with clear button
@@ -8354,7 +8504,7 @@ function FilterChip({ label, values, options = [], onValuesChange, onClear, inpu
8354
8504
  }, [options]);
8355
8505
  // Find selected options for chips display
8356
8506
  const selectedOptions = options.filter((opt) => values.includes(opt.value));
8357
- return (jsxRuntime.jsxs("div", { className: cn('inline-flex items-center', className), children: [jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: handleOpenChange, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", disabled: disabled, className: cn('flex h-7 items-center gap-2 rounded-l-md border border-r-0 border-border bg-card px-2 text-xs outline-none', 'hover:bg-accent/40 data-[state=open]:bg-accent/40 transition-colors', 'disabled:cursor-not-allowed disabled:opacity-50'), children: [jsxRuntime.jsxs("span", { className: "font-medium text-foreground", children: [label, ":"] }), jsxRuntime.jsx("span", { className: "text-foreground truncate max-w-[120px]", children: displayValue }), jsxRuntime.jsx(ChevronDown, { className: "h-3 w-3 text-muted-foreground ml-1" })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[var(--radix-popover-trigger-width)] max-w-[320px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "start", children: inputMode === 'typeahead' ? (jsxRuntime.jsxs(cmdk.Command, { filter: filterOptions, className: "w-full", children: [jsxRuntime.jsx("div", { className: "flex items-center border-b px-3", children: jsxRuntime.jsx(cmdk.CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch, className: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" }) }), values.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 p-2 border-b", children: selectedOptions.map((option) => (jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-accent text-accent-foreground text-xs", children: [option.label, jsxRuntime.jsx("button", { type: "button", onClick: (e) => handleRemoveValue(e, option.value), className: "rounded-sm hover:bg-accent-foreground/20", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) })] }, option.value))) })), jsxRuntime.jsxs(cmdk.CommandList, { className: "max-h-[300px] overflow-y-auto p-1", children: [jsxRuntime.jsx(cmdk.CommandEmpty, { className: "py-6 text-center text-sm text-muted-foreground", children: "No results found." }), jsxRuntime.jsx(cmdk.CommandGroup, { children: options.map((option) => (jsxRuntime.jsxs(cmdk.CommandItem, { value: option.value, onSelect: () => handleSelect(option.value), className: cn('relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none', 'data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground', 'hover:bg-accent hover:text-accent-foreground'), children: [jsxRuntime.jsx("div", { className: cn('mr-2 h-4 w-4 shrink-0 rounded-sm border border-border', values.includes(option.value) && 'bg-primary border-primary'), children: values.includes(option.value) && (jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", fill: "none", className: "h-full w-full p-0.5 text-primary-foreground", children: jsxRuntime.jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })) }), jsxRuntime.jsx("span", { className: "flex-1 truncate", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value))) })] })] })) : (jsxRuntime.jsx("div", { className: "p-3", children: jsxRuntime.jsx(input.Input, { type: "text", value: textValue, onChange: handleTextChange, placeholder: placeholder, className: "w-full", autoFocus: true }) })) }) })] }), jsxRuntime.jsx("button", { type: "button", onClick: handleClearAll, disabled: disabled, className: cn('flex h-7 items-center rounded-r-md border border-border bg-card px-2 outline-none', 'hover:bg-accent/40 transition-colors', 'disabled:cursor-not-allowed disabled:opacity-50'), "aria-label": `Clear ${label} filter`, children: jsxRuntime.jsx(X, { className: "h-3 w-3 text-muted-foreground" }) })] }));
8507
+ return (jsxRuntime.jsxs(buttonGroup.ButtonGroup, { "aria-label": `${label} filter`, className: className, children: [jsxRuntime.jsxs(popover.Popover, { open: open, onOpenChange: handleOpenChange, children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { htmlType: "button", type: "quaternary", theme: "outline", size: "small", disabled: disabled, className: "gap-2 font-normal data-[state=open]:bg-btn-neutral-bg", children: [jsxRuntime.jsxs("span", { className: "font-medium", children: [label, ":"] }), jsxRuntime.jsx("span", { className: "truncate max-w-[120px]", children: displayValue }), jsxRuntime.jsx(ChevronDown, { className: "h-3 w-3 text-muted-foreground" })] }) }), jsxRuntime.jsx(popover.PopoverContent, { className: "w-auto min-w-[var(--radix-popover-trigger-width)] max-w-[320px] p-0", sideOffset: 4, align: "start", children: inputMode === 'typeahead' ? (jsxRuntime.jsxs(command.Command, { filter: filterOptions, children: [jsxRuntime.jsx(command.CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch }), values.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 p-2 border-b", children: selectedOptions.map((option) => (jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-accent text-accent-foreground text-xs", children: [option.label, jsxRuntime.jsx("button", { type: "button", onClick: (e) => handleRemoveValue(e, option.value), className: "rounded-sm hover:bg-accent-foreground/20", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) })] }, option.value))) })), jsxRuntime.jsxs(command.CommandList, { children: [jsxRuntime.jsx(command.CommandEmpty, { children: "No results found." }), jsxRuntime.jsx(command.CommandGroup, { children: options.map((option) => (jsxRuntime.jsxs(command.CommandItem, { value: option.value, onSelect: () => handleSelect(option.value), children: [jsxRuntime.jsx("div", { className: cn('mr-2 h-4 w-4 shrink-0 rounded-sm border border-border', values.includes(option.value) && 'bg-primary border-primary'), children: values.includes(option.value) && (jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", fill: "none", className: "h-full w-full p-0.5 text-primary-foreground", children: jsxRuntime.jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })) }), jsxRuntime.jsx("span", { className: "flex-1 truncate", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value))) })] })] })) : (jsxRuntime.jsx("div", { className: "p-3", children: jsxRuntime.jsx(input.Input, { type: "text", value: textValue, onChange: handleTextChange, placeholder: placeholder, className: "w-full", autoFocus: true }) })) })] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "outline", size: "small", onClick: handleClearAll, disabled: disabled, "aria-label": `Clear ${label} filter`, children: jsxRuntime.jsx(X, { className: "h-3 w-3 text-muted-foreground" }) })] }));
8358
8508
  }
8359
8509
 
8360
8510
  /**
@@ -8371,12 +8521,12 @@ function AddFilterDropdown({ availableFilters, activeFilterIds, onAddFilter, has
8371
8521
  const isFilterActive = (filterId) => activeFilterIds.includes(filterId);
8372
8522
  // Get button label
8373
8523
  const buttonLabel = hasActiveFilters ? 'Filters' : 'Add Filters';
8374
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", disabled: disabled, className: cn('flex h-7 items-center gap-2 rounded-md border border-dashed border-border bg-background px-2 text-xs', 'text-muted-foreground hover:text-foreground hover:border-foreground/50 transition-colors', 'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', className), children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "font-medium", children: buttonLabel })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[180px] overflow-hidden rounded-md border shadow-md', 'bg-white dark:bg-slate-900 text-foreground', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "start", children: jsxRuntime.jsx("div", { className: "p-1", children: availableFilters.map((filter) => {
8375
- const active = isFilterActive(filter.id);
8376
- return (jsxRuntime.jsxs("button", { type: "button", onClick: () => !active && handleFilterClick(filter.id), disabled: active, className: cn('relative flex w-full items-center gap-2 rounded-sm px-3 py-2 text-sm outline-none transition-colors', active
8377
- ? 'cursor-not-allowed opacity-40'
8378
- : 'cursor-pointer hover:bg-accent hover:text-accent-foreground'), children: [filter.icon && jsxRuntime.jsx("span", { className: "text-muted-foreground", children: filter.icon }), jsxRuntime.jsx("span", { children: filter.label }), active && (jsxRuntime.jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: "(active)" }))] }, filter.id));
8379
- }) }) }) })] }));
8524
+ return (jsxRuntime.jsxs(popover.Popover, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { htmlType: "button", type: "quaternary", theme: "outline", size: "small", disabled: disabled, className: cn('gap-1.5 border-dashed text-muted-foreground hover:text-foreground', className), children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "font-medium", children: buttonLabel })] }) }), jsxRuntime.jsx(popover.PopoverContent, { className: "w-auto min-w-[180px] p-0", sideOffset: 4, align: "start", children: jsxRuntime.jsx("div", { className: "p-1", children: availableFilters.map((filter) => {
8525
+ const active = isFilterActive(filter.id);
8526
+ return (jsxRuntime.jsxs("button", { type: "button", onClick: () => !active && handleFilterClick(filter.id), disabled: active, className: cn('relative flex w-full items-center gap-2 rounded-sm px-3 py-2 text-sm outline-none transition-colors', active
8527
+ ? 'cursor-not-allowed opacity-40'
8528
+ : 'cursor-pointer hover:bg-accent hover:text-accent-foreground'), children: [filter.icon && jsxRuntime.jsx("span", { className: "text-muted-foreground", children: filter.icon }), jsxRuntime.jsx("span", { children: filter.label }), active && (jsxRuntime.jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: "(active)" }))] }, filter.id));
8529
+ }) }) })] }));
8380
8530
  }
8381
8531
 
8382
8532
  /**
@@ -8400,10 +8550,10 @@ function ActionMultiSelect({ value, onChange, className = '', disabled = false,
8400
8550
  return '1 action';
8401
8551
  return `${value.length} actions`;
8402
8552
  }, [value.length]);
8403
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", disabled: disabled || isLoading, className: cn('flex h-7 items-center justify-between gap-2 rounded-md border border-input bg-background px-2 text-xs min-w-[100px]', 'hover:bg-accent hover:text-accent-foreground transition-colors', 'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', className), children: [jsxRuntime.jsx("span", { className: "font-medium", children: displayText }), jsxRuntime.jsx(ChevronDown, { className: "h-3 w-3 text-muted-foreground shrink-0" })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[160px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "start", children: jsxRuntime.jsx("div", { className: "p-1", children: isLoading ? (jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "Loading..." })) : options.length === 0 ? (jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "No actions found" })) : (options.map((option) => {
8404
- const checked = value.includes(option.value);
8405
- return (jsxRuntime.jsxs("label", { className: cn('flex items-center gap-2 rounded-sm px-3 py-2 text-sm cursor-pointer', 'hover:bg-accent hover:text-accent-foreground transition-colors'), children: [jsxRuntime.jsx(checkbox.Checkbox, { checked: checked, onCheckedChange: () => handleToggle(option.value), className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "flex-1", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value));
8406
- })) }) }) })] }));
8553
+ return (jsxRuntime.jsxs(popover.Popover, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { htmlType: "button", type: "quaternary", theme: "outline", size: "small", disabled: disabled || isLoading, className: cn('min-w-[100px] justify-between gap-2', className), children: [jsxRuntime.jsx("span", { className: "font-medium", children: displayText }), jsxRuntime.jsx(ChevronDown, { className: "h-3 w-3 text-muted-foreground shrink-0" })] }) }), jsxRuntime.jsx(popover.PopoverContent, { className: "w-auto min-w-[160px] p-0", sideOffset: 4, align: "start", children: jsxRuntime.jsx("div", { className: "p-1", children: isLoading ? (jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "Loading..." })) : options.length === 0 ? (jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "No actions found" })) : (options.map((option) => {
8554
+ const checked = value.includes(option.value);
8555
+ return (jsxRuntime.jsxs("label", { className: cn('flex items-center gap-2 rounded-sm px-3 py-2 text-sm cursor-pointer', 'hover:bg-accent hover:text-accent-foreground transition-colors'), children: [jsxRuntime.jsx(checkbox.Checkbox, { checked: checked, onCheckedChange: () => handleToggle(option.value), className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "flex-1", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value));
8556
+ })) }) })] }));
8407
8557
  }
8408
8558
 
8409
8559
  /**
@@ -8435,7 +8585,7 @@ function UserSelect({ value, options, onChange, className = '', disabled = false
8435
8585
  e.stopPropagation();
8436
8586
  onChange(undefined);
8437
8587
  }, [onChange]);
8438
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", disabled: disabled, className: cn('h-7 text-xs font-medium gap-1.5 px-2', value && 'pr-1', className), children: [jsxRuntime.jsx(User, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: displayLabel }), value && (jsxRuntime.jsx("button", { onClick: handleClear, className: "ml-1 rounded-sm opacity-70 hover:opacity-100 hover:bg-muted p-0.5", "aria-label": "Clear user filter", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) }))] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsxs(Popover__namespace.Content, { className: "z-50 w-64 rounded-md border bg-popover p-0 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", align: "start", sideOffset: 4, children: [jsxRuntime.jsx("div", { className: "border-b p-2", children: jsxRuntime.jsx("input", { type: "text", placeholder: "Search users...", value: search, onChange: (e) => setSearch(e.target.value), className: "w-full rounded-md border border-input bg-background px-2 py-1.5 text-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-0", autoFocus: true }) }), jsxRuntime.jsxs("div", { className: "max-h-64 overflow-y-auto p-1", children: [jsxRuntime.jsxs("button", { onClick: () => handleSelect(undefined), className: cn('w-full flex items-center justify-between rounded-sm px-2 py-1.5 text-xs cursor-pointer hover:bg-accent hover:text-accent-foreground', !value && 'bg-accent text-accent-foreground'), children: [jsxRuntime.jsx("span", { className: "font-medium", children: "All Users" }), options.length > 0 && (jsxRuntime.jsx("span", { className: "text-muted-foreground", children: options.reduce((sum, opt) => sum + (opt.count || 0), 0) }))] }), isLoading && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "Loading users..." })), !isLoading && filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "mt-1 border-t pt-1", children: filteredOptions.map((option) => (jsxRuntime.jsxs("button", { onClick: () => handleSelect(option.value), className: cn('w-full flex items-center justify-between rounded-sm px-2 py-1.5 text-xs cursor-pointer hover:bg-accent hover:text-accent-foreground', value === option.value && 'bg-accent text-accent-foreground'), children: [jsxRuntime.jsx("span", { className: "truncate font-medium", children: option.label }), option.count !== undefined && (jsxRuntime.jsx("span", { className: "text-muted-foreground ml-2 flex-shrink-0", children: option.count }))] }, option.value))) })), !isLoading && filteredOptions.length === 0 && search && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "No users found" })), !isLoading && options.length === 0 && !search && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "No users available" }))] })] }) })] }));
8588
+ return (jsxRuntime.jsxs(popover.Popover, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", disabled: disabled, className: cn('gap-1.5', value && 'pr-1.5', className), children: [jsxRuntime.jsx(User, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: displayLabel }), value && (jsxRuntime.jsx("button", { onClick: handleClear, className: "ml-1 rounded-sm opacity-70 hover:opacity-100 hover:bg-muted p-0.5", "aria-label": "Clear user filter", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) }))] }) }), jsxRuntime.jsxs(popover.PopoverContent, { className: "w-64 p-0", align: "start", sideOffset: 4, children: [jsxRuntime.jsx("div", { className: "border-b p-2", children: jsxRuntime.jsx("input", { type: "text", placeholder: "Search users...", value: search, onChange: (e) => setSearch(e.target.value), className: "w-full rounded-md border border-input bg-background px-2 py-1.5 text-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-0", autoFocus: true }) }), jsxRuntime.jsxs("div", { className: "max-h-64 overflow-y-auto p-1", children: [jsxRuntime.jsxs("button", { onClick: () => handleSelect(undefined), className: cn('w-full flex items-center justify-between rounded-sm px-2 py-1.5 text-xs cursor-pointer hover:bg-accent hover:text-accent-foreground', !value && 'bg-accent text-accent-foreground'), children: [jsxRuntime.jsx("span", { className: "font-medium", children: "All Users" }), options.length > 0 && (jsxRuntime.jsx("span", { className: "text-muted-foreground", children: options.reduce((sum, opt) => sum + (opt.count || 0), 0) }))] }), isLoading && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "Loading users..." })), !isLoading && filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "mt-1 border-t pt-1", children: filteredOptions.map((option) => (jsxRuntime.jsxs("button", { onClick: () => handleSelect(option.value), className: cn('w-full flex items-center justify-between rounded-sm px-2 py-1.5 text-xs cursor-pointer hover:bg-accent hover:text-accent-foreground', value === option.value && 'bg-accent text-accent-foreground'), children: [jsxRuntime.jsx("span", { className: "truncate font-medium", children: option.label }), option.count !== undefined && (jsxRuntime.jsx("span", { className: "text-muted-foreground ml-2 flex-shrink-0", children: option.count }))] }, option.value))) })), !isLoading && filteredOptions.length === 0 && search && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "No users found" })), !isLoading && options.length === 0 && !search && (jsxRuntime.jsx("div", { className: "px-2 py-4 text-center text-xs text-muted-foreground", children: "No users available" }))] })] })] }));
8439
8589
  }
8440
8590
 
8441
8591
  /**
@@ -8782,7 +8932,7 @@ function AuditLogFilters({ client, filters, timeRange, onFiltersChange, onTimeRa
8782
8932
  label: facet.value,
8783
8933
  count: facet.count,
8784
8934
  }));
8785
- return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 pt-0 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [jsxRuntime.jsx(ActionMultiSelect, { value: getActionValues(), onChange: handleActionChange, options: actionOptions, disabled: disabled, isLoading: !verbs.length && !facetsError, className: "h-7 text-xs min-w-[180px]" }), jsxRuntime.jsx(UserSelect, { value: getCurrentUser(), options: userOptions, onChange: handleUserChange, disabled: disabled, isLoading: !usernames.length && !facetsError }), activeFilterIds.map((filterId) => {
8935
+ return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 pt-0 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [jsxRuntime.jsx(ActionMultiSelect, { value: getActionValues(), onChange: handleActionChange, options: actionOptions, disabled: disabled, isLoading: !verbs.length && !facetsError, className: "min-w-[180px]" }), jsxRuntime.jsx(UserSelect, { value: getCurrentUser(), options: userOptions, onChange: handleUserChange, disabled: disabled, isLoading: !usernames.length && !facetsError }), activeFilterIds.map((filterId) => {
8786
8936
  const config = FILTER_CONFIGS$2[filterId];
8787
8937
  return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === "typeahead"
8788
8938
  ? getFilterOptions(filterId)
@@ -8918,7 +9068,7 @@ function CopyButton({ value, label }) {
8918
9068
  console.error('Failed to copy:', err);
8919
9069
  }
8920
9070
  };
8921
- return (jsxRuntime.jsxs(Tooltip, { delayDuration: 400, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { type: "button", onClick: handleCopy, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-opacity cursor-pointer ml-1 opacity-0 group-hover:opacity-100", "aria-label": `Copy ${label}`, children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-green-600 dark:text-green-400" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-gray-500 dark:text-gray-400" })) }) }), jsxRuntime.jsx(TooltipContent, { side: "top", children: jsxRuntime.jsx("p", { className: "text-xs", children: isCopied ? 'Copied!' : `Copy ${label}` }) })] }));
9071
+ return (jsxRuntime.jsxs(Tooltip, { delayDuration: 400, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { type: "button", onClick: handleCopy, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-muted transition-opacity cursor-pointer ml-1 opacity-0 group-hover:opacity-100", "aria-label": `Copy ${label}`, children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-[var(--success-500)]" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-muted-foreground" })) }) }), jsxRuntime.jsx(TooltipContent, { side: "top", children: jsxRuntime.jsx("p", { className: "text-xs", children: isCopied ? 'Copied!' : `Copy ${label}` }) })] }));
8922
9072
  }
8923
9073
  /**
8924
9074
  * A label / value row inside a Section. The value is truncated to one
@@ -8996,8 +9146,8 @@ function AuditLogExpandedDetails({ event, compact = true }) {
8996
9146
  const status = event.responseStatus;
8997
9147
  const isOk = status?.code != null && status.code >= 200 && status.code < 300;
8998
9148
  const body = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(DetailGrid, { children: [jsxRuntime.jsxs(Section, { title: "Request", children: [jsxRuntime.jsx(Field, { label: "Verb", value: event.verb || 'Unknown', copyValue: event.verb || undefined, copyLabel: "verb" }), event.requestURI ? (jsxRuntime.jsx(Field, { label: "URI", value: event.requestURI, copyValue: event.requestURI, mono: true })) : null] }), status ? (jsxRuntime.jsxs(Section, { title: "Response", children: [status.code != null ? (jsxRuntime.jsx(Field, { label: "Status code", value: jsxRuntime.jsxs("span", { className: isOk
8999
- ? 'text-green-600 dark:text-green-400'
9000
- : 'text-red-600 dark:text-red-400', children: [isOk ? '✓ ' : '✗ ', status.code] }), copyValue: String(status.code), copyLabel: "status code" })) : null, status.status ? jsxRuntime.jsx(Field, { label: "Status", value: status.status }) : null, status.reason ? jsxRuntime.jsx(Field, { label: "Reason", value: status.reason }) : null, status.message ? (jsxRuntime.jsx(Field, { label: "Message", value: status.message, copyValue: status.message })) : null] })) : null, jsxRuntime.jsx(Section, { title: "When", children: jsxRuntime.jsx(Field, { label: "Timestamp", value: jsxRuntime.jsx(Timestamp, { value: timestamp, variant: "iso-utc" }), copyValue: timestamp || '', copyLabel: "timestamp", disableTooltip: true }) }), event.user ? (jsxRuntime.jsxs(Section, { title: "User", children: [event.user.username ? (jsxRuntime.jsx(Field, { label: "Username", value: event.user.username, copyValue: event.user.username })) : null, event.user.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: event.user.uid, copyValue: event.user.uid, mono: true })) : null, event.user.groups && event.user.groups.length > 0 ? (jsxRuntime.jsx(Field, { label: "Groups", value: event.user.groups.join(', ') })) : null] })) : null, event.objectRef ? (jsxRuntime.jsxs(Section, { title: "Resource", children: [jsxRuntime.jsx(Field, { label: "Kind", value: jsxRuntime.jsxs("span", { children: [event.objectRef.resource || 'Unknown', event.objectRef.apiGroup ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", event.objectRef.apiGroup] })) : null] }), copyValue: event.objectRef.resource, copyLabel: "resource kind" }), event.objectRef.name ? (jsxRuntime.jsx(Field, { label: "Name", value: event.objectRef.name, copyValue: event.objectRef.name, copyLabel: "resource name" })) : null, event.objectRef.namespace ? (jsxRuntime.jsx(Field, { label: "Namespace", value: event.objectRef.namespace, copyValue: event.objectRef.namespace })) : null, event.objectRef.apiVersion ? (jsxRuntime.jsx(Field, { label: "API version", value: event.objectRef.apiVersion })) : null, event.objectRef.subresource ? (jsxRuntime.jsx(Field, { label: "Subresource", value: event.objectRef.subresource })) : null, event.objectRef.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: event.objectRef.uid, copyValue: event.objectRef.uid, mono: true })) : null] })) : null, event.userAgent || (event.sourceIPs && event.sourceIPs.length > 0) ? (jsxRuntime.jsxs(Section, { title: "Source", children: [event.sourceIPs && event.sourceIPs.length > 0 ? (jsxRuntime.jsx(Field, { label: "Source IPs", value: event.sourceIPs.join(', ') })) : null, event.userAgent ? (jsxRuntime.jsx(Field, { label: "User agent", value: event.userAgent, copyValue: event.userAgent, mono: true })) : null] })) : null] }), event.auditID || event.stage || event.level ||
9149
+ ? 'text-[var(--success-500)]'
9150
+ : 'text-destructive', children: [isOk ? '✓ ' : '✗ ', status.code] }), copyValue: String(status.code), copyLabel: "status code" })) : null, status.status ? jsxRuntime.jsx(Field, { label: "Status", value: status.status }) : null, status.reason ? jsxRuntime.jsx(Field, { label: "Reason", value: status.reason }) : null, status.message ? (jsxRuntime.jsx(Field, { label: "Message", value: status.message, copyValue: status.message })) : null] })) : null, jsxRuntime.jsx(Section, { title: "When", children: jsxRuntime.jsx(Field, { label: "Timestamp", value: jsxRuntime.jsx(Timestamp, { value: timestamp, variant: "iso-utc" }), copyValue: timestamp || '', copyLabel: "timestamp", disableTooltip: true }) }), event.user ? (jsxRuntime.jsxs(Section, { title: "User", children: [event.user.username ? (jsxRuntime.jsx(Field, { label: "Username", value: event.user.username, copyValue: event.user.username })) : null, event.user.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: event.user.uid, copyValue: event.user.uid, mono: true })) : null, event.user.groups && event.user.groups.length > 0 ? (jsxRuntime.jsx(Field, { label: "Groups", value: event.user.groups.join(', ') })) : null] })) : null, event.objectRef ? (jsxRuntime.jsxs(Section, { title: "Resource", children: [jsxRuntime.jsx(Field, { label: "Kind", value: jsxRuntime.jsxs("span", { children: [event.objectRef.resource || 'Unknown', event.objectRef.apiGroup ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", event.objectRef.apiGroup] })) : null] }), copyValue: event.objectRef.resource, copyLabel: "resource kind" }), event.objectRef.name ? (jsxRuntime.jsx(Field, { label: "Name", value: event.objectRef.name, copyValue: event.objectRef.name, copyLabel: "resource name" })) : null, event.objectRef.namespace ? (jsxRuntime.jsx(Field, { label: "Namespace", value: event.objectRef.namespace, copyValue: event.objectRef.namespace })) : null, event.objectRef.apiVersion ? (jsxRuntime.jsx(Field, { label: "API version", value: event.objectRef.apiVersion })) : null, event.objectRef.subresource ? (jsxRuntime.jsx(Field, { label: "Subresource", value: event.objectRef.subresource })) : null, event.objectRef.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: event.objectRef.uid, copyValue: event.objectRef.uid, mono: true })) : null] })) : null, event.userAgent || (event.sourceIPs && event.sourceIPs.length > 0) ? (jsxRuntime.jsxs(Section, { title: "Source", children: [event.sourceIPs && event.sourceIPs.length > 0 ? (jsxRuntime.jsx(Field, { label: "Source IPs", value: event.sourceIPs.join(', ') })) : null, event.userAgent ? (jsxRuntime.jsx(Field, { label: "User agent", value: event.userAgent, copyValue: event.userAgent, mono: true })) : null] })) : null] }), event.auditID || event.stage || event.level ||
9001
9151
  (event.annotations && Object.keys(event.annotations).length > 0) ? (jsxRuntime.jsxs("details", { className: "group mt-5", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer list-none", children: jsxRuntime.jsxs("h4", { className: "inline-flex items-center m-0 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/80 hover:text-foreground", children: [jsxRuntime.jsx("span", { className: "mr-1 group-open:rotate-90 transition-transform", children: "\u25B8" }), "Advanced"] }) }), jsxRuntime.jsx("div", { className: "mt-3 pl-3", children: jsxRuntime.jsxs(DetailGrid, { children: [jsxRuntime.jsxs(Section, { title: "Audit", children: [event.auditID ? (jsxRuntime.jsx(Field, { label: "Audit ID", value: event.auditID, copyValue: event.auditID, mono: true })) : null, event.stage ? jsxRuntime.jsx(Field, { label: "Stage", value: event.stage }) : null, event.level ? jsxRuntime.jsx(Field, { label: "Level", value: event.level }) : null] }), event.annotations && Object.keys(event.annotations).length > 0 ? (jsxRuntime.jsx(Section, { title: "Annotations", children: Object.entries(event.annotations).map(([key, value]) => (jsxRuntime.jsx(Field, { label: key, value: value, mono: true }, key))) })) : null] }) })] })) : null, event.requestObject || event.responseObject ? (jsxRuntime.jsxs("details", { className: "group mt-3", children: [jsxRuntime.jsx("summary", { className: "cursor-pointer list-none", children: jsxRuntime.jsxs("h4", { className: "inline-flex items-center m-0 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/80 hover:text-foreground", children: [jsxRuntime.jsx("span", { className: "mr-1 group-open:rotate-90 transition-transform", children: "\u25B8" }), "Raw objects"] }) }), jsxRuntime.jsxs("div", { className: "mt-3 space-y-3", children: [event.requestObject ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Request" }), jsxRuntime.jsx("pre", { className: "m-0 p-3 bg-muted rounded overflow-x-auto text-xs font-mono", children: JSON.stringify(event.requestObject, null, 2) })] })) : null, event.responseObject ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Response" }), jsxRuntime.jsx("pre", { className: "m-0 p-3 bg-muted rounded overflow-x-auto text-xs font-mono", children: JSON.stringify(event.responseObject, null, 2) })] })) : null] })] })) : null] }));
9002
9152
  return (jsxRuntime.jsx(TooltipProvider, { children: compact ? (jsxRuntime.jsx(DetailPanelShell, { children: body })) : (jsxRuntime.jsx("div", { className: "mt-4 pt-4 border-t border-border", children: body })) }));
9003
9153
  }
@@ -9005,22 +9155,21 @@ function AuditLogExpandedDetails({ event, compact = true }) {
9005
9155
  // Number of columns rendered for the audit log table. Used by the colSpan
9006
9156
  // on the expanded-detail row so it spans the full width.
9007
9157
  const AUDIT_LOG_COLUMN_COUNT = 5;
9158
+ const VERB_BADGE_CLASSES = 'text-[0.55rem] h-5 px-2 py-1 leading-3';
9008
9159
  /**
9009
- * Get Tailwind classes for verb badge
9160
+ * Get the badge variant for a verb
9010
9161
  */
9011
- function getVerbBadgeClasses(verb) {
9012
- const baseClasses = 'text-[0.55rem] h-5 px-2 py-1 leading-3';
9013
- const normalized = verb?.toLowerCase();
9014
- switch (normalized) {
9162
+ function getVerbBadgeVariant(verb) {
9163
+ switch (verb?.toLowerCase()) {
9015
9164
  case 'create':
9016
- return cn(baseClasses, 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300');
9165
+ return 'success';
9017
9166
  case 'update':
9018
9167
  case 'patch':
9019
- return cn(baseClasses, 'bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300');
9168
+ return 'warning';
9020
9169
  case 'delete':
9021
- return cn(baseClasses, 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300');
9170
+ return 'destructive';
9022
9171
  default:
9023
- return cn(baseClasses, 'bg-muted text-muted-foreground');
9172
+ return 'outline';
9024
9173
  }
9025
9174
  }
9026
9175
  /**
@@ -9031,9 +9180,9 @@ function getResponseStatusIndicator(code) {
9031
9180
  return { icon: '?', className: 'text-muted-foreground' };
9032
9181
  }
9033
9182
  if (code >= 200 && code < 300) {
9034
- return { icon: '✓', className: 'text-green-600 dark:text-green-400' };
9183
+ return { icon: '✓', className: 'text-[var(--success-500)]' };
9035
9184
  }
9036
- return { icon: '✗', className: 'text-red-600 dark:text-red-400' };
9185
+ return { icon: '✗', className: 'text-destructive' };
9037
9186
  }
9038
9187
  /**
9039
9188
  * Build human-readable summary
@@ -9074,14 +9223,14 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9074
9223
  verb === 'delete' ? Trash2 :
9075
9224
  verb === 'update' || verb === 'patch' ? Pencil :
9076
9225
  Activity;
9077
- const iconBg = verb === 'create' ? 'bg-green-50 dark:bg-green-950' :
9078
- verb === 'delete' ? 'bg-red-50 dark:bg-red-950' :
9079
- verb === 'update' || verb === 'patch' ? 'bg-amber-50 dark:bg-amber-950' :
9080
- 'bg-slate-100 dark:bg-slate-800';
9081
- const iconColor = verb === 'create' ? 'text-green-600 dark:text-green-400' :
9082
- verb === 'delete' ? 'text-red-500 dark:text-red-400' :
9083
- verb === 'update' || verb === 'patch' ? 'text-amber-600 dark:text-amber-400' :
9084
- 'text-slate-500 dark:text-slate-400';
9226
+ const iconBg = verb === 'create' ? 'bg-[var(--success-100)]' :
9227
+ verb === 'delete' ? 'bg-destructive/10' :
9228
+ verb === 'update' || verb === 'patch' ? 'bg-[color-mix(in_oklab,var(--badge-warning)_15%,transparent)]' :
9229
+ 'bg-muted';
9230
+ const iconColor = verb === 'create' ? 'text-[var(--success-500)]' :
9231
+ verb === 'delete' ? 'text-destructive' :
9232
+ verb === 'update' || verb === 'patch' ? 'text-[var(--badge-warning)]' :
9233
+ 'text-muted-foreground';
9085
9234
  return (jsxRuntime.jsxs("div", { className: cn(!isLast && !isExpanded && 'border-b border-border', className), children: [jsxRuntime.jsxs("div", { className: cn('flex items-center gap-3 cursor-pointer group', compact ? 'py-2' : 'py-3', isSelected && 'bg-muted/40'), onClick: toggleExpand, children: [jsxRuntime.jsx("div", { className: cn('w-8 h-8 rounded-md shrink-0 flex items-center justify-center', iconBg, iconColor), title: event.verb, children: jsxRuntime.jsx(Icon, { size: 16, strokeWidth: 2 }) }), jsxRuntime.jsx("div", { className: "flex-1 min-w-0 text-sm leading-snug", style: { minWidth: 0 }, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("div", { className: "text-foreground", style: {
9086
9235
  display: 'block',
9087
9236
  overflow: 'hidden',
@@ -9090,10 +9239,10 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9090
9239
  cursor: 'help',
9091
9240
  }, children: summary }) }), jsxRuntime.jsx(TooltipContent, { className: "max-w-[480px] whitespace-normal break-words", children: summary })] }) }), jsxRuntime.jsxs("span", { className: cn('inline-flex items-center gap-1 text-xs font-semibold shrink-0', statusIndicator.className), children: [jsxRuntime.jsx("span", { children: statusIndicator.icon }), event.responseStatus?.code ? jsxRuntime.jsx("span", { children: event.responseStatus.code }) : null] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", htmlType: "button", className: "h-5 py-0 px-1 text-base text-muted-foreground hover:text-foreground shrink-0", onClick: toggleExpand, "aria-expanded": isExpanded, "aria-label": isExpanded ? 'Collapse details' : 'Expand details', children: isExpanded ? '−' : '+' })] }), isExpanded ? jsxRuntime.jsx(AuditLogExpandedDetails, { event: event }) : null] }));
9092
9241
  }
9093
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? 'selected' : undefined, className: cn('cursor-pointer', isNew && 'bg-green-50/40 dark:bg-green-950/20', className), onClick: (e) => {
9242
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? 'selected' : undefined, className: cn('cursor-pointer', isNew && 'bg-[var(--success-100)]/60', className), onClick: (e) => {
9094
9243
  toggleExpand(e);
9095
9244
  handleClick();
9096
- }, "aria-expanded": isExpanded, children: [jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap", children: jsxRuntime.jsx(Badge, { className: getVerbBadgeClasses(event.verb), children: event.verb?.toUpperCase() || 'UNKNOWN' }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle", style: { width: '100%', maxWidth: 0, overflow: 'hidden' }, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("div", { className: "text-sm leading-snug", style: {
9245
+ }, "aria-expanded": isExpanded, children: [jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap", children: jsxRuntime.jsx(Badge, { variant: getVerbBadgeVariant(event.verb), className: VERB_BADGE_CLASSES, children: event.verb?.toUpperCase() || 'UNKNOWN' }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle", style: { width: '100%', maxWidth: 0, overflow: 'hidden' }, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("div", { className: "text-sm leading-snug", style: {
9097
9246
  overflow: 'hidden',
9098
9247
  textOverflow: 'ellipsis',
9099
9248
  whiteSpace: 'nowrap',
@@ -9103,7 +9252,7 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9103
9252
  /**
9104
9253
  * React hook for executing audit log queries
9105
9254
  */
9106
- function useAuditLogQuery({ client, autoExecute = false, }) {
9255
+ function useAuditLogQuery({ client, }) {
9107
9256
  const [query, setQuery] = React.useState(null);
9108
9257
  const [events, setEvents] = React.useState([]);
9109
9258
  const [isLoading, setIsLoading] = React.useState(false);
@@ -9645,6 +9794,14 @@ function ActionToggle({ value, onChange, className = '', disabled = false, }) {
9645
9794
 
9646
9795
  // Debounce delay for filter changes (ms)
9647
9796
  const FILTER_DEBOUNCE_MS$1 = 300;
9797
+ // Backoff for watch stream reconnects. Without this, a persistently failing
9798
+ // upstream gets re-opened on every render with no delay — see
9799
+ // https://github.com/datum-cloud/infra/issues/5060, where a single browser
9800
+ // tab reconnected roughly 2.5 times a minute against a stream that kept
9801
+ // aborting, driving the proxy's memory up until the process was OOMKilled.
9802
+ const RECONNECT_BASE_DELAY_MS = 1000;
9803
+ const RECONNECT_MAX_DELAY_MS = 30000;
9804
+ const MAX_RECONNECT_ATTEMPTS = 8;
9648
9805
  /**
9649
9806
  * Escape a value for safe interpolation into a CEL string literal.
9650
9807
  * Prevents injection via values containing backslashes or double quotes.
@@ -9739,6 +9896,12 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
9739
9896
  const resourceVersionRef = React.useRef();
9740
9897
  // Track the watch stop function
9741
9898
  const watchStopRef = React.useRef(null);
9899
+ // Consecutive watch failures since the last successful event, used to back
9900
+ // off reconnect attempts. Reset on any real event (including BOOKMARK) and
9901
+ // on a manual startStreaming() call.
9902
+ const reconnectAttemptsRef = React.useRef(0);
9903
+ // Pending scheduled reconnect, if any.
9904
+ const reconnectTimerRef = React.useRef(null);
9742
9905
  // Track whether streaming should restart after filter change
9743
9906
  const shouldRestartStreamingRef = React.useRef(false);
9744
9907
  // Track if we've done the initial load
@@ -9813,6 +9976,9 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
9813
9976
  console.error('Watch error:', event.object);
9814
9977
  return;
9815
9978
  }
9979
+ // A real event (including a BOOKMARK keep-alive) means the connection is
9980
+ // healthy — reset backoff so a later failure starts from the base delay.
9981
+ reconnectAttemptsRef.current = 0;
9816
9982
  if (event.type === 'BOOKMARK') {
9817
9983
  // Update resource version for resume capability
9818
9984
  if (event.object.metadata?.resourceVersion) {
@@ -9878,15 +10044,13 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
9878
10044
  setActivities((prev) => prev.filter((a) => a.metadata?.name !== event.object.metadata?.name));
9879
10045
  }
9880
10046
  }, [filters]);
9881
- // Start watching for real-time updates
9882
- const startStreaming = React.useCallback(() => {
10047
+ // Open the watch connection. Does not touch userPaused/backoff state —
10048
+ // callers (startStreaming, scheduleReconnect) own that.
10049
+ const connectWatch = React.useCallback(() => {
9883
10050
  if (watchStopRef.current) {
9884
10051
  // Already watching
9885
10052
  return;
9886
10053
  }
9887
- // Explicit start clears the user-paused flag so the auto-restart
9888
- // effects can keep the stream alive after subsequent filter changes.
9889
- setUserPaused(false);
9890
10054
  // Clear any previous watch error when starting a new stream
9891
10055
  setWatchError(null);
9892
10056
  const params = buildWatchParams();
@@ -9900,6 +10064,7 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
9900
10064
  setWatchError(streamError);
9901
10065
  setIsStreaming(false);
9902
10066
  watchStopRef.current = null;
10067
+ reconnectAttemptsRef.current += 1;
9903
10068
  },
9904
10069
  onClose: () => {
9905
10070
  setIsStreaming(false);
@@ -9910,11 +10075,50 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
9910
10075
  setIsStreaming(true);
9911
10076
  setNewActivitiesCount(0);
9912
10077
  }, [client, buildWatchParams, handleWatchEvent]);
10078
+ // Reconnect with exponential backoff. The first attempt (no prior
10079
+ // failures) connects immediately; each subsequent failure doubles the
10080
+ // delay up to RECONNECT_MAX_DELAY_MS. After MAX_RECONNECT_ATTEMPTS
10081
+ // consecutive failures, this stops retrying automatically — the watch
10082
+ // stays stopped (with watchError set) until the user calls
10083
+ // startStreaming() again, which resets the attempt count.
10084
+ const scheduleReconnect = React.useCallback(() => {
10085
+ if (reconnectTimerRef.current) {
10086
+ // A reconnect is already scheduled.
10087
+ return;
10088
+ }
10089
+ if (reconnectAttemptsRef.current >= MAX_RECONNECT_ATTEMPTS) {
10090
+ return;
10091
+ }
10092
+ const attempt = reconnectAttemptsRef.current;
10093
+ const delay = attempt === 0 ? 0 : Math.min(RECONNECT_MAX_DELAY_MS, RECONNECT_BASE_DELAY_MS * 2 ** (attempt - 1));
10094
+ reconnectTimerRef.current = setTimeout(() => {
10095
+ reconnectTimerRef.current = null;
10096
+ connectWatch();
10097
+ }, delay);
10098
+ }, [connectWatch]);
10099
+ // Start watching for real-time updates. This is the user/effect-facing
10100
+ // entry point: it resets backoff and any pending scheduled reconnect
10101
+ // before connecting, so a manual retry always starts from a clean slate.
10102
+ const startStreaming = React.useCallback(() => {
10103
+ // Explicit start clears the user-paused flag so the auto-restart
10104
+ // effects can keep the stream alive after subsequent filter changes.
10105
+ setUserPaused(false);
10106
+ reconnectAttemptsRef.current = 0;
10107
+ if (reconnectTimerRef.current) {
10108
+ clearTimeout(reconnectTimerRef.current);
10109
+ reconnectTimerRef.current = null;
10110
+ }
10111
+ connectWatch();
10112
+ }, [connectWatch]);
9913
10113
  // Stop watching. Marks the user as paused so the auto-start effects
9914
10114
  // below don't immediately re-open the stream this call just closed.
9915
10115
  const stopStreaming = React.useCallback(() => {
9916
10116
  setUserPaused(true);
9917
10117
  setIsStreaming(false);
10118
+ if (reconnectTimerRef.current) {
10119
+ clearTimeout(reconnectTimerRef.current);
10120
+ reconnectTimerRef.current = null;
10121
+ }
9918
10122
  if (watchStopRef.current) {
9919
10123
  watchStopRef.current();
9920
10124
  watchStopRef.current = null;
@@ -10077,9 +10281,10 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
10077
10281
  }
10078
10282
  };
10079
10283
  }, [filters, timeRange]); // eslint-disable-line react-hooks/exhaustive-deps
10080
- // Auto-start streaming after initial load when enabled. Skipped when
10081
- // the user has explicitly paused — otherwise clicking Pause would be
10082
- // immediately undone by this effect on the next render.
10284
+ // Auto-start streaming after initial load when enabled, and reconnect
10285
+ // (with backoff — see scheduleReconnect) whenever a connection drops.
10286
+ // Skipped when the user has explicitly paused — otherwise clicking Pause
10287
+ // would be immediately undone by this effect on the next render.
10083
10288
  React.useEffect(() => {
10084
10289
  if (enableStreaming &&
10085
10290
  autoStartStreaming &&
@@ -10087,9 +10292,9 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
10087
10292
  activities.length > 0 &&
10088
10293
  !isStreaming &&
10089
10294
  !isLoading) {
10090
- startStreaming();
10295
+ scheduleReconnect();
10091
10296
  }
10092
- }, [enableStreaming, autoStartStreaming, userPaused, activities.length, isStreaming, isLoading, startStreaming]);
10297
+ }, [enableStreaming, autoStartStreaming, userPaused, activities.length, isStreaming, isLoading, scheduleReconnect]);
10093
10298
  // Restart streaming after filter change refresh completes. Also skipped
10094
10299
  // when the user has paused — a filter change shouldn't silently resume
10095
10300
  // a stream the user intentionally stopped.
@@ -10101,15 +10306,18 @@ function useActivityFeed({ client, initialFilters = {}, initialTimeRange = { sta
10101
10306
  !isStreaming &&
10102
10307
  !isLoading) {
10103
10308
  shouldRestartStreamingRef.current = false;
10104
- startStreaming();
10309
+ scheduleReconnect();
10105
10310
  }
10106
- }, [enableStreaming, userPaused, activities.length, isStreaming, isLoading, startStreaming]);
10311
+ }, [enableStreaming, userPaused, activities.length, isStreaming, isLoading, scheduleReconnect]);
10107
10312
  // Cleanup on unmount
10108
10313
  React.useEffect(() => {
10109
10314
  return () => {
10110
10315
  if (watchStopRef.current) {
10111
10316
  watchStopRef.current();
10112
10317
  }
10318
+ if (reconnectTimerRef.current) {
10319
+ clearTimeout(reconnectTimerRef.current);
10320
+ }
10113
10321
  if (filterDebounceRef.current) {
10114
10322
  clearTimeout(filterDebounceRef.current);
10115
10323
  }
@@ -10270,40 +10478,10 @@ function ActivityExpandedDetails({ activity, compact = false, }) {
10270
10478
  const timestamp = metadata?.creationTimestamp;
10271
10479
  const actorDisplay = actor.displayName || actor.name;
10272
10480
  const actorIsUser = actor.type === 'user';
10273
- const body = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [changes && changes.length > 0 ? (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "m-0 mb-2 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/80", children: "Changes" }), jsxRuntime.jsx("div", { className: "flex flex-col gap-1.5", children: changes.map((change, index) => (jsxRuntime.jsxs("div", { className: "rounded bg-muted px-2.5 py-1.5 text-xs", children: [jsxRuntime.jsx("span", { className: "block font-mono text-[11px] font-semibold text-foreground", children: change.field }), change.old ? (jsxRuntime.jsxs("span", { className: "block ml-2 text-red-600 dark:text-red-400", children: [jsxRuntime.jsx("span", { className: "mr-1 font-medium", children: "\u2212" }), jsxRuntime.jsx("span", { className: "line-through", children: change.old })] })) : null, change.new ? (jsxRuntime.jsxs("span", { className: "block ml-2 text-green-600 dark:text-green-400", children: [jsxRuntime.jsx("span", { className: "mr-1 font-medium", children: "+" }), change.new] })) : null] }, index))) })] })) : null, jsxRuntime.jsxs(DetailGrid, { children: [jsxRuntime.jsx(Section, { title: "When", children: jsxRuntime.jsx(Field, { label: "Timestamp", value: jsxRuntime.jsx(Timestamp, { value: timestamp, variant: "iso-utc" }), copyValue: timestamp ?? '', copyLabel: "timestamp", disableTooltip: true }) }), jsxRuntime.jsxs(Section, { title: "Actor", children: [jsxRuntime.jsx(Field, { label: "Name", value: jsxRuntime.jsxs("span", { children: [actorDisplay, actor.type ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["(", actor.type, ")"] })) : null] }), copyValue: actorDisplay, copyLabel: "actor name" }), actorIsUser && actor.email ? (jsxRuntime.jsx(Field, { label: "Email", value: actor.email, copyValue: actor.email, mono: true })) : null, actor.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: actor.uid, copyValue: actor.uid, mono: true })) : null] }), jsxRuntime.jsxs(Section, { title: "Resource", children: [jsxRuntime.jsx(Field, { label: "Kind", value: jsxRuntime.jsxs("span", { children: [resource.kind, resource.apiGroup ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", resource.apiGroup] })) : null] }), copyValue: resource.kind, copyLabel: "resource kind" }), resource.name ? (jsxRuntime.jsx(Field, { label: "Name", value: resource.name, copyValue: resource.name, copyLabel: "resource name" })) : null, resource.namespace ? (jsxRuntime.jsx(Field, { label: "Namespace", value: resource.namespace, copyValue: resource.namespace })) : null, resource.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: resource.uid, copyValue: resource.uid, mono: true })) : null] }), jsxRuntime.jsxs(Section, { title: "Origin", children: [jsxRuntime.jsx(Field, { label: "Source", value: origin.type, copyValue: origin.type, copyLabel: "origin type" }), origin.id ? (jsxRuntime.jsx(Field, { label: "ID", value: origin.id, copyValue: origin.id, mono: true })) : null] })] })] }));
10481
+ const body = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [changes && changes.length > 0 ? (jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "m-0 mb-2 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/80", children: "Changes" }), jsxRuntime.jsx("div", { className: "flex flex-col gap-1.5", children: changes.map((change, index) => (jsxRuntime.jsxs("div", { className: "rounded bg-muted px-2.5 py-1.5 text-xs", children: [jsxRuntime.jsx("span", { className: "block font-mono text-[11px] font-semibold text-foreground", children: change.field }), change.old ? (jsxRuntime.jsxs("span", { className: "block ml-2 text-destructive", children: [jsxRuntime.jsx("span", { className: "mr-1 font-medium", children: "\u2212" }), jsxRuntime.jsx("span", { className: "line-through", children: change.old })] })) : null, change.new ? (jsxRuntime.jsxs("span", { className: "block ml-2 text-[var(--success-500)]", children: [jsxRuntime.jsx("span", { className: "mr-1 font-medium", children: "+" }), change.new] })) : null] }, index))) })] })) : null, jsxRuntime.jsxs(DetailGrid, { children: [jsxRuntime.jsx(Section, { title: "When", children: jsxRuntime.jsx(Field, { label: "Timestamp", value: jsxRuntime.jsx(Timestamp, { value: timestamp, variant: "iso-utc" }), copyValue: timestamp ?? '', copyLabel: "timestamp", disableTooltip: true }) }), jsxRuntime.jsxs(Section, { title: "Actor", children: [jsxRuntime.jsx(Field, { label: "Name", value: jsxRuntime.jsxs("span", { children: [actorDisplay, actor.type ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["(", actor.type, ")"] })) : null] }), copyValue: actorDisplay, copyLabel: "actor name" }), actorIsUser && actor.email ? (jsxRuntime.jsx(Field, { label: "Email", value: actor.email, copyValue: actor.email, mono: true })) : null, actor.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: actor.uid, copyValue: actor.uid, mono: true })) : null] }), jsxRuntime.jsxs(Section, { title: "Resource", children: [jsxRuntime.jsx(Field, { label: "Kind", value: jsxRuntime.jsxs("span", { children: [resource.kind, resource.apiGroup ? (jsxRuntime.jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", resource.apiGroup] })) : null] }), copyValue: resource.kind, copyLabel: "resource kind" }), resource.name ? (jsxRuntime.jsx(Field, { label: "Name", value: resource.name, copyValue: resource.name, copyLabel: "resource name" })) : null, resource.namespace ? (jsxRuntime.jsx(Field, { label: "Namespace", value: resource.namespace, copyValue: resource.namespace })) : null, resource.uid ? (jsxRuntime.jsx(Field, { label: "UID", value: resource.uid, copyValue: resource.uid, mono: true })) : null] }), jsxRuntime.jsxs(Section, { title: "Origin", children: [jsxRuntime.jsx(Field, { label: "Source", value: origin.type, copyValue: origin.type, copyLabel: "origin type" }), origin.id ? (jsxRuntime.jsx(Field, { label: "ID", value: origin.id, copyValue: origin.id, mono: true })) : null] })] })] }));
10274
10482
  return (jsxRuntime.jsx(TooltipProvider, { children: compact ? (jsxRuntime.jsx(DetailPanelShell, { children: body })) : (jsxRuntime.jsx("div", { className: "mt-4 pt-4 border-t border-border", children: body })) }));
10275
10483
  }
10276
10484
 
10277
- // Number of columns rendered for the feed variant. Used as the colSpan on
10278
- // the expanded-detail row so it stretches across the full width.
10279
- const ACTIVITY_FEED_COLUMN_COUNT = 5;
10280
- /**
10281
- * Get avatar initials from actor name
10282
- */
10283
- function getActorInitials(name) {
10284
- const parts = name.split(/[@\s.]+/).filter(Boolean);
10285
- if (parts.length === 0)
10286
- return "?";
10287
- if (parts.length === 1)
10288
- return parts[0].charAt(0).toUpperCase();
10289
- return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
10290
- }
10291
- /**
10292
- * Get Tailwind classes for actor avatar based on actor type
10293
- */
10294
- function getActorAvatarClasses(actorType, compact) {
10295
- const baseClasses = cn("rounded-full flex items-center justify-center shrink-0 font-semibold", compact ? "w-5 h-5 text-1xs" : "w-6 h-6 text-1xs");
10296
- switch (actorType) {
10297
- case "user":
10298
- return cn(baseClasses, "bg-primary text-primary-foreground");
10299
- case "controller":
10300
- return cn(baseClasses, "bg-secondary text-secondary-foreground");
10301
- case "machine account":
10302
- return cn(baseClasses, "bg-muted text-muted-foreground");
10303
- default:
10304
- return cn(baseClasses, "bg-muted text-muted-foreground");
10305
- }
10306
- }
10307
10485
  /**
10308
10486
  * Extract verb from activity summary (e.g., "alice created HTTPProxy" -> "created")
10309
10487
  */
@@ -10312,24 +10490,24 @@ function extractVerb(summary) {
10312
10490
  if (words.length >= 2) {
10313
10491
  return words[1].toLowerCase();
10314
10492
  }
10315
- return "unknown";
10493
+ return 'unknown';
10316
10494
  }
10317
10495
  /**
10318
- * Normalize verb to a canonical form for coloring
10496
+ * Normalize a verb to a canonical form used for coloring/icons/grouping.
10319
10497
  */
10320
10498
  function normalizeVerb(verb) {
10321
10499
  const normalized = verb.toLowerCase();
10322
- if (normalized.includes("create") || normalized.includes("add"))
10323
- return "create";
10324
- if (normalized.includes("delete") || normalized.includes("remove"))
10325
- return "delete";
10326
- if (normalized.includes("update") ||
10327
- normalized.includes("patch") ||
10328
- normalized.includes("modify") ||
10329
- normalized.includes("change") ||
10330
- normalized.includes("edit"))
10331
- return "update";
10332
- return "other";
10500
+ if (normalized.includes('create') || normalized.includes('add'))
10501
+ return 'create';
10502
+ if (normalized.includes('delete') || normalized.includes('remove'))
10503
+ return 'delete';
10504
+ if (normalized.includes('update') ||
10505
+ normalized.includes('patch') ||
10506
+ normalized.includes('modify') ||
10507
+ normalized.includes('change') ||
10508
+ normalized.includes('edit'))
10509
+ return 'update';
10510
+ return 'other';
10333
10511
  }
10334
10512
  /**
10335
10513
  * Get icon container + icon color classes based on verb
@@ -10337,25 +10515,25 @@ function normalizeVerb(verb) {
10337
10515
  function getActionIconClasses(verb) {
10338
10516
  const normalizedVerb = normalizeVerb(verb);
10339
10517
  switch (normalizedVerb) {
10340
- case "create":
10518
+ case 'create':
10341
10519
  return {
10342
- container: "bg-blue-50 dark:bg-blue-950",
10343
- icon: "text-blue-500 dark:text-blue-400",
10520
+ container: 'bg-blue-50 dark:bg-blue-950',
10521
+ icon: 'text-blue-500 dark:text-blue-400',
10344
10522
  };
10345
- case "update":
10523
+ case 'update':
10346
10524
  return {
10347
- container: "bg-green-50 dark:bg-green-950",
10348
- icon: "text-green-600 dark:text-green-400",
10525
+ container: 'bg-green-50 dark:bg-green-950',
10526
+ icon: 'text-green-600 dark:text-green-400',
10349
10527
  };
10350
- case "delete":
10528
+ case 'delete':
10351
10529
  return {
10352
- container: "bg-red-50 dark:bg-red-950",
10353
- icon: "text-red-500 dark:text-red-400",
10530
+ container: 'bg-red-50 dark:bg-red-950',
10531
+ icon: 'text-red-500 dark:text-red-400',
10354
10532
  };
10355
10533
  default:
10356
10534
  return {
10357
- container: "bg-slate-100 dark:bg-slate-800",
10358
- icon: "text-slate-500 dark:text-slate-400",
10535
+ container: 'bg-slate-100 dark:bg-slate-800',
10536
+ icon: 'text-slate-500 dark:text-slate-400',
10359
10537
  };
10360
10538
  }
10361
10539
  }
@@ -10365,20 +10543,51 @@ function getActionIconClasses(verb) {
10365
10543
  function getTimelineIcon(verb) {
10366
10544
  const normalizedVerb = normalizeVerb(verb);
10367
10545
  switch (normalizedVerb) {
10368
- case "create":
10546
+ case 'create':
10369
10547
  return Plus;
10370
- case "update":
10548
+ case 'update':
10371
10549
  return Pencil;
10372
- case "delete":
10550
+ case 'delete':
10373
10551
  return Trash2;
10374
10552
  default:
10375
10553
  return Activity;
10376
10554
  }
10377
10555
  }
10556
+
10557
+ // Number of columns rendered for the feed variant. Used as the colSpan on
10558
+ // the expanded-detail row so it stretches across the full width.
10559
+ const ACTIVITY_FEED_COLUMN_COUNT = 5;
10560
+ /**
10561
+ * Get avatar initials from actor name
10562
+ */
10563
+ function getActorInitials(name) {
10564
+ const parts = name.split(/[@\s.]+/).filter(Boolean);
10565
+ if (parts.length === 0)
10566
+ return "?";
10567
+ if (parts.length === 1)
10568
+ return parts[0].charAt(0).toUpperCase();
10569
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
10570
+ }
10571
+ /**
10572
+ * Get Tailwind classes for actor avatar based on actor type
10573
+ */
10574
+ function getActorAvatarClasses(actorType, compact) {
10575
+ const baseClasses = cn("rounded-full flex items-center justify-center shrink-0 font-semibold", compact ? "w-5 h-5 text-1xs" : "w-6 h-6 text-1xs");
10576
+ switch (actorType) {
10577
+ case "user":
10578
+ return cn(baseClasses, "bg-primary text-primary-foreground");
10579
+ case "controller":
10580
+ return cn(baseClasses, "bg-secondary text-secondary-foreground");
10581
+ case "machine account":
10582
+ return cn(baseClasses, "bg-muted text-muted-foreground");
10583
+ default:
10584
+ return cn(baseClasses, "bg-muted text-muted-foreground");
10585
+ }
10586
+ }
10378
10587
  /**
10379
10588
  * ActivityFeedItem renders a single activity in the feed or timeline
10380
10589
  */
10381
- function ActivityFeedItem({ activity, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActorClick, onActivityClick, isSelected = false, className = "", compact = false, isNew = false, variant = "feed", isLast = false, defaultExpanded = false, }) {
10590
+ function ActivityFeedItem({ activity, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActorClick, onActivityClick, isSelected = false, className = "", compact = false, isNew = false, variant = "feed", isLast = false, defaultExpanded = false, density = "default", }) {
10382
10591
  const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);
10383
10592
  const { spec, metadata } = activity;
10384
10593
  const { actor, summary, links, tenant } = spec;
@@ -10399,7 +10608,7 @@ function ActivityFeedItem({ activity, onResourceClick, resourceLinkResolver, ten
10399
10608
  if (isTimeline) {
10400
10609
  const { container: iconBg, icon: iconColor } = getActionIconClasses(verb);
10401
10610
  const Icon = getTimelineIcon(verb);
10402
- return (jsxRuntime.jsxs("div", { className: cn(!isLast && !isExpanded && "border-b border-border", className), children: [jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3 py-3 cursor-pointer group", isSelected && "bg-muted/40"), onClick: toggleExpand, children: [jsxRuntime.jsx("div", { className: cn("w-8 h-8 rounded-md shrink-0 flex items-center justify-center", iconBg, iconColor), children: jsxRuntime.jsx(Icon, { size: 16, strokeWidth: 2 }) }), jsxRuntime.jsx("div", { className: "flex-1 min-w-0 text-sm text-foreground leading-snug", children: jsxRuntime.jsx(ActivityFeedSummary, { summary: summary, links: links, onResourceClick: onResourceClick, resourceLinkResolver: resourceLinkResolver, resourceLinkContext: { tenant } }) }), tenant && (jsxRuntime.jsx("div", { className: "shrink-0", children: tenantRenderer ? (tenantRenderer(tenant)) : (jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver, size: "compact" })) })), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", className: "h-5 py-0 px-1 text-base text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0", onClick: toggleExpand, "aria-expanded": isExpanded, children: isExpanded ? "−" : "+" })] }), isExpanded && (jsxRuntime.jsx(ActivityExpandedDetails, { activity: activity, tenantLinkResolver: tenantLinkResolver, compact: true }))] }));
10611
+ return (jsxRuntime.jsxs("div", { className: cn(!isLast && !isExpanded && "border-b border-border", className), children: [jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3 cursor-pointer group", density === "compact" ? "py-1.5" : "py-3", isSelected && "bg-muted/40"), onClick: toggleExpand, children: [jsxRuntime.jsx("div", { className: cn("rounded-md shrink-0 flex items-center justify-center", density === "compact" ? "w-6 h-6" : "w-8 h-8", iconBg, iconColor), children: jsxRuntime.jsx(Icon, { size: 16, strokeWidth: 2 }) }), jsxRuntime.jsx("div", { className: "flex-1 min-w-0 text-sm text-foreground leading-snug", children: jsxRuntime.jsx(ActivityFeedSummary, { summary: summary, links: links, onResourceClick: onResourceClick, resourceLinkResolver: resourceLinkResolver, resourceLinkContext: { tenant } }) }), tenant && (jsxRuntime.jsx("div", { className: "shrink-0", children: tenantRenderer ? (tenantRenderer(tenant)) : (jsxRuntime.jsx(TenantBadge, { tenant: tenant, tenantLinkResolver: tenantLinkResolver, size: "compact" })) })), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", className: "h-5 py-0 px-1 text-base text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0", onClick: toggleExpand, "aria-expanded": isExpanded, children: isExpanded ? "−" : "+" })] }), isExpanded && (jsxRuntime.jsx(ActivityExpandedDetails, { activity: activity, tenantLinkResolver: tenantLinkResolver, compact: true }))] }));
10403
10612
  }
10404
10613
  // Feed variant — flat-column table row. Columns: Actor | Summary |
10405
10614
  // Tenant | When | expand toggle. Renders an additional TableRow with a
@@ -10413,7 +10622,7 @@ function ActivityFeedItem({ activity, onResourceClick, resourceLinkResolver, ten
10413
10622
  // surfaced via a hover tooltip on the avatar so the column stays narrow.
10414
10623
  const actorTooltipBody = (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 text-xs", children: [jsxRuntime.jsx("span", { className: "font-medium", children: actorVisible }), actor.email && actor.email !== actorVisible ? (jsxRuntime.jsx("span", { className: "font-mono", children: actor.email })) : null, actor.uid ? (jsxRuntime.jsx("span", { className: "font-mono opacity-70", children: actor.uid })) : null] }));
10415
10624
  const actorCell = (jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: avatar }), jsxRuntime.jsx(TooltipContent, { children: actorTooltipBody })] }));
10416
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? "selected" : undefined, className: cn("cursor-pointer", isNew && "bg-green-50/40 dark:bg-green-950/20", className), onClick: (e) => {
10625
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? "selected" : undefined, className: cn("cursor-pointer", isNew && "bg-[var(--success-100)]/60", className), onClick: (e) => {
10417
10626
  // Row-level click toggles expansion. Inner interactive elements
10418
10627
  // (links, avatar, expand button) call e.stopPropagation() so
10419
10628
  // they don't double-fire. If a parent passed onActivityClick,
@@ -10584,6 +10793,18 @@ function useFacets(client, timeRange, filters = {}) {
10584
10793
  };
10585
10794
  }
10586
10795
 
10796
+ /**
10797
+ * SegmentedToggle - a single-select control built on datum-ui's ButtonGroup.
10798
+ * The active segment is a solid primary Button; inactive segments sit on the
10799
+ * neutral (muted) button surface so the control reads in both themes.
10800
+ */
10801
+ function SegmentedToggle({ options, value, onChange, ariaLabel, className, disabled = false, }) {
10802
+ return (jsxRuntime.jsx(buttonGroup.ButtonGroup, { "aria-label": ariaLabel, className: className, children: options.map((option) => {
10803
+ const active = value === option.value;
10804
+ return (jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", type: active ? 'primary' : 'quaternary', theme: active ? 'solid' : 'light', className: cn('font-medium', !active && 'border border-border'), onClick: () => onChange(option.value), disabled: disabled, "aria-pressed": active, title: option.description, children: option.label }, option.value));
10805
+ }) }));
10806
+ }
10807
+
10587
10808
  /**
10588
10809
  * Options for the change source toggle
10589
10810
  */
@@ -10607,17 +10828,8 @@ const OPTIONS$1 = [
10607
10828
  /**
10608
10829
  * ChangeSourceToggle provides a segmented control for filtering by change source
10609
10830
  */
10610
- function ChangeSourceToggle({ value, onChange, className = "", disabled = false, }) {
10611
- return (jsxRuntime.jsx("div", { className: cn("inline-flex border border-input rounded-md overflow-hidden", className), role: "group", "aria-label": "Filter by change source", children: OPTIONS$1.map((option, index) => {
10612
- const active = value === option.value;
10613
- return (jsxRuntime.jsx(button.Button, { htmlType: "button", type: active ? 'primary' : 'quaternary', theme: active ? 'solid' : 'borderless', className: cn('px-2 h-7 text-xs font-medium transition-all duration-200', index < OPTIONS$1.length - 1 && 'border-r border-input', !active && 'bg-muted text-foreground hover:bg-muted/80'),
10614
- // Inline styles win over datum-ui's baked-in `rounded-lg` and
10615
- // (for the primary/solid active button) its own `border`. The
10616
- // outer wrapper's rounded-md + overflow-hidden draws the
10617
- // segmented control's outer corners; per-button border-right
10618
- // (className) draws the separators between inactive buttons.
10619
- style: active ? { borderRadius: 0, border: 0 } : { borderRadius: 0 }, onClick: () => onChange(option.value), disabled: disabled, "aria-pressed": active, title: option.description, children: option.label }, option.value));
10620
- }) }));
10831
+ function ChangeSourceToggle({ value, onChange, className, disabled = false, }) {
10832
+ return (jsxRuntime.jsx(SegmentedToggle, { options: OPTIONS$1, value: value, onChange: onChange, ariaLabel: "Filter by change source", className: className, disabled: disabled }));
10621
10833
  }
10622
10834
 
10623
10835
  /**
@@ -10689,7 +10901,7 @@ const getSelectedPreset$1 = (timeRange) => {
10689
10901
  /**
10690
10902
  * ActivityFeedFilters provides filter controls for the activity feed
10691
10903
  */
10692
- function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTimeRangeChange, disabled = false, hiddenFilters = [], className = "", extraFilters, }) {
10904
+ function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTimeRangeChange, disabled = false, hiddenFilters = [], className = "", extraFilters, layout = "inline", }) {
10693
10905
  const { resourceKinds, actorNames, apiGroups, resourceNamespaces, error: facetsError, } = useFacets(client, timeRange, filters);
10694
10906
  // Log facets error for debugging
10695
10907
  if (facetsError) {
@@ -10909,12 +11121,186 @@ function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTi
10909
11121
  clearTimeout(searchDebounceRef.current);
10910
11122
  onFiltersChangeRef.current({ ...filtersRef.current, search: undefined });
10911
11123
  }, []);
10912
- return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [!hiddenFilters.includes("changeSource") && (jsxRuntime.jsx(ChangeSourceToggle, { value: filters.changeSource || "all", onChange: handleChangeSourceChange, disabled: disabled })), jsxRuntime.jsxs("div", { className: "relative min-w-[200px] flex-1 max-w-xs", children: [jsxRuntime.jsx(Search, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(input.Input, { type: "text", placeholder: "Search activities...", value: searchInputValue, onChange: handleSearchChange, className: "pl-8 h-7 text-xs pr-6" }), searchInputValue && (jsxRuntime.jsx("button", { onClick: handleSearchClear, className: "absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors", "aria-label": "Clear search", children: jsxRuntime.jsx(X, { className: "h-3.5 w-3.5" }) }))] }), activeFilterIds.map((filterId) => {
11124
+ const searchInput = (jsxRuntime.jsxs("div", { className: "relative min-w-[200px] flex-1 max-w-xs", children: [jsxRuntime.jsx(Search, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(input.Input, { type: "text", placeholder: "Search activities...", value: searchInputValue, onChange: handleSearchChange, className: "pl-8 h-7 text-xs pr-6" }), searchInputValue && (jsxRuntime.jsx("button", { onClick: handleSearchClear, className: "absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors", "aria-label": "Clear search", children: jsxRuntime.jsx(X, { className: "h-3.5 w-3.5" }) }))] }));
11125
+ const changeSourceControl = !hiddenFilters.includes("changeSource") && (jsxRuntime.jsx(ChangeSourceToggle, { value: filters.changeSource || "all", onChange: handleChangeSourceChange, disabled: disabled }));
11126
+ const filterChips = activeFilterIds.map((filterId) => {
11127
+ const config = FILTER_CONFIGS$1[filterId];
11128
+ return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === "typeahead"
11129
+ ? getFilterOptions(filterId)
11130
+ : undefined, onValuesChange: (values) => handleFilterChange(filterId, values), onClear: () => handleFilterClear(filterId), onPopoverClose: () => handlePopoverClose(filterId), inputMode: config.inputMode, placeholder: config.placeholder, searchPlaceholder: config.searchPlaceholder, autoOpen: pendingFilter === filterId, disabled: disabled }, filterId));
11131
+ });
11132
+ const addFilterControl = (jsxRuntime.jsx(AddFilterDropdown, { availableFilters: availableFilters, activeFilterIds: activeFilterIds, onAddFilter: handleAddFilter, hasActiveFilters: activeFilterIds.length > 0, disabled: disabled }));
11133
+ const timeRangeControl = (jsxRuntime.jsx(TimeRangeDropdown, { presets: TIME_PRESETS$1, selectedPreset: selectedPreset, onPresetSelect: handleTimePresetSelect, onCustomRangeApply: handleCustomRangeApply, customStart: customStart, customEnd: customEnd, disabled: disabled, displayLabel: getTimeRangeLabel() }));
11134
+ if (layout === "compact") {
11135
+ const activeFilterCount = activeFilterIds.length +
11136
+ (!hiddenFilters.includes("changeSource") &&
11137
+ filters.changeSource &&
11138
+ filters.changeSource !== "all"
11139
+ ? 1
11140
+ : 0);
11141
+ return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [searchInput, jsxRuntime.jsxs(popover.Popover, { children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", disabled: disabled, className: cn("flex h-7 items-center gap-1.5 rounded-md border border-border bg-background px-2 text-xs", "text-muted-foreground hover:text-foreground hover:border-foreground/50 transition-colors", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", "disabled:cursor-not-allowed disabled:opacity-50"), children: [jsxRuntime.jsx(SlidersHorizontal, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { className: "font-medium", children: "Filters" }), activeFilterCount > 0 && (jsxRuntime.jsx("span", { className: "ml-0.5 rounded-full bg-primary text-primary-foreground text-[10px] font-semibold leading-none px-1.5 py-0.5", children: activeFilterCount }))] }) }), jsxRuntime.jsx(popover.PopoverContent, { className: "w-[320px] p-3", sideOffset: 4, align: "start", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [changeSourceControl, jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [filterChips, addFilterControl] }), extraFilters, timeRangeControl] }) })] })] }) }));
11142
+ }
11143
+ return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [!hiddenFilters.includes("changeSource") && (jsxRuntime.jsx(ChangeSourceToggle, { value: filters.changeSource || "all", onChange: handleChangeSourceChange, disabled: disabled })), jsxRuntime.jsxs("div", { className: "relative min-w-[200px] flex-1 max-w-xs", children: [jsxRuntime.jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(input.Input, { type: "text", placeholder: "Search activities...", value: searchInputValue, onChange: handleSearchChange, className: "h-9 pl-9 pr-9 text-xs md:text-xs" }), searchInputValue && (jsxRuntime.jsx("button", { onClick: handleSearchClear, className: "absolute right-0 top-0 flex h-9 w-9 items-center justify-center rounded-r-lg text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "aria-label": "Clear search", children: jsxRuntime.jsx(X, { className: "h-3.5 w-3.5" }) }))] }), activeFilterIds.map((filterId) => {
10913
11144
  const config = FILTER_CONFIGS$1[filterId];
10914
11145
  return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === "typeahead"
10915
11146
  ? getFilterOptions(filterId)
10916
11147
  : undefined, onValuesChange: (values) => handleFilterChange(filterId, values), onClear: () => handleFilterClear(filterId), onPopoverClose: () => handlePopoverClose(filterId), inputMode: config.inputMode, placeholder: config.placeholder, searchPlaceholder: config.searchPlaceholder, autoOpen: pendingFilter === filterId, disabled: disabled }, filterId));
10917
- }), jsxRuntime.jsx(AddFilterDropdown, { availableFilters: availableFilters, activeFilterIds: activeFilterIds, onAddFilter: handleAddFilter, hasActiveFilters: activeFilterIds.length > 0, disabled: disabled }), extraFilters, jsxRuntime.jsx("div", { className: "flex-1 min-w-[20px]" }), jsxRuntime.jsx(TimeRangeDropdown, { presets: TIME_PRESETS$1, selectedPreset: selectedPreset, onPresetSelect: handleTimePresetSelect, onCustomRangeApply: handleCustomRangeApply, customStart: customStart, customEnd: customEnd, disabled: disabled, displayLabel: getTimeRangeLabel() })] }) }));
11148
+ }), jsxRuntime.jsx(AddFilterDropdown, { availableFilters: availableFilters, activeFilterIds: activeFilterIds, onAddFilter: handleAddFilter, hasActiveFilters: activeFilterIds.length > 0, disabled: disabled }), extraFilters, jsxRuntime.jsx("div", { className: "flex-1 min-w-[20px]" }), timeRangeControl] }) }));
11149
+ }
11150
+
11151
+ const KIND_PLURALS = {
11152
+ DNSRecordSet: "DNS records",
11153
+ };
11154
+ function pluralizeKind(kind, count) {
11155
+ if (count === 1)
11156
+ return kind;
11157
+ return KIND_PLURALS[kind] ?? `${kind}s`;
11158
+ }
11159
+ const VERB_LABEL = {
11160
+ create: "created",
11161
+ update: "updated",
11162
+ delete: "deleted",
11163
+ other: "changed",
11164
+ };
11165
+ /**
11166
+ * ActivityFeedGroupItem renders a run of consecutive same verb/kind/actor
11167
+ * activities (see `groupActivities`) as a single collapsed row in the
11168
+ * "digest" timeline. A group of size 1 renders exactly like a normal
11169
+ * `ActivityFeedItem` — no visual change for ungrouped activities. Larger
11170
+ * groups render a synthesized summary ("{actor} created 12 DNS records")
11171
+ * that expands to reveal the individual activities underneath.
11172
+ */
11173
+ function ActivityFeedGroupItem({ group, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActorClick, onActivityClick, isLast = false, }) {
11174
+ const [isExpanded, setIsExpanded] = React.useState(false);
11175
+ if (group.count === 1) {
11176
+ return (jsxRuntime.jsx(ActivityFeedItem, { activity: group.activities[0], resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: onActorClick, onActivityClick: onActivityClick, variant: "timeline", density: "compact", isLast: isLast }));
11177
+ }
11178
+ const { container: iconBg, icon: iconColor } = getActionIconClasses(group.verb);
11179
+ const Icon = getTimelineIcon(group.verb);
11180
+ const actorVisible = group.actorDisplayName || group.actorName;
11181
+ const summary = `${actorVisible} ${VERB_LABEL[group.verb]} ${group.count} ${pluralizeKind(group.kind, group.count)}`;
11182
+ const toggleExpand = (e) => {
11183
+ e.stopPropagation();
11184
+ setIsExpanded((prev) => !prev);
11185
+ };
11186
+ return (jsxRuntime.jsxs("div", { className: cn(!isLast && !isExpanded && "border-b border-border"), children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-3 py-1.5 cursor-pointer group", onClick: toggleExpand, children: [jsxRuntime.jsxs("div", { className: cn("w-6 h-6 rounded-md shrink-0 flex items-center justify-center relative", iconBg, iconColor), children: [jsxRuntime.jsx(Icon, { size: 14, strokeWidth: 2 }), jsxRuntime.jsx("span", { className: "absolute -bottom-1 -right-1 rounded-full bg-background border border-border px-1 text-[10px] font-semibold leading-tight text-foreground", children: group.count })] }), jsxRuntime.jsx("div", { className: "flex-1 min-w-0 text-xs text-foreground leading-normal", children: summary }), group.tenant && (jsxRuntime.jsx("div", { className: "shrink-0", children: tenantRenderer ? (tenantRenderer(group.tenant)) : (jsxRuntime.jsx(TenantBadge, { tenant: group.tenant, tenantLinkResolver: tenantLinkResolver, size: "compact" })) })), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: jsxRuntime.jsx(Timestamp, { value: group.latestTimestamp }) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", className: "h-5 py-0 px-1 text-base text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0", onClick: toggleExpand, "aria-expanded": isExpanded, children: isExpanded ? "−" : "+" })] }), isExpanded && (jsxRuntime.jsx("div", { className: "pl-11 flex flex-col", children: group.activities.map((activity, index) => (jsxRuntime.jsx(ActivityFeedItem, { activity: activity, resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: onActorClick, onActivityClick: onActivityClick, compact: true, density: "compact", variant: "timeline", isLast: index === group.activities.length - 1 }, activity.metadata?.uid || activity.metadata?.name))) }))] }));
11187
+ }
11188
+
11189
+ /**
11190
+ * Thin stat strip summarizing the activities currently loaded in the feed —
11191
+ * e.g. "18 changes · 3 people · 1 system". Computed client-side over the
11192
+ * loaded/paginated activities; it is a quick-glance headline, not a
11193
+ * full-range aggregate (that would require a backend facet query).
11194
+ */
11195
+ function ActivityDigestSummary({ activities, className = "" }) {
11196
+ const stats = React.useMemo(() => {
11197
+ const humanActors = new Set();
11198
+ const systemActors = new Set();
11199
+ for (const activity of activities) {
11200
+ const { actor, changeSource } = activity.spec;
11201
+ if (changeSource === "human") {
11202
+ humanActors.add(actor.name);
11203
+ }
11204
+ else {
11205
+ systemActors.add(actor.name);
11206
+ }
11207
+ }
11208
+ return {
11209
+ total: activities.length,
11210
+ people: humanActors.size,
11211
+ systems: systemActors.size,
11212
+ };
11213
+ }, [activities]);
11214
+ if (stats.total === 0)
11215
+ return null;
11216
+ const parts = [`${stats.total} ${stats.total === 1 ? "change" : "changes"}`];
11217
+ if (stats.people > 0)
11218
+ parts.push(`${stats.people} ${stats.people === 1 ? "person" : "people"}`);
11219
+ if (stats.systems > 0)
11220
+ parts.push(`${stats.systems} ${stats.systems === 1 ? "system" : "systems"}`);
11221
+ return (jsxRuntime.jsx("div", { className: `px-1 pt-4 pb-2 text-xs text-muted-foreground ${className}`, children: parts.join(" · ") }));
11222
+ }
11223
+
11224
+ function tenantKey(tenant) {
11225
+ if (!tenant)
11226
+ return '';
11227
+ return `${tenant.type}:${tenant.name}`;
11228
+ }
11229
+ function groupSignature(activity) {
11230
+ const { spec } = activity;
11231
+ const verb = normalizeVerb(extractVerb(spec.summary));
11232
+ return [verb, spec.resource.kind, spec.actor.name, tenantKey(spec.tenant)].join('|');
11233
+ }
11234
+ /**
11235
+ * Group consecutive activities that share verb + resource kind + actor +
11236
+ * tenant. Activities are assumed to already be sorted newest-first (as
11237
+ * returned by `useActivityFeed`); only adjacent items are merged, so a
11238
+ * burst of matching activities collapses into one group without needing
11239
+ * any time-window heuristics.
11240
+ */
11241
+ function groupActivities(activities) {
11242
+ const groups = [];
11243
+ for (const activity of activities) {
11244
+ const signature = groupSignature(activity);
11245
+ const last = groups[groups.length - 1];
11246
+ if (last && last.key === signature) {
11247
+ last.activities.push(activity);
11248
+ last.count += 1;
11249
+ continue;
11250
+ }
11251
+ const { spec } = activity;
11252
+ groups.push({
11253
+ key: signature,
11254
+ verb: normalizeVerb(extractVerb(spec.summary)),
11255
+ kind: spec.resource.kind,
11256
+ actorName: spec.actor.name,
11257
+ actorDisplayName: spec.actor.displayName,
11258
+ tenant: spec.tenant,
11259
+ activities: [activity],
11260
+ count: 1,
11261
+ latestTimestamp: activity.metadata?.creationTimestamp,
11262
+ });
11263
+ }
11264
+ return groups;
11265
+ }
11266
+ function dayLabel(timestamp) {
11267
+ if (!timestamp)
11268
+ return 'Unknown date';
11269
+ const date = new Date(timestamp);
11270
+ if (Number.isNaN(date.getTime()))
11271
+ return 'Unknown date';
11272
+ if (isToday(date))
11273
+ return 'Today';
11274
+ if (isYesterday(date))
11275
+ return 'Yesterday';
11276
+ return format(date, 'MMMM d, yyyy');
11277
+ }
11278
+ /**
11279
+ * Bucket activities into calendar-day sections (Today / Yesterday / a
11280
+ * formatted date), then group consecutive matching activities within each
11281
+ * day. Bucketing by day first (rather than grouping across the whole list)
11282
+ * keeps a group from silently spanning a day boundary.
11283
+ */
11284
+ function groupActivitiesByDay(activities) {
11285
+ const sections = [];
11286
+ let currentLabel = null;
11287
+ let currentBucket = [];
11288
+ const flush = () => {
11289
+ if (currentLabel !== null && currentBucket.length > 0) {
11290
+ sections.push({ label: currentLabel, groups: groupActivities(currentBucket) });
11291
+ }
11292
+ };
11293
+ for (const activity of activities) {
11294
+ const label = dayLabel(activity.metadata?.creationTimestamp);
11295
+ if (label !== currentLabel) {
11296
+ flush();
11297
+ currentLabel = label;
11298
+ currentBucket = [];
11299
+ }
11300
+ currentBucket.push(activity);
11301
+ }
11302
+ flush();
11303
+ return sections;
10918
11304
  }
10919
11305
 
10920
11306
  /**
@@ -10984,26 +11370,28 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
10984
11370
  React.useEffect(() => {
10985
11371
  isLoadingRef.current = isLoading;
10986
11372
  }, [isLoading]);
10987
- // Infinite scroll using Intersection Observer
11373
+ // Infinite scroll using Intersection Observer.
11374
+ // The list container is the root only when it actually scrolls. Host apps
11375
+ // such as cloud-portal scroll at the page level, so the container never
11376
+ // overflows; in that case observe against the viewport instead.
10988
11377
  React.useEffect(() => {
10989
11378
  if (!infiniteScroll || !hasMore || !loadMoreTriggerRef.current)
10990
11379
  return;
11380
+ const container = scrollContainerRef.current;
11381
+ const containerScrolls = !!container && container.scrollHeight > container.clientHeight + 1;
10991
11382
  const observer = new IntersectionObserver((entries) => {
10992
11383
  const entry = entries[0];
10993
11384
  if (entry.isIntersecting && !isLoadingRef.current) {
10994
- // Call through the ref to always use the latest function
10995
11385
  loadMoreRef.current();
10996
11386
  }
10997
11387
  }, {
10998
- root: scrollContainerRef.current,
11388
+ root: containerScrolls ? container : null,
10999
11389
  rootMargin: `${loadMoreThreshold}px`,
11000
11390
  threshold: 0,
11001
11391
  });
11002
11392
  observer.observe(loadMoreTriggerRef.current);
11003
- return () => {
11004
- observer.disconnect();
11005
- };
11006
- }, [infiniteScroll, loadMoreThreshold, hasMore]);
11393
+ return () => observer.disconnect();
11394
+ }, [infiniteScroll, loadMoreThreshold, hasMore, activities.length]);
11007
11395
  // Handle filter changes - refresh is automatic via the hook
11008
11396
  const handleFiltersChange = React.useCallback((newFilters) => {
11009
11397
  setFilters(newFilters);
@@ -11043,10 +11431,10 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
11043
11431
  // Parent containers must have proper height constraints (h-screen/h-full + overflow-hidden)
11044
11432
  const effectiveMaxHeight = maxHeight === "none" ? undefined : maxHeight;
11045
11433
  const listClasses = "flex-1 min-h-0 overflow-y-auto flex flex-col";
11046
- return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 200, children: jsxRuntime.jsxs(card.Card, { className: containerClasses, children: [enableStreaming && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center", children: [isStreaming && !watchError && (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 dark:bg-green-500 opacity-75" }), jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500 dark:bg-green-400" })] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Streaming activity..." })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "New activities will appear automatically" }) })] }) })), watchError && (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("span", { className: "relative flex h-2 w-2", children: jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-red-500 dark:bg-red-400" }) }), jsxRuntime.jsx("span", { className: "text-xs text-destructive", children: "Connection error" })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "Stream connection lost" }) })] }) })), newActivitiesCount > 0 && !watchError && (jsxRuntime.jsxs(Badge, { variant: "secondary", className: "text-xs", children: ["+", newActivitiesCount, " new"] }))] }), jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: handleStreamingToggle, children: watchError ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", strokeWidth: "2", children: [jsxRuntime.jsx("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" }), jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "3" })] }), "Retry"] })) : isStreaming ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [jsxRuntime.jsx("rect", { x: "6", y: "4", width: "4", height: "16" }), jsxRuntime.jsx("rect", { x: "14", y: "4", width: "4", height: "16" })] }), "Pause"] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("polygon", { points: "5,3 19,12 5,21", fill: "currentColor" }) }), "Resume"] })) })] })), showFilters && (jsxRuntime.jsx(ActivityFeedFilters, { client: client, filters: filters, timeRange: timeRange, onFiltersChange: handleFiltersChange, onTimeRangeChange: handleTimeRangeChange, disabled: isLoading, hiddenFilters: hiddenFilters })), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-4", errorFormatter: errorFormatter }), jsxRuntime.jsx(ApiErrorAlert, { error: watchError, onRetry: startStreaming, className: "mb-4", errorFormatter: errorFormatter }), !policiesLoading && hasPolicies === false && (jsxRuntime.jsxs("div", { className: "flex flex-col items-center py-12 px-8 text-center bg-muted border border-dashed border-border rounded-xl mb-4", children: [jsxRuntime.jsx("div", { className: "flex justify-center mb-4 text-muted-foreground", children: jsxRuntime.jsxs("svg", { width: "56", height: "56", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2" }), jsxRuntime.jsx("rect", { x: "9", y: "3", width: "6", height: "4", rx: "1" }), jsxRuntime.jsx("path", { d: "M9 12h6" }), jsxRuntime.jsx("path", { d: "M9 16h6" })] }) }), jsxRuntime.jsx("h3", { className: "m-0 mb-2 text-lg font-semibold text-foreground leading-snug", children: "Get started with activity logging" }), jsxRuntime.jsx("p", { className: "m-0 mb-6 text-sm leading-relaxed text-muted-foreground max-w-[400px]", children: "Activity policies define which resources to track and how to summarize changes. Create your first policy to start seeing activity logs here." }), onCreatePolicy && (jsxRuntime.jsx(button.Button, { onClick: onCreatePolicy, children: "Create Policy" }))] })), jsxRuntime.jsxs("div", { className: listClasses, ref: scrollContainerRef, style: effectiveMaxHeight ? { maxHeight: effectiveMaxHeight } : undefined, children: [!isLoading &&
11434
+ return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 200, children: jsxRuntime.jsxs(card.Card, { className: containerClasses, children: [enableStreaming && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center", children: [isStreaming && !watchError && (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-[var(--success-500)] opacity-75" }), jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-[var(--success-500)]" })] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Streaming activity..." })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "New activities will appear automatically" }) })] }) })), watchError && (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("span", { className: "relative flex h-2 w-2", children: jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-destructive" }) }), jsxRuntime.jsx("span", { className: "text-xs text-destructive", children: "Connection error" })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "Stream connection lost" }) })] }) })), newActivitiesCount > 0 && !watchError && (jsxRuntime.jsxs(Badge, { variant: "secondary", className: "text-xs", children: ["+", newActivitiesCount, " new"] }))] }), jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: handleStreamingToggle, children: watchError ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", strokeWidth: "2", children: [jsxRuntime.jsx("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" }), jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "3" })] }), "Retry"] })) : isStreaming ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [jsxRuntime.jsx("rect", { x: "6", y: "4", width: "4", height: "16" }), jsxRuntime.jsx("rect", { x: "14", y: "4", width: "4", height: "16" })] }), "Pause"] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("polygon", { points: "5,3 19,12 5,21", fill: "currentColor" }) }), "Resume"] })) })] })), showFilters && (jsxRuntime.jsx(ActivityFeedFilters, { client: client, filters: filters, timeRange: timeRange, onFiltersChange: handleFiltersChange, onTimeRangeChange: handleTimeRangeChange, disabled: isLoading, hiddenFilters: hiddenFilters, layout: variant === "digest" ? "compact" : "inline" })), variant === "digest" && !isLoading && activities.length > 0 && (jsxRuntime.jsx(ActivityDigestSummary, { activities: activities })), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-4", errorFormatter: errorFormatter }), jsxRuntime.jsx(ApiErrorAlert, { error: watchError, onRetry: startStreaming, className: "mb-4", errorFormatter: errorFormatter }), !policiesLoading && hasPolicies === false && (jsxRuntime.jsxs("div", { className: "flex flex-col items-center py-12 px-8 text-center bg-muted border border-dashed border-border rounded-xl mb-4", children: [jsxRuntime.jsx("div", { className: "flex justify-center mb-4 text-muted-foreground", children: jsxRuntime.jsxs("svg", { width: "56", height: "56", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2" }), jsxRuntime.jsx("rect", { x: "9", y: "3", width: "6", height: "4", rx: "1" }), jsxRuntime.jsx("path", { d: "M9 12h6" }), jsxRuntime.jsx("path", { d: "M9 16h6" })] }) }), jsxRuntime.jsx("h3", { className: "m-0 mb-2 text-lg font-semibold text-foreground leading-snug", children: "Get started with activity logging" }), jsxRuntime.jsx("p", { className: "m-0 mb-6 text-sm leading-relaxed text-muted-foreground max-w-[400px]", children: "Activity policies define which resources to track and how to summarize changes. Create your first policy to start seeing activity logs here." }), onCreatePolicy && (jsxRuntime.jsx(button.Button, { onClick: onCreatePolicy, children: "Create Policy" }))] })), jsxRuntime.jsxs("div", { className: listClasses, ref: scrollContainerRef, style: effectiveMaxHeight ? { maxHeight: effectiveMaxHeight } : undefined, children: [!isLoading &&
11047
11435
  activities.length === 0 &&
11048
11436
  hasPolicies !== false &&
11049
- variant === "timeline" && (jsxRuntime.jsxs("div", { className: "py-12 text-center text-muted-foreground", children: [jsxRuntime.jsx("p", { className: "m-0", children: "No activities found" }), jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-2 m-0", children: "Try adjusting your filters or time range" })] })), variant === "timeline" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isLoading && activities.length === 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsx(ActivityFeedItemSkeleton, { compact: compact }, index))) })), activities.map((activity, index) => (jsxRuntime.jsx(ActivityFeedItem, { activity: activity, onResourceClick: onResourceClick, resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: handleActorClick, onActivityClick: onActivityClick, compact: compact, isNew: enableStreaming && index < newActivitiesCount, variant: variant, isLast: index === activities.length - 1 }, activity.metadata?.uid || activity.metadata?.name)))] })) : (jsxRuntime.jsxs(table.Table, { className: "w-full", children: [jsxRuntime.jsx(table.TableHeader, { children: jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableHead, { className: "w-12", "aria-label": "Actor" }), jsxRuntime.jsx(table.TableHead, { children: "Summary" }), jsxRuntime.jsx(table.TableHead, { children: "Tenant" }), jsxRuntime.jsx(table.TableHead, { className: "w-[170px]", children: "When" }), jsxRuntime.jsx(table.TableHead, { className: "w-10", "aria-label": "Expand" })] }) }), jsxRuntime.jsxs(table.TableBody, { children: [isLoading && activities.length === 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-6 rounded-full" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-3/4" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-32 rounded-full" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-6" }) })] }, `sk-${index}`))) })), !isLoading &&
11437
+ (variant === "timeline" || variant === "digest") && (jsxRuntime.jsxs("div", { className: "py-12 text-center text-muted-foreground", children: [jsxRuntime.jsx("p", { className: "m-0", children: "No activities found" }), jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-2 m-0", children: "Try adjusting your filters or time range" })] })), variant === "digest" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isLoading && activities.length === 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsx(ActivityFeedItemSkeleton, { compact: compact }, index))) })), groupActivitiesByDay(activities).map((section) => (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-card pt-2 pb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: section.label }), section.groups.map((group, index) => (jsxRuntime.jsx(ActivityFeedGroupItem, { group: group, resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: handleActorClick, onActivityClick: onActivityClick, isLast: index === section.groups.length - 1 }, `${section.label}-${group.key}-${index}`)))] }, section.label)))] })) : variant === "timeline" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isLoading && activities.length === 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsx(ActivityFeedItemSkeleton, { compact: compact }, index))) })), activities.map((activity, index) => (jsxRuntime.jsx(ActivityFeedItem, { activity: activity, onResourceClick: onResourceClick, resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: handleActorClick, onActivityClick: onActivityClick, compact: compact, isNew: enableStreaming && index < newActivitiesCount, variant: variant, isLast: index === activities.length - 1 }, activity.metadata?.uid || activity.metadata?.name)))] })) : (jsxRuntime.jsxs(table.Table, { className: "w-full", children: [jsxRuntime.jsx(table.TableHeader, { children: jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableHead, { className: "w-12", "aria-label": "Actor" }), jsxRuntime.jsx(table.TableHead, { children: "Summary" }), jsxRuntime.jsx(table.TableHead, { children: "Tenant" }), jsxRuntime.jsx(table.TableHead, { className: "w-[170px]", children: "When" }), jsxRuntime.jsx(table.TableHead, { className: "w-10", "aria-label": "Expand" })] }) }), jsxRuntime.jsxs(table.TableBody, { children: [isLoading && activities.length === 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-6 rounded-full" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-3/4" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-32 rounded-full" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-6" }) })] }, `sk-${index}`))) })), !isLoading &&
11050
11438
  activities.length === 0 &&
11051
11439
  hasPolicies !== false && (jsxRuntime.jsx(table.TableRow, { children: jsxRuntime.jsxs(table.TableCell, { colSpan: ACTIVITY_FEED_COLUMN_COUNT, className: "text-center py-12 text-muted-foreground", children: [jsxRuntime.jsx("div", { children: "No activities found" }), jsxRuntime.jsx("div", { className: "text-sm mt-2", children: "Try adjusting your filters or time range" })] }) })), activities.map((activity, index) => (jsxRuntime.jsx(ActivityFeedItem, { activity: activity, onResourceClick: onResourceClick, resourceLinkResolver: resourceLinkResolver, tenantLinkResolver: tenantLinkResolver, tenantRenderer: tenantRenderer, onActorClick: handleActorClick, onActivityClick: onActivityClick, compact: compact, isNew: enableStreaming && index < newActivitiesCount, variant: variant, isLast: index === activities.length - 1 }, activity.metadata?.uid || activity.metadata?.name)))] })] })), infiniteScroll && hasMore && (jsxRuntime.jsx("div", { ref: loadMoreTriggerRef, className: "h-px mt-4" })), !infiniteScroll && activities.length > 0 ? (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3 border-t border-border text-sm text-muted-foreground", children: [jsxRuntime.jsxs("span", { children: [activities.length, " ", activities.length === 1 ? "activity" : "activities", hasMore ? " so far" : ""] }), hasMore ? (jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", htmlType: "button", onClick: handleLoadMoreClick, disabled: isLoading, children: isLoading ? "Loading…" : "Load more" })) : (jsxRuntime.jsx("span", { children: "End of results" }))] })) : null] })] }) }));
11052
11440
  }
@@ -11697,7 +12085,7 @@ function useEventsFeed({ client, initialFilters = {}, initialTimeRange = { start
11697
12085
  function getRegarding$1(event) {
11698
12086
  return event.regarding || event.involvedObject || {};
11699
12087
  }
11700
- function getReportingController$1(event) {
12088
+ function getReportingController(event) {
11701
12089
  return event.reportingController || event.reportingComponent || event.source?.component;
11702
12090
  }
11703
12091
  function getReportingInstance(event) {
@@ -11710,7 +12098,7 @@ function getReportingInstance(event) {
11710
12098
  */
11711
12099
  function EventExpandedDetails({ event, compact = true }) {
11712
12100
  const regarding = getRegarding$1(event);
11713
- const reportingController = getReportingController$1(event);
12101
+ const reportingController = getReportingController(event);
11714
12102
  const reportingInstance = getReportingInstance(event);
11715
12103
  const { eventTime, action, metadata, related } = event;
11716
12104
  const firstTimestamp = event.firstTimestamp || event.deprecatedFirstTimestamp;
@@ -11737,12 +12125,6 @@ function getRegarding(event) {
11737
12125
  function getNote(event) {
11738
12126
  return event.note || event.message;
11739
12127
  }
11740
- /**
11741
- * Get the reporting controller (handling both new and deprecated field names)
11742
- */
11743
- function getReportingController(event) {
11744
- return event.reportingController || event.source?.component;
11745
- }
11746
12128
  /**
11747
12129
  * Get the event count (handling both new and deprecated field names)
11748
12130
  */
@@ -11778,7 +12160,6 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11778
12160
  const note = getNote(event);
11779
12161
  const count = getCount(event);
11780
12162
  const timestamp = getTimestamp(event);
11781
- getReportingController(event);
11782
12163
  const { type, reason } = event;
11783
12164
  const handleClick = () => {
11784
12165
  onEventClick?.(event);
@@ -11821,11 +12202,11 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11821
12202
  if (variant === 'timeline') {
11822
12203
  const TypeIcon = isWarning ? TriangleAlert : Bell;
11823
12204
  const iconBg = isWarning
11824
- ? 'bg-red-50 dark:bg-red-950'
11825
- : 'bg-blue-50 dark:bg-blue-950';
12205
+ ? 'bg-destructive/10'
12206
+ : 'bg-[var(--info-100)]';
11826
12207
  const iconColor = isWarning
11827
- ? 'text-red-500 dark:text-red-400'
11828
- : 'text-blue-500 dark:text-blue-400';
12208
+ ? 'text-destructive'
12209
+ : 'text-[var(--info-500)]';
11829
12210
  const objectLabel = regarding.namespace
11830
12211
  ? `${regarding.kind || 'Unknown'} · ${regarding.namespace}/${regarding.name || ''}`
11831
12212
  : `${regarding.kind || 'Unknown'} · ${regarding.name || ''}`;
@@ -11838,18 +12219,16 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11838
12219
  cursor: 'help',
11839
12220
  }, children: summary }) }), jsxRuntime.jsx(TooltipContent, { className: "max-w-[480px] whitespace-normal break-words", children: summary })] })] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0 max-w-[200px] truncate", title: objectLabel, children: regarding.name }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", htmlType: "button", className: "h-5 py-0 px-1 text-muted-foreground hover:text-foreground shrink-0", onClick: toggleExpand, "aria-expanded": isExpanded, children: isExpanded ? jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4" }) : jsxRuntime.jsx(ChevronRight, { className: "h-4 w-4" }) })] }), isExpanded ? jsxRuntime.jsx(EventExpandedDetails, { event: event }) : null] }));
11840
12221
  }
11841
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? 'selected' : undefined, className: cn('cursor-pointer', isNew && 'bg-green-50/40 dark:bg-green-950/20', isWarning && !isSelected && 'border-l-2 border-l-red-400', className), onClick: (e) => {
12222
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(table.TableRow, { "data-state": isSelected ? 'selected' : undefined, className: cn('cursor-pointer', isNew && 'bg-[var(--success-100)]/60', isWarning && !isSelected && 'border-l-2 border-l-destructive', className), onClick: (e) => {
11842
12223
  toggleExpand(e);
11843
12224
  handleClick();
11844
- }, "aria-expanded": isExpanded, children: [jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap", children: jsxRuntime.jsx("span", { className: cn('inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium', isWarning
11845
- ? 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300'
11846
- : 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300'), children: type || 'Unknown' }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap text-sm font-medium", children: reason || '' }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle", style: { width: '100%', maxWidth: 0, overflow: 'hidden' }, children: note ? (jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground leading-snug", style: {
12225
+ }, "aria-expanded": isExpanded, children: [jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap", children: jsxRuntime.jsx(badge.Badge, { type: isWarning ? 'danger' : 'info', theme: "light", className: "px-1.5 py-0.5 text-xs font-medium", children: type || 'Unknown' }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap text-sm font-medium", children: reason || '' }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle", style: { width: '100%', maxWidth: 0, overflow: 'hidden' }, children: note ? (jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground leading-snug", style: {
11847
12226
  overflow: 'hidden',
11848
12227
  textOverflow: 'ellipsis',
11849
12228
  whiteSpace: 'nowrap',
11850
12229
  }, children: noteWithCount }) }), jsxRuntime.jsx(TooltipContent, { className: "max-w-[480px] whitespace-normal break-words", children: noteWithCount })] })) : null }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("span", { className: cn('text-sm font-medium text-foreground truncate', onResourceClick && 'cursor-pointer hover:underline hover:text-primary'), onClick: onResourceClick ? handleResourceClick : undefined, style: { maxWidth: 200 }, children: regarding.name || 'Unknown' }) }), jsxRuntime.jsx(TooltipContent, { children: regarding.namespace
11851
12230
  ? `${regarding.kind || 'Unknown'} · ${regarding.namespace}/${regarding.name}`
11852
- : `${regarding.kind || 'Unknown'} · ${regarding.name}` })] }), jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer", "aria-label": "Copy resource name", type: "button", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-green-600 dark:text-green-400" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-gray-500 dark:text-gray-400" })) })] }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap text-sm text-muted-foreground", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle w-10", children: jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", htmlType: "button", className: "h-6 w-6 p-0 text-muted-foreground hover:text-foreground", onClick: toggleExpand, "aria-expanded": isExpanded, "aria-label": isExpanded ? 'Collapse details' : 'Expand details', children: isExpanded ? (jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4" })) : (jsxRuntime.jsx(ChevronRight, { className: "h-4 w-4" })) }) })] }), isExpanded ? (jsxRuntime.jsx(table.TableRow, { className: "bg-muted/30 hover:bg-muted/30", children: jsxRuntime.jsx(table.TableCell, { colSpan: EVENT_COLUMN_COUNT, className: "p-0", children: jsxRuntime.jsx(EventExpandedDetails, { event: event }) }) })) : null] }));
12231
+ : `${regarding.kind || 'Unknown'} · ${regarding.name}` })] }), jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-muted cursor-pointer", "aria-label": "Copy resource name", type: "button", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-[var(--success-500)]" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-muted-foreground" })) })] }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle whitespace-nowrap text-sm text-muted-foreground", children: jsxRuntime.jsx(Timestamp, { value: timestamp }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2 align-middle w-10", children: jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", htmlType: "button", className: "h-6 w-6 p-0 text-muted-foreground hover:text-foreground", onClick: toggleExpand, "aria-expanded": isExpanded, "aria-label": isExpanded ? 'Collapse details' : 'Expand details', children: isExpanded ? (jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4" })) : (jsxRuntime.jsx(ChevronRight, { className: "h-4 w-4" })) }) })] }), isExpanded ? (jsxRuntime.jsx(table.TableRow, { className: "bg-muted/30 hover:bg-muted/30", children: jsxRuntime.jsx(table.TableCell, { colSpan: EVENT_COLUMN_COUNT, className: "p-0", children: jsxRuntime.jsx(EventExpandedDetails, { event: event }) }) })) : null] }));
11853
12232
  }
11854
12233
 
11855
12234
  /**
@@ -11962,11 +12341,8 @@ const OPTIONS = [
11962
12341
  /**
11963
12342
  * EventTypeToggle provides a segmented control for filtering by event type
11964
12343
  */
11965
- function EventTypeToggle({ value, onChange, className = '', disabled = false, }) {
11966
- return (jsxRuntime.jsx("div", { className: cn('inline-flex border border-input rounded-md overflow-hidden', className), role: "group", "aria-label": "Filter by event type", children: OPTIONS.map((option, index) => {
11967
- const active = value === option.value;
11968
- return (jsxRuntime.jsx(button.Button, { htmlType: "button", type: active ? 'primary' : 'quaternary', theme: active ? 'solid' : 'borderless', className: cn('px-2 h-7 text-xs font-medium transition-all duration-200', index < OPTIONS.length - 1 && 'border-r border-input', !active && 'bg-muted text-foreground hover:bg-muted/80'), style: active ? { borderRadius: 0, border: 0 } : { borderRadius: 0 }, onClick: () => onChange(option.value), disabled: disabled, "aria-pressed": active, title: option.description, children: option.label }, option.value));
11969
- }) }));
12344
+ function EventTypeToggle({ value, onChange, className, disabled = false, }) {
12345
+ return (jsxRuntime.jsx(SegmentedToggle, { options: OPTIONS, value: value, onChange: onChange, ariaLabel: "Filter by event type", className: className, disabled: disabled }));
11970
12346
  }
11971
12347
 
11972
12348
  /**
@@ -12210,7 +12586,7 @@ function EventsFeedFilters({ client, filters, timeRange, onFiltersChange, onTime
12210
12586
  search: value || undefined,
12211
12587
  });
12212
12588
  }, [filters, onFiltersChange]);
12213
- return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [!hiddenFilters.includes('eventType') && (jsxRuntime.jsx(EventTypeToggle, { value: eventTypeValue, onChange: handleEventTypeChange, disabled: disabled })), jsxRuntime.jsxs("div", { className: "relative min-w-[200px] flex-1 max-w-xs", children: [jsxRuntime.jsx(Search, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(input.Input, { type: "text", placeholder: "Search events...", value: filters.search || '', onChange: handleSearchChange, disabled: disabled, className: "pl-8 h-7 text-xs pr-6" }), filters.search ? (jsxRuntime.jsx("button", { type: "button", onClick: () => onFiltersChange({ ...filters, search: undefined }), className: "absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors", "aria-label": "Clear search", children: jsxRuntime.jsx(X, { className: "h-3.5 w-3.5" }) })) : null] }), activeFilterIds.map((filterId) => {
12589
+ return (jsxRuntime.jsx("div", { className: `border-b border-border py-4 ${className}`, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [!hiddenFilters.includes('eventType') && (jsxRuntime.jsx(EventTypeToggle, { value: eventTypeValue, onChange: handleEventTypeChange, disabled: disabled })), jsxRuntime.jsxs("div", { className: "relative min-w-[200px] flex-1 max-w-xs", children: [jsxRuntime.jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(input.Input, { type: "text", placeholder: "Search events...", value: filters.search || '', onChange: handleSearchChange, disabled: disabled, className: "h-9 pl-9 pr-9 text-xs md:text-xs" }), filters.search ? (jsxRuntime.jsx("button", { type: "button", onClick: () => onFiltersChange({ ...filters, search: undefined }), className: "absolute right-0 top-0 flex h-9 w-9 items-center justify-center rounded-r-lg text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "aria-label": "Clear search", children: jsxRuntime.jsx(X, { className: "h-3.5 w-3.5" }) })) : null] }), activeFilterIds.map((filterId) => {
12214
12590
  const config = FILTER_CONFIGS[filterId];
12215
12591
  return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === 'typeahead' ? getFilterOptions(filterId) : undefined, onValuesChange: (values) => handleFilterChange(filterId, values), onClear: () => handleFilterClear(filterId), onPopoverClose: () => handlePopoverClose(filterId), inputMode: config.inputMode, placeholder: config.placeholder, searchPlaceholder: config.searchPlaceholder, autoOpen: pendingFilter === filterId, disabled: disabled }, filterId));
12216
12592
  }), jsxRuntime.jsx(AddFilterDropdown, { availableFilters: availableFilters, activeFilterIds: activeFilterIds, onAddFilter: handleAddFilter, hasActiveFilters: activeFilterIds.length > 0, disabled: disabled }), jsxRuntime.jsx("div", { className: "flex-1 min-w-[20px]" }), jsxRuntime.jsx(TimeRangeDropdown, { presets: TIME_PRESETS, selectedPreset: selectedPreset, onPresetSelect: handleTimePresetSelect, onCustomRangeApply: handleCustomRangeApply, customStart: customStart, customEnd: customEnd, disabled: disabled, displayLabel: getTimeRangeLabel() })] }) }));
@@ -12278,7 +12654,7 @@ function EventsFeed({ client, initialFilters = {}, initialTimeRange = { start: "
12278
12654
  : `flex-1 min-h-0 flex flex-col p-3 gap-0 ${className}`;
12279
12655
  // Build list classes - use flex-1 min-h-0 for flex-based scrolling
12280
12656
  const listClasses = "flex-1 min-h-0 overflow-y-auto pr-2";
12281
- return (jsxRuntime.jsxs(card.Card, { className: containerClasses, children: [enableStreaming && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center", children: [isStreaming ? (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 dark:bg-green-500 opacity-75" }), jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500 dark:bg-green-400" })] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Streaming events..." })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "New events will appear automatically" }) })] }) })) : null, newEventsCount > 0 ? (jsxRuntime.jsxs(Badge, { variant: "secondary", className: "text-xs ml-2", children: ["+", newEventsCount, " new"] })) : null] }), jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: handleStreamingToggle, children: isStreaming ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [jsxRuntime.jsx("rect", { x: "6", y: "4", width: "4", height: "16" }), jsxRuntime.jsx("rect", { x: "14", y: "4", width: "4", height: "16" })] }), "Pause"] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("polygon", { points: "5,3 19,12 5,21", fill: "currentColor" }) }), "Resume"] })) })] })), showFilters && (jsxRuntime.jsx(EventsFeedFilters, { client: client, filters: filters, timeRange: timeRange, onFiltersChange: handleFiltersChange, onTimeRangeChange: handleTimeRangeChange, disabled: isLoading, namespace: namespace, hiddenFilters: hiddenFilters })), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-4", errorFormatter: errorFormatter }), jsxRuntime.jsxs("div", { className: listClasses, ref: scrollContainerRef, children: [jsxRuntime.jsx(TooltipProvider, { delayDuration: 200, children: variant === 'timeline' ? (jsxRuntime.jsxs("div", { children: [(isLoading || isRefreshing) && events.length === 0
12657
+ return (jsxRuntime.jsxs(card.Card, { className: containerClasses, children: [enableStreaming && (jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center", children: [isStreaming ? (jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-[var(--success-500)] opacity-75" }), jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-[var(--success-500)]" })] }), jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Streaming events..." })] }) }), jsxRuntime.jsx(TooltipContent, { className: "text-xs", children: jsxRuntime.jsx("p", { children: "New events will appear automatically" }) })] }) })) : null, newEventsCount > 0 ? (jsxRuntime.jsxs(Badge, { variant: "secondary", className: "text-xs ml-2", children: ["+", newEventsCount, " new"] })) : null] }), jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: handleStreamingToggle, children: isStreaming ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [jsxRuntime.jsx("rect", { x: "6", y: "4", width: "4", height: "16" }), jsxRuntime.jsx("rect", { x: "14", y: "4", width: "4", height: "16" })] }), "Pause"] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("svg", { className: "w-4 h-4 mr-1.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("polygon", { points: "5,3 19,12 5,21", fill: "currentColor" }) }), "Resume"] })) })] })), showFilters && (jsxRuntime.jsx(EventsFeedFilters, { client: client, filters: filters, timeRange: timeRange, onFiltersChange: handleFiltersChange, onTimeRangeChange: handleTimeRangeChange, disabled: isLoading, namespace: namespace, hiddenFilters: hiddenFilters })), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-4", errorFormatter: errorFormatter }), jsxRuntime.jsxs("div", { className: listClasses, ref: scrollContainerRef, children: [jsxRuntime.jsx(TooltipProvider, { delayDuration: 200, children: variant === 'timeline' ? (jsxRuntime.jsxs("div", { children: [(isLoading || isRefreshing) && events.length === 0
12282
12658
  ? Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsx("div", { className: cn(index < 7 && 'border-b border-border', compact ? 'py-2' : 'py-3'), children: jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "w-8 h-8 rounded-md shrink-0" }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-3/4" })] }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-32 shrink-0" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24 shrink-0" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-5 shrink-0" })] }) }, `sk-${index}`)))
12283
12659
  : null, !isLoading && !isRefreshing && events.length === 0 ? (jsxRuntime.jsxs("div", { className: "py-12 text-center text-muted-foreground", children: [jsxRuntime.jsx("div", { children: "No events found" }), jsxRuntime.jsx("div", { className: "text-sm mt-2", children: "Try adjusting your filters or time range" })] })) : null, events.map((event, index) => (jsxRuntime.jsx(EventFeedItem, { event: event, onEventClick: onEventClick, onResourceClick: onResourceClick, compact: compact, isNew: enableStreaming && index < newEventsCount, variant: "timeline", isLast: index === events.length - 1 }, event.metadata?.uid || event.metadata?.name)))] })) : (jsxRuntime.jsxs(table.Table, { className: "w-full", children: [jsxRuntime.jsx(table.TableHeader, { children: jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableHead, { className: "w-[90px]", children: "Type" }), jsxRuntime.jsx(table.TableHead, { className: "w-[160px]", children: "Reason" }), jsxRuntime.jsx(table.TableHead, { children: "Note" }), jsxRuntime.jsx(table.TableHead, { className: "w-[220px]", children: "Object" }), jsxRuntime.jsx(table.TableHead, { className: "w-[170px]", children: "When" }), jsxRuntime.jsx(table.TableHead, { className: "w-10", "aria-label": "Expand" })] }) }), jsxRuntime.jsxs(table.TableBody, { children: [(isLoading || isRefreshing) && events.length === 0
12284
12660
  ? Array.from({ length: 8 }).map((_, index) => (jsxRuntime.jsxs(table.TableRow, { children: [jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-14 rounded" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-3/4" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-32" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }) }), jsxRuntime.jsx(table.TableCell, { className: "py-2", children: jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-6" }) })] }, `sk-${index}`)))
@@ -12458,14 +12834,14 @@ function PolicyList({ client, onViewPolicy, onEditPolicy, onCreatePolicy, groupB
12458
12834
  policyList.policies.length === 0 && (jsxRuntime.jsxs("div", { className: "text-center py-8 px-6 text-muted-foreground", children: [jsxRuntime.jsx("div", { className: "text-4xl mb-3", children: "\uD83D\uDCCB" }), jsxRuntime.jsx("h3", { className: "m-0 mb-1.5 text-foreground", children: "No policies found" }), jsxRuntime.jsx("p", { className: "m-0 mb-4 max-w-[400px] mx-auto", children: "Activity policies define how audit events and Kubernetes events are translated into human-readable activity summaries." }), onCreatePolicy && (jsxRuntime.jsx(button.Button, { size: "small", onClick: onCreatePolicy, className: "bg-primary text-primary-foreground hover:bg-primary/90 h-7 text-xs", children: "Create your first policy" }))] })), policyList.groups.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-col gap-2.5", children: policyList.groups.map((group) => (jsxRuntime.jsxs("div", { className: "border border-input rounded-lg overflow-hidden", children: [jsxRuntime.jsxs("button", { type: "button", className: "w-full flex items-center gap-2.5 px-3 py-2 bg-muted border-none cursor-pointer text-left text-xs font-medium text-foreground transition-colors duration-200 hover:bg-accent", onClick: () => toggleGroup(group.apiGroup), children: [jsxRuntime.jsx("span", { className: `text-xs text-muted-foreground transition-transform duration-200 ${expandedGroups.has(group.apiGroup) ? "rotate-90" : ""}`, children: "\u25B6" }), jsxRuntime.jsx("span", { className: "flex-1 font-mono", children: group.apiGroup }), jsxRuntime.jsx(Badge, { variant: "secondary", className: "rounded-full", children: group.policies.length })] }), expandedGroups.has(group.apiGroup) && (jsxRuntime.jsx("div", { className: "p-1.5", children: jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Kind" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input w-24 text-xs whitespace-nowrap", children: "Audit Rules" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input w-24 text-xs whitespace-nowrap", children: "Event Rules" })] }) }), jsxRuntime.jsx("tbody", { children: group.policies.map((policy) => {
12459
12835
  const rules = countRules(policy);
12460
12836
  const policyStatus = getPolicyStatus(policy);
12461
- return (jsxRuntime.jsxs("tr", { className: `hover:bg-muted transition-colors ${handlePolicyClick ? "cursor-pointer" : ""}`, onClick: () => handlePolicyClick?.(policy.metadata?.name || ""), children: [jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [policyStatus.status === "ready" ? (jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full bg-green-500", title: policyStatus.message })) : (jsxRuntime.jsx("div", { title: policyStatus.message, children: jsxRuntime.jsx(TriangleAlert, { className: `w-4 h-4 ${policyStatus.status === "error"
12462
- ? "text-red-500 dark:text-red-400"
12837
+ return (jsxRuntime.jsxs("tr", { className: `hover:bg-muted transition-colors ${handlePolicyClick ? "cursor-pointer" : ""}`, onClick: () => handlePolicyClick?.(policy.metadata?.name || ""), children: [jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [policyStatus.status === "ready" ? (jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full bg-[var(--success-500)]", title: policyStatus.message })) : (jsxRuntime.jsx("div", { title: policyStatus.message, children: jsxRuntime.jsx(TriangleAlert, { className: `w-4 h-4 ${policyStatus.status === "error"
12838
+ ? "text-destructive"
12463
12839
  : policyStatus.status === "pending"
12464
- ? "text-amber-600 dark:text-amber-400"
12465
- : "text-gray-400"}` }) })), jsxRuntime.jsx("span", { className: "text-xs font-medium", children: policy.spec.resource.kind })] }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center w-24", children: jsxRuntime.jsx(Badge, { variant: rules.audit > 0 ? "success" : "secondary", className: rules.audit === 0
12466
- ? "bg-gray-100 text-gray-400 dark:bg-gray-800 dark:text-gray-500"
12840
+ ? "text-[var(--badge-warning)]"
12841
+ : "text-muted-foreground"}` }) })), jsxRuntime.jsx("span", { className: "text-xs font-medium", children: policy.spec.resource.kind })] }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center w-24", children: jsxRuntime.jsx(Badge, { variant: rules.audit > 0 ? "success" : "secondary", className: rules.audit === 0
12842
+ ? "bg-muted text-muted-foreground"
12467
12843
  : "", children: rules.audit }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center w-24", children: jsxRuntime.jsx(Badge, { variant: rules.event > 0 ? "success" : "secondary", className: rules.event === 0
12468
- ? "bg-gray-100 text-gray-400 dark:bg-gray-800 dark:text-gray-500"
12844
+ ? "bg-muted text-muted-foreground"
12469
12845
  : "", children: rules.event }) })] }, policy.metadata?.name));
12470
12846
  }) })] }) }))] }, group.apiGroup))) }))] })] }));
12471
12847
  }
@@ -12913,7 +13289,7 @@ function PolicyRuleListItem({ rule, ruleType, index, onEdit, onDelete, onMoveUp,
12913
13289
  flex items-center gap-2 p-2 rounded-md border transition-all duration-200
12914
13290
  border-border bg-background hover:bg-muted/50
12915
13291
  ${className}
12916
- `, children: [jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2 mb-0.5", children: jsxRuntime.jsx("span", { className: "font-medium text-xs text-foreground truncate", children: rule.name || `${ruleType === 'audit' ? 'Audit' : 'Event'} Rule #${index + 1}` }) }), rule.description && (jsxRuntime.jsx("div", { className: "text-[11px] text-muted-foreground mb-0.5 truncate", children: rule.description })), jsxRuntime.jsx("div", { className: "text-[11px] font-mono text-muted-foreground truncate", title: rule.match, children: truncatedMatch })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-5 w-5 p-0", onClick: onMoveUp, disabled: !canMoveUp, title: "Move up", "aria-label": "Move rule up", children: jsxRuntime.jsx(ChevronUp, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-5 w-5 p-0", onClick: onMoveDown, disabled: !canMoveDown, title: "Move down", "aria-label": "Move rule down", children: jsxRuntime.jsx(ChevronDown, { className: "h-3.5 w-3.5" }) })] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-6 w-6 text-muted-foreground hover:text-foreground hover:bg-muted", onClick: onEdit, title: "Edit rule", "aria-label": "Edit rule", children: jsxRuntime.jsx(SquarePen, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-6 w-6 text-muted-foreground hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-950/50", onClick: onDelete, title: "Delete rule", "aria-label": "Delete rule", children: jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })] }));
13292
+ `, children: [jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2 mb-0.5", children: jsxRuntime.jsx("span", { className: "font-medium text-xs text-foreground truncate", children: rule.name || `${ruleType === 'audit' ? 'Audit' : 'Event'} Rule #${index + 1}` }) }), rule.description && (jsxRuntime.jsx("div", { className: "text-[11px] text-muted-foreground mb-0.5 truncate", children: rule.description })), jsxRuntime.jsx("div", { className: "text-[11px] font-mono text-muted-foreground truncate", title: rule.match, children: truncatedMatch })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-5 w-5 p-0", onClick: onMoveUp, disabled: !canMoveUp, title: "Move up", "aria-label": "Move rule up", children: jsxRuntime.jsx(ChevronUp, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-5 w-5 p-0", onClick: onMoveDown, disabled: !canMoveDown, title: "Move down", "aria-label": "Move rule down", children: jsxRuntime.jsx(ChevronDown, { className: "h-3.5 w-3.5" }) })] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-6 w-6 text-muted-foreground hover:text-foreground hover:bg-muted", onClick: onEdit, title: "Edit rule", "aria-label": "Edit rule", children: jsxRuntime.jsx(SquarePen, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "h-6 w-6 text-muted-foreground hover:text-destructive hover:bg-destructive/10", onClick: onDelete, title: "Delete rule", "aria-label": "Delete rule", children: jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })] }));
12917
13293
  }
12918
13294
 
12919
13295
  /**
@@ -13034,7 +13410,7 @@ const registeredLanguages = new Set();
13034
13410
  * Lazy-loaded Monaco editor for CEL expressions and templates
13035
13411
  * Provides autocomplete based on available field paths
13036
13412
  */
13037
- function CelEditor({ value, onChange, language = 'cel', availableFields = [], placeholder = '', height = '100px', className, error = false, readOnly = false, 'data-testid': testId, }) {
13413
+ function CelEditor({ value, onChange, language = 'cel', availableFields = [], height = '100px', className, error = false, readOnly = false, 'data-testid': testId, }) {
13038
13414
  const [Editor, setEditor] = React.useState(null);
13039
13415
  const [loadError, setLoadError] = React.useState(null);
13040
13416
  const [isLoading, setIsLoading] = React.useState(true);
@@ -13193,7 +13569,7 @@ function CelEditor({ value, onChange, language = 'cel', availableFields = [], pl
13193
13569
  */
13194
13570
  function requiresBracketNotation(key) {
13195
13571
  // Keys with dots, slashes, or other special characters need bracket notation
13196
- return /[.\/\-:]/.test(key) || /^\d/.test(key);
13572
+ return /[./\-:]/.test(key) || /^\d/.test(key);
13197
13573
  }
13198
13574
  /**
13199
13575
  * Build the CEL path for a key, using bracket notation when needed
@@ -13400,7 +13776,7 @@ function PolicyRuleEditorDialog({ open, onOpenChange, rule, ruleType, existingNa
13400
13776
  const [previewError, setPreviewError] = React.useState(null);
13401
13777
  // Sample data for autocomplete (fetched once when dialog opens)
13402
13778
  const [sampleData, setSampleData] = React.useState([]);
13403
- const [sampleDataLoading, setSampleDataLoading] = React.useState(false);
13779
+ const [, setSampleDataLoading] = React.useState(false);
13404
13780
  // Extract field paths from sample data OR preview data for autocomplete
13405
13781
  const availableFields = React.useMemo(() => {
13406
13782
  // First try to use preview data if available
@@ -13849,10 +14225,10 @@ function PolicyEditor({ client, policyName, onSaveSuccess, onCancel, onResourceC
13849
14225
  };
13850
14226
  const policyStatus = getPolicyStatus();
13851
14227
  return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-4 border-b border-border space-y-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: editor.isNew ? (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx(label.Label, { htmlFor: "policy-name", className: "text-xs text-muted-foreground", children: "Policy Name" }), jsxRuntime.jsx(input.Input, { id: "policy-name", type: "text", className: "w-[300px] text-base font-medium", value: editor.name, onChange: (e) => editor.setName(e.target.value), placeholder: "e.g., httpproxy-policy" })] })) : (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [policyStatus && (jsxRuntime.jsxs(Tooltip, { delayDuration: 300, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("span", { className: `w-2 h-2 rounded-full ${policyStatus.status === 'ready'
13852
- ? 'bg-green-500'
14228
+ ? 'bg-[var(--success-500)]'
13853
14229
  : policyStatus.status === 'error'
13854
- ? 'bg-red-500'
13855
- : 'bg-yellow-500'}`, "aria-label": `Policy status: ${policyStatus.status}` }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: policyStatus.message }) })] })), jsxRuntime.jsx("h2", { className: "m-0 text-xl font-semibold text-foreground leading-tight", children: editor.spec.resource.kind || 'Untitled Policy' })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [editor.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", editor.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", editor.name] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-green-600 dark:text-green-400" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-gray-500 dark:text-gray-400" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] })) }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [onCancel && (jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: onCancel, disabled: editor.isSaving, className: "h-7 text-xs", children: "Cancel" })), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: () => handleSave(true), disabled: !canSave || editor.isSaving, title: "Validate without saving", className: "h-7 text-xs", children: "Validate" }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", onClick: () => handleSave(false), disabled: !canSave || editor.isSaving || !editor.isDirty, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: editor.isSaving ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-[#BF9595] rounded-full animate-spin" }), "Saving..."] })) : ('Save Policy') })] })] }), jsxRuntime.jsx(ApiErrorAlert, { error: editor.error, className: "mx-4 mt-3", errorFormatter: errorFormatter }), editor.isLoading && (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [jsxRuntime.jsx("span", { className: "w-5 h-5 border-[3px] border-border border-t-[#BF9595] rounded-full animate-spin" }), "Loading policy..."] })), !editor.isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-4", children: jsxRuntime.jsxs(tabs.Tabs, { defaultValue: "activity", value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [jsxRuntime.jsxs(tabs.TabsList, { className: "grid w-full grid-cols-2 mb-4", children: [jsxRuntime.jsx(tabs.TabsTrigger, { value: "activity", children: "Activity" }), jsxRuntime.jsx(tabs.TabsTrigger, { value: "editor", children: "Editor" })] }), jsxRuntime.jsx(tabs.TabsContent, { value: "activity", className: "mt-0", children: jsxRuntime.jsx(PolicyActivityView, { client: client, policyResource: editor.spec.resource, policyName: editor.name, onResourceClick: onResourceClick, errorFormatter: errorFormatter }) }), jsxRuntime.jsx(tabs.TabsContent, { value: "editor", className: "mt-0", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntime.jsx(PolicyResourceForm, { resource: editor.spec.resource, onChange: editor.setResource, client: client, isEditMode: !editor.isNew }), jsxRuntime.jsx(PolicyRuleList, { auditRules: editor.spec.auditRules || [], eventRules: editor.spec.eventRules || [], policyResource: editor.spec.resource, apiClient: client, onAuditRulesChange: editor.setAuditRules, onEventRulesChange: editor.setEventRules }), !editor.isNew && (jsxRuntime.jsx("div", { className: "mt-6 pt-4 border-t border-border", children: jsxRuntime.jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: jsxRuntime.jsx("div", { className: "flex items-start gap-3", children: jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsxs("h3", { className: "text-base font-semibold text-foreground mb-1.5 flex items-center gap-2", children: [jsxRuntime.jsx(TriangleAlert, { className: "h-5 w-5 text-destructive" }), "Danger Zone"] }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: ["Deleting this policy will stop translating audit logs and events for", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.spec.resource.kind }), ' ', "resources. Existing activities will be preserved, but no new activities will be generated."] }), jsxRuntime.jsxs(button.Button, { type: "danger", theme: "solid", size: "small", onClick: () => setShowDeleteDialog(true), className: "h-8 text-xs", children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })] }) }) }) }))] }) })] }) })), jsxRuntime.jsx(Dialog, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: jsxRuntime.jsxs(DialogContent, { className: "max-w-[500px]", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Delete Policy" }), jsxRuntime.jsxs(DialogDescription, { children: ["Are you sure you want to delete", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.name }), "?"] })] }), jsxRuntime.jsxs(alert.Alert, { variant: "destructive", className: "mt-2", children: [jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" }), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: "This action cannot be undone." }), jsxRuntime.jsx("br", {}), "Activities already generated by this policy will remain in the system, but no new activities will be created for ", editor.spec.resource.kind, " resources."] })] }), jsxRuntime.jsxs(DialogFooter, { children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: () => setShowDeleteDialog(false), disabled: isDeleting, className: "h-8 text-xs", children: "Cancel" }), jsxRuntime.jsx(button.Button, { type: "danger", theme: "solid", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 text-xs", children: isDeleting ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin mr-2" }), "Deleting..."] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })) })] })] }) })] }) }));
14230
+ ? 'bg-destructive'
14231
+ : 'bg-[var(--badge-warning)]'}`, "aria-label": `Policy status: ${policyStatus.status}` }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: policyStatus.message }) })] })), jsxRuntime.jsx("h2", { className: "m-0 text-xl font-semibold text-foreground leading-tight", children: editor.spec.resource.kind || 'Untitled Policy' })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [editor.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", editor.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", editor.name] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-muted transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-[var(--success-500)]" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-muted-foreground" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] })) }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [onCancel && (jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: onCancel, disabled: editor.isSaving, className: "h-7 text-xs", children: "Cancel" })), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: () => handleSave(true), disabled: !canSave || editor.isSaving, title: "Validate without saving", className: "h-7 text-xs", children: "Validate" }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", onClick: () => handleSave(false), disabled: !canSave || editor.isSaving || !editor.isDirty, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: editor.isSaving ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-[#BF9595] rounded-full animate-spin" }), "Saving..."] })) : ('Save Policy') })] })] }), jsxRuntime.jsx(ApiErrorAlert, { error: editor.error, className: "mx-4 mt-3", errorFormatter: errorFormatter }), editor.isLoading && (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [jsxRuntime.jsx("span", { className: "w-5 h-5 border-[3px] border-border border-t-[#BF9595] rounded-full animate-spin" }), "Loading policy..."] })), !editor.isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-4", children: jsxRuntime.jsxs(tabs.Tabs, { defaultValue: "activity", value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [jsxRuntime.jsxs(tabs.TabsList, { className: "grid w-full grid-cols-2 mb-4", children: [jsxRuntime.jsx(tabs.TabsTrigger, { value: "activity", children: "Activity" }), jsxRuntime.jsx(tabs.TabsTrigger, { value: "editor", children: "Editor" })] }), jsxRuntime.jsx(tabs.TabsContent, { value: "activity", className: "mt-0", children: jsxRuntime.jsx(PolicyActivityView, { client: client, policyResource: editor.spec.resource, policyName: editor.name, onResourceClick: onResourceClick, errorFormatter: errorFormatter }) }), jsxRuntime.jsx(tabs.TabsContent, { value: "editor", className: "mt-0", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntime.jsx(PolicyResourceForm, { resource: editor.spec.resource, onChange: editor.setResource, client: client, isEditMode: !editor.isNew }), jsxRuntime.jsx(PolicyRuleList, { auditRules: editor.spec.auditRules || [], eventRules: editor.spec.eventRules || [], policyResource: editor.spec.resource, apiClient: client, onAuditRulesChange: editor.setAuditRules, onEventRulesChange: editor.setEventRules }), !editor.isNew && (jsxRuntime.jsx("div", { className: "mt-6 pt-4 border-t border-border", children: jsxRuntime.jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: jsxRuntime.jsx("div", { className: "flex items-start gap-3", children: jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsxs("h3", { className: "text-base font-semibold text-foreground mb-1.5 flex items-center gap-2", children: [jsxRuntime.jsx(TriangleAlert, { className: "h-5 w-5 text-destructive" }), "Danger Zone"] }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: ["Deleting this policy will stop translating audit logs and events for", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.spec.resource.kind }), ' ', "resources. Existing activities will be preserved, but no new activities will be generated."] }), jsxRuntime.jsxs(button.Button, { type: "danger", theme: "solid", size: "small", onClick: () => setShowDeleteDialog(true), className: "h-8 text-xs", children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })] }) }) }) }))] }) })] }) })), jsxRuntime.jsx(Dialog, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: jsxRuntime.jsxs(DialogContent, { className: "max-w-[500px]", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Delete Policy" }), jsxRuntime.jsxs(DialogDescription, { children: ["Are you sure you want to delete", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.name }), "?"] })] }), jsxRuntime.jsxs(alert.Alert, { variant: "destructive", className: "mt-2", children: [jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" }), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: "This action cannot be undone." }), jsxRuntime.jsx("br", {}), "Activities already generated by this policy will remain in the system, but no new activities will be created for ", editor.spec.resource.kind, " resources."] })] }), jsxRuntime.jsxs(DialogFooter, { children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: () => setShowDeleteDialog(false), disabled: isDeleting, className: "h-8 text-xs", children: "Cancel" }), jsxRuntime.jsx(button.Button, { type: "danger", theme: "solid", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 text-xs", children: isDeleting ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-current border-t-transparent rounded-full animate-spin mr-2" }), "Deleting..."] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })) })] })] }) })] }) }));
13856
14232
  }
13857
14233
 
13858
14234
  /**
@@ -13936,12 +14312,12 @@ function PolicyDetailView({ client, policyName, onEdit, onResourceClick, classNa
13936
14312
  const policyStatus = getPolicyStatus();
13937
14313
  const isUnhealthy = policyStatus && policyStatus.status !== 'ready';
13938
14314
  return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-6 border-b border-border space-y-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [isLoading && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "w-2 h-2 rounded-full" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-6 w-32" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-24" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-32" })] })] })), !isLoading && policy && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [jsxRuntime.jsxs("h2", { className: "m-0 text-xl font-semibold text-foreground leading-tight flex items-center gap-2", children: [jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("span", { className: `w-2 h-2 rounded-full ${policyStatus?.status === 'ready'
13939
- ? 'bg-green-500'
14315
+ ? 'bg-[var(--success-500)]'
13940
14316
  : policyStatus?.status === 'error'
13941
- ? 'bg-red-500'
14317
+ ? 'bg-destructive'
13942
14318
  : policyStatus?.status === 'pending'
13943
- ? 'bg-yellow-500'
13944
- : 'bg-green-500'}` }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: policyStatus?.message || 'Policy is active' }) })] }), policy.spec.resource.kind || 'Untitled Policy'] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [policy.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", policy.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", policyName] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-green-600 dark:text-green-400" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-gray-500 dark:text-gray-400" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] }))] }), jsxRuntime.jsx("div", { className: "flex gap-3", children: onEdit && (jsxRuntime.jsxs(button.Button, { htmlType: "button", size: "small", onClick: onEdit, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: [jsxRuntime.jsx(SquarePen, { className: "h-3.5 w-3.5 mr-1.5" }), "Edit Policy"] })) })] }), jsxRuntime.jsx(ApiErrorAlert, { error: error, className: "mx-6 mt-4", errorFormatter: errorFormatter }), isUnhealthy && policyStatus && (jsxRuntime.jsxs(alert.Alert, { variant: policyStatus.status === 'error' ? 'destructive' : 'warning', className: "mx-6 mt-4", children: [policyStatus.status === 'error' ? (jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" })) : (jsxRuntime.jsx(TriangleAlert, { className: "h-4 w-4" })), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: policyStatus.status === 'error' ? 'Policy Error: ' : 'Policy Pending: ' }), policyStatus.message] })] })), isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-6", children: jsxRuntime.jsx(PolicyActivityViewSkeleton, {}) })), !isLoading && policy && (jsxRuntime.jsx(card.CardContent, { className: "p-6", children: jsxRuntime.jsx(PolicyActivityView, { client: client, policyResource: policy.spec.resource, policyName: policyName, onResourceClick: onResourceClick, errorFormatter: errorFormatter }) }))] }) }));
14319
+ ? 'bg-[var(--badge-warning)]'
14320
+ : 'bg-[var(--success-500)]'}` }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: policyStatus?.message || 'Policy is active' }) })] }), policy.spec.resource.kind || 'Untitled Policy'] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [policy.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", policy.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", policyName] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-muted transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-[var(--success-500)]" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-muted-foreground" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] }))] }), jsxRuntime.jsx("div", { className: "flex gap-3", children: onEdit && (jsxRuntime.jsxs(button.Button, { htmlType: "button", size: "small", onClick: onEdit, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: [jsxRuntime.jsx(SquarePen, { className: "h-3.5 w-3.5 mr-1.5" }), "Edit Policy"] })) })] }), jsxRuntime.jsx(ApiErrorAlert, { error: error, className: "mx-6 mt-4", errorFormatter: errorFormatter }), isUnhealthy && policyStatus && (jsxRuntime.jsxs(alert.Alert, { variant: policyStatus.status === 'error' ? 'destructive' : 'warning', className: "mx-6 mt-4", children: [policyStatus.status === 'error' ? (jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" })) : (jsxRuntime.jsx(TriangleAlert, { className: "h-4 w-4" })), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: policyStatus.status === 'error' ? 'Policy Error: ' : 'Policy Pending: ' }), policyStatus.message] })] })), isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-6", children: jsxRuntime.jsx(PolicyActivityViewSkeleton, {}) })), !isLoading && policy && (jsxRuntime.jsx(card.CardContent, { className: "p-6", children: jsxRuntime.jsx(PolicyActivityView, { client: client, policyResource: policy.spec.resource, policyName: policyName, onResourceClick: onResourceClick, errorFormatter: errorFormatter }) }))] }) }));
13945
14321
  }
13946
14322
 
13947
14323
  /**
@@ -14041,7 +14417,7 @@ function PolicyEditView({ client, policyName, onSaveSuccess, onCancel, className
14041
14417
  };
14042
14418
  const policyStatus = getPolicyStatus();
14043
14419
  const isUnhealthy = policyStatus && policyStatus.status !== 'ready';
14044
- return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-4 border-b border-border space-y-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: editor.isNew ? (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx(label.Label, { htmlFor: "policy-name", className: "text-xs text-muted-foreground", children: "Policy Name" }), jsxRuntime.jsx(input.Input, { id: "policy-name", type: "text", className: "w-[300px] text-base font-medium", value: editor.name, onChange: (e) => editor.setName(e.target.value), placeholder: "e.g., httpproxy-policy" })] })) : (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx("h2", { className: "m-0 text-xl font-semibold text-foreground leading-tight", children: editor.spec.resource.kind || 'Untitled Policy' }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [editor.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", editor.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", editor.name] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-green-600 dark:text-green-400" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-gray-500 dark:text-gray-400" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] })) }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [onCancel && (jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: onCancel, disabled: editor.isSaving, className: "h-7 text-xs", children: "Cancel" })), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: () => handleSave(true), disabled: !canSave || editor.isSaving, title: "Validate without saving", className: "h-7 text-xs", children: "Validate" }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", onClick: () => handleSave(false), disabled: !canSave || editor.isSaving || !editor.isDirty, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: editor.isSaving ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-[#BF9595] rounded-full animate-spin" }), "Saving..."] })) : ('Save Policy') })] })] }), jsxRuntime.jsx(ApiErrorAlert, { error: editor.error, className: "mx-4 mt-3", errorFormatter: errorFormatter }), isUnhealthy && policyStatus && (jsxRuntime.jsxs(alert.Alert, { variant: policyStatus.status === 'error' ? 'destructive' : 'warning', className: "mx-4 mt-3", children: [policyStatus.status === 'error' ? (jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" })) : (jsxRuntime.jsx(TriangleAlert, { className: "h-4 w-4" })), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: policyStatus.status === 'error' ? 'Policy Error: ' : 'Policy Pending: ' }), policyStatus.message] })] })), editor.isLoading && (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [jsxRuntime.jsx("span", { className: "w-5 h-5 border-[3px] border-border border-t-[#BF9595] rounded-full animate-spin" }), "Loading policy..."] })), !editor.isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-4", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntime.jsx(PolicyResourceForm, { resource: editor.spec.resource, onChange: editor.setResource, client: client, isEditMode: !editor.isNew }), jsxRuntime.jsx(PolicyRuleList, { auditRules: editor.spec.auditRules || [], eventRules: editor.spec.eventRules || [], policyResource: editor.spec.resource, apiClient: client, onAuditRulesChange: editor.setAuditRules, onEventRulesChange: editor.setEventRules }), !editor.isNew && (jsxRuntime.jsx("div", { className: "mt-6 pt-4 border-t border-border", children: jsxRuntime.jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: jsxRuntime.jsx("div", { className: "flex items-start gap-3", children: jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsxs("h3", { className: "text-base font-semibold text-foreground mb-1.5 flex items-center gap-2", children: [jsxRuntime.jsx(TriangleAlert, { className: "h-5 w-5 text-destructive" }), "Danger Zone"] }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: ["Deleting this policy will stop translating audit logs and events for", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.spec.resource.kind }), ' ', "resources. Existing activities will be preserved, but no new activities will be generated."] }), jsxRuntime.jsxs(button.Button, { type: "danger", theme: "solid", size: "small", onClick: () => setShowDeleteDialog(true), className: "h-8 text-xs", children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })] }) }) }) }))] }) })), jsxRuntime.jsx(Dialog, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: jsxRuntime.jsxs(DialogContent, { className: "max-w-[500px]", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Delete Policy" }), jsxRuntime.jsxs(DialogDescription, { children: ["Are you sure you want to delete", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.name }), "?"] })] }), jsxRuntime.jsxs(alert.Alert, { variant: "destructive", className: "mt-2", children: [jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" }), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: "This action cannot be undone." }), jsxRuntime.jsx("br", {}), "Activities already generated by this policy will remain in the system, but no new activities will be created for ", editor.spec.resource.kind, " resources."] })] }), jsxRuntime.jsxs(DialogFooter, { children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: () => setShowDeleteDialog(false), disabled: isDeleting, className: "h-8 text-xs", children: "Cancel" }), jsxRuntime.jsx(button.Button, { type: "danger", theme: "solid", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 text-xs", children: isDeleting ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin mr-2" }), "Deleting..."] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })) })] })] }) })] }) }));
14420
+ return (jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-4 border-b border-border space-y-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: editor.isNew ? (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx(label.Label, { htmlFor: "policy-name", className: "text-xs text-muted-foreground", children: "Policy Name" }), jsxRuntime.jsx(input.Input, { id: "policy-name", type: "text", className: "w-[300px] text-base font-medium", value: editor.name, onChange: (e) => editor.setName(e.target.value), placeholder: "e.g., httpproxy-policy" })] })) : (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [jsxRuntime.jsx("h2", { className: "m-0 text-xl font-semibold text-foreground leading-tight", children: editor.spec.resource.kind || 'Untitled Policy' }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [editor.spec.resource.apiGroup && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("span", { children: ["API Group: ", editor.spec.resource.apiGroup] }), jsxRuntime.jsx("span", { className: "text-muted-foreground/50", children: "\u2022" })] })), jsxRuntime.jsxs("span", { children: ["Resource: ", editor.name] }), jsxRuntime.jsxs(Tooltip, { delayDuration: 500, children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("button", { onClick: handleCopyResourceName, className: "inline-flex items-center justify-center p-0.5 rounded hover:bg-muted transition-opacity cursor-pointer", "aria-label": "Copy resource name", children: isCopied ? (jsxRuntime.jsx(Check, { className: "h-3 w-3 text-[var(--success-500)]" })) : (jsxRuntime.jsx(Copy, { className: "h-3 w-3 text-muted-foreground" })) }) }), jsxRuntime.jsx(TooltipContent, { children: jsxRuntime.jsx("p", { className: "text-xs", children: "Click to copy" }) })] })] })] })) }), jsxRuntime.jsxs("div", { className: "flex gap-2", children: [onCancel && (jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: onCancel, disabled: editor.isSaving, className: "h-7 text-xs", children: "Cancel" })), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", onClick: () => handleSave(true), disabled: !canSave || editor.isSaving, title: "Validate without saving", className: "h-7 text-xs", children: "Validate" }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", onClick: () => handleSave(false), disabled: !canSave || editor.isSaving || !editor.isDirty, className: "bg-primary text-primary-foreground border-primary hover:bg-primary/90 hover:border-primary/90 h-7 text-xs", children: editor.isSaving ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-[#BF9595] rounded-full animate-spin" }), "Saving..."] })) : ('Save Policy') })] })] }), jsxRuntime.jsx(ApiErrorAlert, { error: editor.error, className: "mx-4 mt-3", errorFormatter: errorFormatter }), isUnhealthy && policyStatus && (jsxRuntime.jsxs(alert.Alert, { variant: policyStatus.status === 'error' ? 'destructive' : 'warning', className: "mx-4 mt-3", children: [policyStatus.status === 'error' ? (jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" })) : (jsxRuntime.jsx(TriangleAlert, { className: "h-4 w-4" })), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: policyStatus.status === 'error' ? 'Policy Error: ' : 'Policy Pending: ' }), policyStatus.message] })] })), editor.isLoading && (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [jsxRuntime.jsx("span", { className: "w-5 h-5 border-[3px] border-border border-t-[#BF9595] rounded-full animate-spin" }), "Loading policy..."] })), !editor.isLoading && (jsxRuntime.jsx(card.CardContent, { className: "p-4", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntime.jsx(PolicyResourceForm, { resource: editor.spec.resource, onChange: editor.setResource, client: client, isEditMode: !editor.isNew }), jsxRuntime.jsx(PolicyRuleList, { auditRules: editor.spec.auditRules || [], eventRules: editor.spec.eventRules || [], policyResource: editor.spec.resource, apiClient: client, onAuditRulesChange: editor.setAuditRules, onEventRulesChange: editor.setEventRules }), !editor.isNew && (jsxRuntime.jsx("div", { className: "mt-6 pt-4 border-t border-border", children: jsxRuntime.jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: jsxRuntime.jsx("div", { className: "flex items-start gap-3", children: jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsxs("h3", { className: "text-base font-semibold text-foreground mb-1.5 flex items-center gap-2", children: [jsxRuntime.jsx(TriangleAlert, { className: "h-5 w-5 text-destructive" }), "Danger Zone"] }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: ["Deleting this policy will stop translating audit logs and events for", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.spec.resource.kind }), ' ', "resources. Existing activities will be preserved, but no new activities will be generated."] }), jsxRuntime.jsxs(button.Button, { type: "danger", theme: "solid", size: "small", onClick: () => setShowDeleteDialog(true), className: "h-8 text-xs", children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })] }) }) }) }))] }) })), jsxRuntime.jsx(Dialog, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: jsxRuntime.jsxs(DialogContent, { className: "max-w-[500px]", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Delete Policy" }), jsxRuntime.jsxs(DialogDescription, { children: ["Are you sure you want to delete", ' ', jsxRuntime.jsx("strong", { className: "text-foreground", children: editor.name }), "?"] })] }), jsxRuntime.jsxs(alert.Alert, { variant: "destructive", className: "mt-2", children: [jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" }), jsxRuntime.jsxs(alert.AlertDescription, { children: [jsxRuntime.jsx("strong", { children: "This action cannot be undone." }), jsxRuntime.jsx("br", {}), "Activities already generated by this policy will remain in the system, but no new activities will be created for ", editor.spec.resource.kind, " resources."] })] }), jsxRuntime.jsxs(DialogFooter, { children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: () => setShowDeleteDialog(false), disabled: isDeleting, className: "h-8 text-xs", children: "Cancel" }), jsxRuntime.jsx(button.Button, { type: "danger", theme: "solid", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 text-xs", children: isDeleting ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-current border-t-transparent rounded-full animate-spin mr-2" }), "Deleting..."] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Trash2, { className: "h-3.5 w-3.5 mr-1.5" }), "Delete Policy"] })) })] })] }) })] }) }));
14045
14421
  }
14046
14422
 
14047
14423
  /**
@@ -14122,8 +14498,8 @@ function PolicyRuleEditor({ rule, index, ruleType, isHighlighted = false, onChan
14122
14498
  onChange({ ...rule, summary: example });
14123
14499
  };
14124
14500
  return (jsxRuntime.jsxs(card.Card, { className: `mb-3 transition-all duration-200 ${isHighlighted
14125
- ? 'border-emerald-600 bg-emerald-50'
14126
- : 'bg-muted'} ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-3 pb-0", children: [jsxRuntime.jsxs("span", { className: `text-xs font-semibold uppercase tracking-wide ${isHighlighted ? 'text-emerald-600' : 'text-muted-foreground'}`, children: [ruleType === 'audit' ? 'Audit' : 'Event', " Rule #", index + 1] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "w-6 h-6 text-xl leading-none text-muted-foreground hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-950/50 dark:hover:text-red-400", onClick: onDelete, title: "Delete rule", children: "\u00D7" })] }), jsxRuntime.jsxs(card.CardContent, { className: "p-3", children: [jsxRuntime.jsxs("div", { className: "mb-3", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsxRuntime.jsx(label.Label, { htmlFor: `rule-${index}-match`, children: "Match Expression (CEL)" }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", className: "px-2 py-0.5 h-auto text-xs", onClick: () => setShowMatchHelp(!showMatchHelp), children: showMatchHelp ? 'Hide Help' : 'Show Help' })] }), jsxRuntime.jsx(textarea.Textarea, { id: `rule-${index}-match`, className: "font-mono text-sm resize-y min-h-[60px]", value: rule.match, onChange: handleMatchChange, placeholder: `e.g., ${celHelp.examples[0]}`, rows: 2, spellCheck: false }), showMatchHelp && (jsxRuntime.jsxs("div", { className: "mt-2 p-3 bg-background border border-border rounded-md text-xs", children: [jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Available Variables:" }), jsxRuntime.jsx("ul", { className: "m-0 pl-5 list-disc", children: celHelp.variables.map((v) => (jsxRuntime.jsxs("li", { className: "mb-0.5", children: [jsxRuntime.jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: v.name }), " - ", v.description] }, v.name))) })] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Examples:" }), jsxRuntime.jsx("ul", { className: "m-0 p-0 list-none", children: celHelp.examples.map((ex, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-1 px-2 py-1 bg-muted rounded", children: [jsxRuntime.jsx("code", { className: "flex-1 text-xs break-all", children: ex }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", className: "px-2 py-0.5 h-auto bg-primary text-primary-foreground border-none text-xs font-medium uppercase hover:bg-primary/90", onClick: () => insertMatchExample(ex), children: "Use" })] }, i))) })] })] }))] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsxRuntime.jsx(label.Label, { htmlFor: `rule-${index}-summary`, children: "Summary Template (CEL)" }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", className: "px-2 py-0.5 h-auto text-xs", onClick: () => setShowSummaryHelp(!showSummaryHelp), children: showSummaryHelp ? 'Hide Help' : 'Show Help' })] }), jsxRuntime.jsx(textarea.Textarea, { id: `rule-${index}-summary`, className: "font-mono text-sm resize-y min-h-[60px]", value: rule.summary, onChange: handleSummaryChange, placeholder: `e.g., ${SUMMARY_HELP.examples[0]}`, rows: 2, spellCheck: false }), showSummaryHelp && (jsxRuntime.jsxs("div", { className: "mt-2 p-3 bg-background border border-border rounded-md text-xs", children: [jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Available Variables:" }), jsxRuntime.jsx("ul", { className: "m-0 pl-5 list-disc", children: SUMMARY_HELP.variables.map((v) => (jsxRuntime.jsxs("li", { className: "mb-0.5", children: [jsxRuntime.jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: '{{ ' + v.name + ' }}' }), " - ", v.description] }, v.name))) })] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Examples:" }), jsxRuntime.jsx("ul", { className: "m-0 p-0 list-none", children: SUMMARY_HELP.examples.map((ex, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-1 px-2 py-1 bg-muted rounded", children: [jsxRuntime.jsx("code", { className: "flex-1 text-xs break-all", children: ex }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", className: "px-2 py-0.5 h-auto bg-primary text-primary-foreground border-none text-xs font-medium uppercase hover:bg-primary/90", onClick: () => insertSummaryExample(ex), children: "Use" })] }, i))) })] })] }))] })] })] }));
14501
+ ? 'border-[var(--success-500)] bg-[var(--success-100)]'
14502
+ : 'bg-muted'} ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-center p-3 pb-0", children: [jsxRuntime.jsxs("span", { className: `text-xs font-semibold uppercase tracking-wide ${isHighlighted ? 'text-[var(--success-500)]' : 'text-muted-foreground'}`, children: [ruleType === 'audit' ? 'Audit' : 'Event', " Rule #", index + 1] }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "quaternary", theme: "borderless", size: "icon", className: "w-6 h-6 text-xl leading-none text-muted-foreground hover:bg-destructive/10 hover:text-destructive", onClick: onDelete, title: "Delete rule", children: "\u00D7" })] }), jsxRuntime.jsxs(card.CardContent, { className: "p-3", children: [jsxRuntime.jsxs("div", { className: "mb-3", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsxRuntime.jsx(label.Label, { htmlFor: `rule-${index}-match`, children: "Match Expression (CEL)" }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", className: "px-2 py-0.5 h-auto text-xs", onClick: () => setShowMatchHelp(!showMatchHelp), children: showMatchHelp ? 'Hide Help' : 'Show Help' })] }), jsxRuntime.jsx(textarea.Textarea, { id: `rule-${index}-match`, className: "font-mono text-sm resize-y min-h-[60px]", value: rule.match, onChange: handleMatchChange, placeholder: `e.g., ${celHelp.examples[0]}`, rows: 2, spellCheck: false }), showMatchHelp && (jsxRuntime.jsxs("div", { className: "mt-2 p-3 bg-background border border-border rounded-md text-xs", children: [jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Available Variables:" }), jsxRuntime.jsx("ul", { className: "m-0 pl-5 list-disc", children: celHelp.variables.map((v) => (jsxRuntime.jsxs("li", { className: "mb-0.5", children: [jsxRuntime.jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: v.name }), " - ", v.description] }, v.name))) })] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Examples:" }), jsxRuntime.jsx("ul", { className: "m-0 p-0 list-none", children: celHelp.examples.map((ex, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-1 px-2 py-1 bg-muted rounded", children: [jsxRuntime.jsx("code", { className: "flex-1 text-xs break-all", children: ex }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", className: "px-2 py-0.5 h-auto bg-primary text-primary-foreground border-none text-xs font-medium uppercase hover:bg-primary/90", onClick: () => insertMatchExample(ex), children: "Use" })] }, i))) })] })] }))] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsxRuntime.jsx(label.Label, { htmlFor: `rule-${index}-summary`, children: "Summary Template (CEL)" }), jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", size: "small", className: "px-2 py-0.5 h-auto text-xs", onClick: () => setShowSummaryHelp(!showSummaryHelp), children: showSummaryHelp ? 'Hide Help' : 'Show Help' })] }), jsxRuntime.jsx(textarea.Textarea, { id: `rule-${index}-summary`, className: "font-mono text-sm resize-y min-h-[60px]", value: rule.summary, onChange: handleSummaryChange, placeholder: `e.g., ${SUMMARY_HELP.examples[0]}`, rows: 2, spellCheck: false }), showSummaryHelp && (jsxRuntime.jsxs("div", { className: "mt-2 p-3 bg-background border border-border rounded-md text-xs", children: [jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Available Variables:" }), jsxRuntime.jsx("ul", { className: "m-0 pl-5 list-disc", children: SUMMARY_HELP.variables.map((v) => (jsxRuntime.jsxs("li", { className: "mb-0.5", children: [jsxRuntime.jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: '{{ ' + v.name + ' }}' }), " - ", v.description] }, v.name))) })] }), jsxRuntime.jsxs("div", { className: "mb-3 last:mb-0", children: [jsxRuntime.jsx("strong", { className: "block mb-1.5 text-foreground", children: "Examples:" }), jsxRuntime.jsx("ul", { className: "m-0 p-0 list-none", children: SUMMARY_HELP.examples.map((ex, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-1 px-2 py-1 bg-muted rounded", children: [jsxRuntime.jsx("code", { className: "flex-1 text-xs break-all", children: ex }), jsxRuntime.jsx(button.Button, { htmlType: "button", size: "small", className: "px-2 py-0.5 h-auto bg-primary text-primary-foreground border-none text-xs font-medium uppercase hover:bg-primary/90", onClick: () => insertSummaryExample(ex), children: "Use" })] }, i))) })] })] }))] })] })] }));
14127
14503
  }
14128
14504
 
14129
14505
  /**
@@ -14781,7 +15157,7 @@ function ReindexJobList({ client, onViewJob, onCreateJob, watch = true, classNam
14781
15157
  const bTime = b.metadata?.creationTimestamp || '';
14782
15158
  return bTime.localeCompare(aTime);
14783
15159
  });
14784
- return (jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "pb-1.5", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground m-0", children: "Re-process historical events through updated policies" }), isWatching && (jsxRuntime.jsxs(Badge, { variant: "success", className: "text-xs", children: [jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 bg-green-500 rounded-full mr-1.5 animate-pulse" }), "Live"] }))] }), jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: refresh, disabled: isLoading, title: "Refresh job list", className: "h-7 px-2", children: isLoading ? (jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-primary rounded-full animate-spin" })) : ('↻') }), onCreateJob && (jsxRuntime.jsx(button.Button, { size: "small", onClick: onCreateJob, className: "bg-primary text-primary-foreground hover:bg-primary/90 h-7 text-xs", children: "+ Create Job" }))] })] }), jsxRuntime.jsx(separator.Separator, { className: "mt-1.5" })] }), jsxRuntime.jsxs(card.CardContent, { className: "pt-3", children: [jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-3", errorFormatter: errorFormatter }), isLoading && jobs.length === 0 && (jsxRuntime.jsx("div", { className: "border border-input rounded-lg overflow-hidden", children: jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Job Name" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Status" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Message" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Duration" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Actions" })] }) }), jsxRuntime.jsxs("tbody", { children: [jsxRuntime.jsx(ReindexJobSkeletonRow, {}), jsxRuntime.jsx(ReindexJobSkeletonRow, {}), jsxRuntime.jsx(ReindexJobSkeletonRow, {})] })] }) })), !isLoading && !error && jobs.length === 0 && (jsxRuntime.jsxs("div", { className: "text-center py-8 px-6 text-muted-foreground", children: [jsxRuntime.jsx("div", { className: "text-4xl mb-3", children: "\uD83D\uDD04" }), jsxRuntime.jsx("h3", { className: "m-0 mb-1.5 text-foreground", children: "No reindex jobs found" }), jsxRuntime.jsx("p", { className: "m-0 mb-4 max-w-[400px] mx-auto", children: "Create a reindex job to re-process historical audit logs and events through current ActivityPolicy rules." }), onCreateJob && (jsxRuntime.jsx(button.Button, { size: "small", onClick: onCreateJob, className: "bg-primary text-primary-foreground hover:bg-primary/90 h-7 text-xs", children: "Create your first reindex job" }))] })), sortedJobs.length > 0 && (jsxRuntime.jsx("div", { className: "border border-input rounded-lg overflow-hidden", children: jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Job Name" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Status" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Message" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Duration" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Actions" })] }) }), jsxRuntime.jsx("tbody", { children: sortedJobs.map((job) => {
15160
+ return (jsxRuntime.jsxs(card.Card, { className: `rounded-xl ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "pb-1.5", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground m-0", children: "Re-process historical events through updated policies" }), isWatching && (jsxRuntime.jsxs(Badge, { variant: "success", className: "text-xs", children: [jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 bg-[var(--success-500)] rounded-full mr-1.5 animate-pulse" }), "Live"] }))] }), jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [jsxRuntime.jsx(button.Button, { type: "tertiary", theme: "outline", size: "small", onClick: refresh, disabled: isLoading, title: "Refresh job list", className: "h-7 px-2", children: isLoading ? (jsxRuntime.jsx("span", { className: "w-3.5 h-3.5 border-2 border-border border-t-primary rounded-full animate-spin" })) : ('↻') }), onCreateJob && (jsxRuntime.jsx(button.Button, { size: "small", onClick: onCreateJob, className: "bg-primary text-primary-foreground hover:bg-primary/90 h-7 text-xs", children: "+ Create Job" }))] })] }), jsxRuntime.jsx(separator.Separator, { className: "mt-1.5" })] }), jsxRuntime.jsxs(card.CardContent, { className: "pt-3", children: [jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: refresh, className: "mb-3", errorFormatter: errorFormatter }), isLoading && jobs.length === 0 && (jsxRuntime.jsx("div", { className: "border border-input rounded-lg overflow-hidden", children: jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Job Name" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Status" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Message" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Duration" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Actions" })] }) }), jsxRuntime.jsxs("tbody", { children: [jsxRuntime.jsx(ReindexJobSkeletonRow, {}), jsxRuntime.jsx(ReindexJobSkeletonRow, {}), jsxRuntime.jsx(ReindexJobSkeletonRow, {})] })] }) })), !isLoading && !error && jobs.length === 0 && (jsxRuntime.jsxs("div", { className: "text-center py-8 px-6 text-muted-foreground", children: [jsxRuntime.jsx("div", { className: "text-4xl mb-3", children: "\uD83D\uDD04" }), jsxRuntime.jsx("h3", { className: "m-0 mb-1.5 text-foreground", children: "No reindex jobs found" }), jsxRuntime.jsx("p", { className: "m-0 mb-4 max-w-[400px] mx-auto", children: "Create a reindex job to re-process historical audit logs and events through current ActivityPolicy rules." }), onCreateJob && (jsxRuntime.jsx(button.Button, { size: "small", onClick: onCreateJob, className: "bg-primary text-primary-foreground hover:bg-primary/90 h-7 text-xs", children: "Create your first reindex job" }))] })), sortedJobs.length > 0 && (jsxRuntime.jsx("div", { className: "border border-input rounded-lg overflow-hidden", children: jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Job Name" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Status" }), jsxRuntime.jsx("th", { className: "text-left px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap", children: "Message" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Duration" }), jsxRuntime.jsx("th", { className: "text-center px-3 py-2 bg-muted text-muted-foreground font-medium border-b border-input text-xs whitespace-nowrap w-24", children: "Actions" })] }) }), jsxRuntime.jsx("tbody", { children: sortedJobs.map((job) => {
14785
15161
  const duration = getReindexJobDuration(job);
14786
15162
  return (jsxRuntime.jsxs("tr", { className: "hover:bg-muted transition-colors", children: [jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0", children: jsxRuntime.jsx("span", { className: "text-xs font-medium font-mono", children: job.metadata?.name }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center", children: jsxRuntime.jsxs(Badge, { variant: getPhaseBadgeVariant(job.status?.phase), className: "inline-flex items-center gap-1", children: [getPhaseIcon$1(job.status?.phase), job.status?.phase || 'Unknown'] }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0", children: job.status?.phase === 'Failed' ? (jsxRuntime.jsx("span", { className: "text-xs text-destructive", children: job.status?.message || 'Job failed' })) : (jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: job.status?.message || 'Waiting to start' })) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center", children: jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: duration || '-' }) }), jsxRuntime.jsx("td", { className: "px-3 py-2 border-b border-border last:border-b-0 text-center", children: onViewJob && (jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", onClick: () => onViewJob(job.metadata?.name || ''), className: "h-7 px-2", title: "View job details", children: jsxRuntime.jsx(Eye, { className: "h-3.5 w-3.5" }) })) })] }, job.metadata?.name));
14787
15163
  }) })] }) }))] })] }));
@@ -14793,11 +15169,11 @@ function ReindexJobList({ client, onViewJob, onCreateJob, watch = true, classNam
14793
15169
  function getPhaseIcon(phase) {
14794
15170
  switch (phase) {
14795
15171
  case 'Succeeded':
14796
- return jsxRuntime.jsx(CircleCheck, { className: "h-8 w-8 text-green-500" });
15172
+ return jsxRuntime.jsx(CircleCheck, { className: "h-8 w-8 text-[var(--success-500)]" });
14797
15173
  case 'Failed':
14798
- return jsxRuntime.jsx(CircleX, { className: "h-8 w-8 text-red-500" });
15174
+ return jsxRuntime.jsx(CircleX, { className: "h-8 w-8 text-destructive" });
14799
15175
  case 'Running':
14800
- return jsxRuntime.jsx(LoaderCircle, { className: "h-8 w-8 text-blue-500 animate-spin" });
15176
+ return jsxRuntime.jsx(LoaderCircle, { className: "h-8 w-8 text-[var(--info-500)] animate-spin" });
14801
15177
  case 'Pending':
14802
15178
  default:
14803
15179
  return jsxRuntime.jsx(Clock, { className: "h-8 w-8 text-muted-foreground" });
@@ -14878,7 +15254,7 @@ function ReindexJobDetailView({ client, jobName, onDelete, watch = true, classNa
14878
15254
  const duration = job ? getReindexJobDuration(job) : null;
14879
15255
  const statusMessage = job ? getReindexJobStatusMessage(job) : '';
14880
15256
  const isTerminal = job ? isReindexJobTerminal(job) : false;
14881
- return (jsxRuntime.jsxs(card.Card, { className: `rounded-xl max-w-md ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-start p-6 border-b border-border space-y-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [isLoading ? (jsxRuntime.jsx(skeleton.Skeleton, { className: "h-8 w-8 rounded-full" })) : (getPhaseIcon(job?.status?.phase)), jsxRuntime.jsx("div", { children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-32 mb-2" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-24" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground m-0", children: statusMessage }), jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground m-0", children: [duration && jsxRuntime.jsx(jsxRuntime.Fragment, { children: duration }), isWatching && !isTerminal && (jsxRuntime.jsx(Badge, { variant: "outline", className: "ml-2 text-xs text-green-600 border-green-300", children: "Live" }))] })] })) })] }), isTerminal && onDelete && (jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 w-8 p-0", children: isDeleting ? (jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxRuntime.jsx(Trash2, { className: "h-4 w-4" })) }))] }), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: loadJob, className: "mx-6 mt-4", errorFormatter: errorFormatter }), !isLoading && job && (jsxRuntime.jsxs(card.CardContent, { className: "p-6 space-y-4", children: [job.status?.phase === 'Failed' && job.status?.message && (jsxRuntime.jsx("div", { className: "p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700", children: job.status.message })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-1", children: "Time Range" }), jsxRuntime.jsxs("div", { className: "text-sm font-mono", children: [job.spec.timeRange.startTime, job.spec.timeRange.endTime && jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [" \u2192 ", job.spec.timeRange.endTime] })] })] }), job.spec.policySelector?.names && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-1", children: "Policy" }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: job.spec.policySelector.names.map((name) => (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-mono", children: name }, name))) })] }))] }))] }));
15257
+ return (jsxRuntime.jsxs(card.Card, { className: `rounded-xl max-w-md ${className}`, children: [jsxRuntime.jsxs(card.CardHeader, { className: "flex flex-row justify-between items-start p-6 border-b border-border space-y-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [isLoading ? (jsxRuntime.jsx(skeleton.Skeleton, { className: "h-8 w-8 rounded-full" })) : (getPhaseIcon(job?.status?.phase)), jsxRuntime.jsx("div", { children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(skeleton.Skeleton, { className: "h-5 w-32 mb-2" }), jsxRuntime.jsx(skeleton.Skeleton, { className: "h-3 w-24" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground m-0", children: statusMessage }), jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground m-0", children: [duration && jsxRuntime.jsx(jsxRuntime.Fragment, { children: duration }), isWatching && !isTerminal && (jsxRuntime.jsx(Badge, { variant: "outline", className: "ml-2 text-xs text-[var(--success-500)] border-[var(--success-300)]", children: "Live" }))] })] })) })] }), isTerminal && onDelete && (jsxRuntime.jsx(button.Button, { type: "quaternary", theme: "borderless", size: "small", onClick: handleDelete, disabled: isDeleting, className: "h-8 w-8 p-0", children: isDeleting ? (jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxRuntime.jsx(Trash2, { className: "h-4 w-4" })) }))] }), jsxRuntime.jsx(ApiErrorAlert, { error: error, onRetry: loadJob, className: "mx-6 mt-4", errorFormatter: errorFormatter }), !isLoading && job && (jsxRuntime.jsxs(card.CardContent, { className: "p-6 space-y-4", children: [job.status?.phase === 'Failed' && job.status?.message && (jsxRuntime.jsx("div", { className: "p-3 bg-destructive/10 border border-destructive/30 rounded-lg text-sm text-destructive", children: job.status.message })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-1", children: "Time Range" }), jsxRuntime.jsxs("div", { className: "text-sm font-mono", children: [job.spec.timeRange.startTime, job.spec.timeRange.endTime && jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [" \u2192 ", job.spec.timeRange.endTime] })] })] }), job.spec.policySelector?.names && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-1", children: "Policy" }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: job.spec.policySelector.names.map((name) => (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-mono", children: name }, name))) })] }))] }))] }));
14882
15258
  }
14883
15259
 
14884
15260
  const TIME_RANGE_OPTIONS$1 = [
@@ -14981,76 +15357,11 @@ function ReindexJobDialog({ client, policyName, open, onOpenChange, onSuccess, e
14981
15357
  return (jsxRuntime.jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-sm", children: [jsxRuntime.jsx(DialogHeader, { children: jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx("div", { className: "p-2 bg-primary/10 rounded-lg", children: jsxRuntime.jsx(RefreshCw, { className: "h-5 w-5 text-primary" }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(DialogTitle, { children: "Reindex Policy" }), jsxRuntime.jsxs(DialogDescription, { className: "text-xs", children: ["Re-process events for \"", policyName, "\""] })] })] }) }), jsxRuntime.jsxs("div", { className: "space-y-4 py-2", children: [jsxRuntime.jsx(ApiErrorAlert, { error: error, errorFormatter: errorFormatter }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-2", children: "Time range" }), jsxRuntime.jsxs(select.Select, { value: selectedRange, onValueChange: setSelectedRange, children: [jsxRuntime.jsx(select.SelectTrigger, { className: "w-full", children: jsxRuntime.jsx(select.SelectValue, { placeholder: "Select time range" }) }), jsxRuntime.jsx(select.SelectContent, { children: TIME_RANGE_OPTIONS.map((option) => (jsxRuntime.jsx(select.SelectItem, { value: option.value, children: option.label }, option.value))) })] })] }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: ["Events from ", selectedOption?.label.toLowerCase(), " will be re-processed."] })] }), jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [jsxRuntime.jsx(button.Button, { htmlType: "button", type: "tertiary", theme: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Cancel" }), jsxRuntime.jsx(button.Button, { htmlType: "button", onClick: handleSubmit, disabled: isSubmitting, children: isSubmitting ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" }), "Starting..."] })) : ('Start Reindex') })] })] }) }));
14982
15358
  }
14983
15359
 
14984
- /**
14985
- * Multi-select combobox component with type-ahead search and fuzzy matching.
14986
- * Built on cmdk for search functionality and Radix Popover for positioning.
14987
- */
14988
- function MultiCombobox({ options, values, onValuesChange, placeholder = 'Select...', searchPlaceholder = 'Search...', emptyMessage = 'No results found.', disabled = false, loading = false, className, maxDisplayed = 2, }) {
14989
- const [open, setOpen] = React__namespace.useState(false);
14990
- const [search, setSearch] = React__namespace.useState('');
14991
- // Find selected options for display
14992
- const selectedOptions = options.filter((opt) => values.includes(opt.value));
14993
- const displayValue = React__namespace.useMemo(() => {
14994
- if (loading)
14995
- return 'Loading...';
14996
- if (selectedOptions.length === 0)
14997
- return placeholder;
14998
- if (selectedOptions.length <= maxDisplayed) {
14999
- return selectedOptions.map((opt) => opt.label).join(', ');
15000
- }
15001
- return `${selectedOptions.slice(0, maxDisplayed).map((opt) => opt.label).join(', ')} +${selectedOptions.length - maxDisplayed} more`;
15002
- }, [loading, selectedOptions, placeholder, maxDisplayed]);
15003
- const handleSelect = React__namespace.useCallback((selectedValue) => {
15004
- if (values.includes(selectedValue)) {
15005
- // Remove from selection
15006
- onValuesChange(values.filter((v) => v !== selectedValue));
15007
- }
15008
- else {
15009
- // Add to selection
15010
- onValuesChange([...values, selectedValue]);
15011
- }
15012
- }, [onValuesChange, values]);
15013
- const handleClear = React__namespace.useCallback((e) => {
15014
- e.stopPropagation();
15015
- onValuesChange([]);
15016
- }, [onValuesChange]);
15017
- const handleRemove = React__namespace.useCallback((e, valueToRemove) => {
15018
- e.stopPropagation();
15019
- onValuesChange(values.filter((v) => v !== valueToRemove));
15020
- }, [onValuesChange, values]);
15021
- // Custom fuzzy filter function
15022
- const filterOptions = React__namespace.useCallback((optionValue, searchQuery) => {
15023
- if (!searchQuery)
15024
- return 1;
15025
- const option = options.find((o) => o.value === optionValue);
15026
- const label = option?.label || optionValue;
15027
- const lowerLabel = label.toLowerCase();
15028
- const lowerSearch = searchQuery.toLowerCase();
15029
- // Exact match
15030
- if (lowerLabel === lowerSearch)
15031
- return 1;
15032
- // Starts with
15033
- if (lowerLabel.startsWith(lowerSearch))
15034
- return 0.9;
15035
- // Contains
15036
- if (lowerLabel.includes(lowerSearch))
15037
- return 0.8;
15038
- // Fuzzy match - check if all search chars appear in order
15039
- let searchIdx = 0;
15040
- for (let i = 0; i < lowerLabel.length && searchIdx < lowerSearch.length; i++) {
15041
- if (lowerLabel[i] === lowerSearch[searchIdx]) {
15042
- searchIdx++;
15043
- }
15044
- }
15045
- if (searchIdx === lowerSearch.length)
15046
- return 0.6;
15047
- return 0;
15048
- }, [options]);
15049
- return (jsxRuntime.jsxs(Popover__namespace.Root, { open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", disabled: disabled || loading, className: cn('flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background', 'placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', 'whitespace-nowrap', className), children: [jsxRuntime.jsx("span", { className: "truncate text-left flex-1", children: displayValue }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-2", children: [values.length > 0 && !disabled && (jsxRuntime.jsx("span", { role: "button", tabIndex: 0, onClick: handleClear, onKeyDown: (e) => {
15050
- if (e.key === 'Enter' || e.key === ' ') {
15051
- handleClear(e);
15052
- }
15053
- }, className: "rounded-sm opacity-50 hover:opacity-100 cursor-pointer", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) })), jsxRuntime.jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })] })] }) }), jsxRuntime.jsx(Popover__namespace.Portal, { children: jsxRuntime.jsx(Popover__namespace.Content, { className: cn('z-50 min-w-[var(--radix-popover-trigger-width)] overflow-hidden rounded-md border shadow-md', 'bg-white dark:bg-slate-900 text-foreground', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2'), sideOffset: 4, align: "start", children: jsxRuntime.jsxs(cmdk.Command, { filter: filterOptions, className: "w-full", children: [jsxRuntime.jsx("div", { className: "flex items-center border-b px-3", children: jsxRuntime.jsx(cmdk.CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch, className: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" }) }), values.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 p-2 border-b", children: selectedOptions.map((option) => (jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-secondary text-secondary-foreground text-xs", children: [option.label, jsxRuntime.jsx("button", { type: "button", onClick: (e) => handleRemove(e, option.value), className: "rounded-sm hover:bg-secondary-foreground/20", children: jsxRuntime.jsx(X, { className: "h-3 w-3" }) })] }, option.value))) })), jsxRuntime.jsxs(cmdk.CommandList, { className: "max-h-[300px] overflow-y-auto p-1", children: [jsxRuntime.jsx(cmdk.CommandEmpty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }), jsxRuntime.jsx(cmdk.CommandGroup, { children: options.map((option) => (jsxRuntime.jsxs(cmdk.CommandItem, { value: option.value, onSelect: () => handleSelect(option.value), className: cn('relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none', 'data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground', 'hover:bg-accent hover:text-accent-foreground'), children: [jsxRuntime.jsx(Check, { className: cn('mr-2 h-4 w-4', values.includes(option.value) ? 'opacity-100' : 'opacity-0') }), jsxRuntime.jsx("span", { className: "flex-1 truncate", children: option.label }), option.count !== undefined && (jsxRuntime.jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", option.count, ")"] }))] }, option.value))) })] })] }) }) })] }));
15360
+ function MultiCombobox({ options, values, onValuesChange, placeholder = 'Select…',
15361
+ // searchPlaceholder is accepted for API compatibility but MultiSelect has no counterpart.
15362
+ emptyMessage = 'No results', disabled, loading, className, maxDisplayed = 3, }) {
15363
+ const items = React__namespace.useMemo(() => options.map((o) => ({ value: o.value, label: o.label })), [options]);
15364
+ return (jsxRuntime.jsx(multiSelect.MultiSelect, { className: className, options: items, value: values, onValueChange: onValuesChange, placeholder: placeholder, emptyContent: emptyMessage, isLoading: loading, disabled: disabled, maxCount: maxDisplayed }));
15054
15365
  }
15055
15366
 
15056
15367
  /**
@@ -15760,7 +16071,7 @@ class ActivityApiClient {
15760
16071
  const reader = response.body.getReader();
15761
16072
  const decoder = new TextDecoder();
15762
16073
  let buffer = '';
15763
- while (true) {
16074
+ for (;;) {
15764
16075
  const { done, value } = await reader.read();
15765
16076
  if (done) {
15766
16077
  options?.onClose?.();
@@ -16160,7 +16471,7 @@ class ActivityApiClient {
16160
16471
  const reader = response.body.getReader();
16161
16472
  const decoder = new TextDecoder();
16162
16473
  let buffer = '';
16163
- while (true) {
16474
+ for (;;) {
16164
16475
  const { done, value } = await reader.read();
16165
16476
  if (done) {
16166
16477
  options?.onClose?.();
@@ -16276,7 +16587,7 @@ class ActivityApiClient {
16276
16587
  const reader = response.body.getReader();
16277
16588
  const decoder = new TextDecoder();
16278
16589
  let buffer = '';
16279
- while (true) {
16590
+ for (;;) {
16280
16591
  const { done, value } = await reader.read();
16281
16592
  if (done) {
16282
16593
  options?.onClose?.();
@@ -16633,9 +16944,11 @@ exports.AUDIT_TEMPLATES = AUDIT_TEMPLATES;
16633
16944
  exports.ActionMultiSelect = ActionMultiSelect;
16634
16945
  exports.ActionToggle = ActionToggle;
16635
16946
  exports.ActivityApiClient = ActivityApiClient;
16947
+ exports.ActivityDigestSummary = ActivityDigestSummary;
16636
16948
  exports.ActivityExpandedDetails = ActivityExpandedDetails;
16637
16949
  exports.ActivityFeed = ActivityFeed;
16638
16950
  exports.ActivityFeedFilters = ActivityFeedFilters;
16951
+ exports.ActivityFeedGroupItem = ActivityFeedGroupItem;
16639
16952
  exports.ActivityFeedItem = ActivityFeedItem;
16640
16953
  exports.ActivityFeedItemSkeleton = ActivityFeedItemSkeleton;
16641
16954
  exports.ActivityFeedSummary = ActivityFeedSummary;
@@ -16715,6 +17028,8 @@ exports.extractFieldPathsFromMany = extractFieldPathsFromMany;
16715
17028
  exports.generateShareableUrl = generateShareableUrl;
16716
17029
  exports.getReindexJobDuration = getReindexJobDuration;
16717
17030
  exports.getReindexJobStatusMessage = getReindexJobStatusMessage;
17031
+ exports.groupActivities = groupActivities;
17032
+ exports.groupActivitiesByDay = groupActivitiesByDay;
16718
17033
  exports.isEventRecord = isEventRecord;
16719
17034
  exports.isReindexJobRunning = isReindexJobRunning;
16720
17035
  exports.isReindexJobTerminal = isReindexJobTerminal;