@datum-cloud/activity-ui 0.5.0-dev.dc45652 → 0.5.1-dev.7e7e319

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 (62) hide show
  1. package/README.md +15 -1
  2. package/dist/components/ActionMultiSelect.d.ts.map +1 -1
  3. package/dist/components/ActivityFeed.d.ts.map +1 -1
  4. package/dist/components/ActivityFeedFilters.d.ts +9 -1
  5. package/dist/components/ActivityFeedFilters.d.ts.map +1 -1
  6. package/dist/components/AuditLogFeedItem.d.ts.map +1 -1
  7. package/dist/components/CelEditor.d.ts +1 -1
  8. package/dist/components/CelEditor.d.ts.map +1 -1
  9. package/dist/components/ChangeSourceToggle.d.ts.map +1 -1
  10. package/dist/components/DateTimeRangePicker.d.ts.map +1 -1
  11. package/dist/components/EventFeedItem.d.ts.map +1 -1
  12. package/dist/components/EventTypeToggle.d.ts.map +1 -1
  13. package/dist/components/FilterBuilder.d.ts.map +1 -1
  14. package/dist/components/FilterBuilderWithAutocomplete.d.ts.map +1 -1
  15. package/dist/components/PolicyDetailView.d.ts.map +1 -1
  16. package/dist/components/PolicyEditView.d.ts.map +1 -1
  17. package/dist/components/PolicyEditor.d.ts.map +1 -1
  18. package/dist/components/UserSelect.d.ts.map +1 -1
  19. package/dist/components/VerbToggle.d.ts.map +1 -1
  20. package/dist/components/ui/add-filter-dropdown.d.ts.map +1 -1
  21. package/dist/components/ui/combobox.d.ts +0 -4
  22. package/dist/components/ui/combobox.d.ts.map +1 -1
  23. package/dist/components/ui/filter-chip.d.ts.map +1 -1
  24. package/dist/components/ui/multi-combobox.d.ts +2 -5
  25. package/dist/components/ui/multi-combobox.d.ts.map +1 -1
  26. package/dist/components/ui/segmented-toggle.d.ts +26 -0
  27. package/dist/components/ui/segmented-toggle.d.ts.map +1 -0
  28. package/dist/components/ui/time-range-dropdown.d.ts +13 -4
  29. package/dist/components/ui/time-range-dropdown.d.ts.map +1 -1
  30. package/dist/hooks/useAuditLogQuery.d.ts +1 -1
  31. package/dist/hooks/useAuditLogQuery.d.ts.map +1 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.esm.js +1361 -1406
  35. package/dist/index.esm.js.map +1 -1
  36. package/dist/index.js +1361 -1406
  37. package/dist/index.js.map +1 -1
  38. package/package.json +8 -13
  39. package/dist/components/ui/alert.d.ts +0 -9
  40. package/dist/components/ui/alert.d.ts.map +0 -1
  41. package/dist/components/ui/button.d.ts +0 -12
  42. package/dist/components/ui/button.d.ts.map +0 -1
  43. package/dist/components/ui/card.d.ts +0 -9
  44. package/dist/components/ui/card.d.ts.map +0 -1
  45. package/dist/components/ui/checkbox.d.ts +0 -5
  46. package/dist/components/ui/checkbox.d.ts.map +0 -1
  47. package/dist/components/ui/input.d.ts +0 -6
  48. package/dist/components/ui/input.d.ts.map +0 -1
  49. package/dist/components/ui/label.d.ts +0 -8
  50. package/dist/components/ui/label.d.ts.map +0 -1
  51. package/dist/components/ui/select.d.ts +0 -14
  52. package/dist/components/ui/select.d.ts.map +0 -1
  53. package/dist/components/ui/separator.d.ts +0 -5
  54. package/dist/components/ui/separator.d.ts.map +0 -1
  55. package/dist/components/ui/sheet.d.ts +0 -23
  56. package/dist/components/ui/sheet.d.ts.map +0 -1
  57. package/dist/components/ui/skeleton.d.ts +0 -3
  58. package/dist/components/ui/skeleton.d.ts.map +0 -1
  59. package/dist/components/ui/tabs.d.ts +0 -8
  60. package/dist/components/ui/tabs.d.ts.map +0 -1
  61. package/dist/components/ui/textarea.d.ts +0 -6
  62. 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
  /**
@@ -4018,763 +4021,527 @@ function subMinutes(date, amount, options) {
4018
4021
  return addMinutes(date, -15, options);
4019
4022
  }
4020
4023
 
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
- };
4024
+ /** Sentinel for the "All" item; the public value stays '' for "no filter". */
4025
+ const ALL_VALUE = '__all__';
4026
+ function Combobox({ options, value, onValueChange, placeholder = 'Select…', searchPlaceholder = 'Search…', emptyMessage = 'No results', disabled, loading, className, clearable = false, showAllOption = true, allOptionLabel = 'All', }) {
4027
+ const items = React__namespace.useMemo(() => {
4028
+ const base = options.map((o) => ({ value: o.value, label: o.label, count: o.count }));
4029
+ return showAllOption ? [{ value: ALL_VALUE, label: allOptionLabel }, ...base] : base;
4030
+ }, [options, showAllOption, allOptionLabel]);
4031
+ // An empty value selects the "All" item so the trigger reads its label.
4032
+ const selectedValue = value === '' && showAllOption ? ALL_VALUE : value;
4033
+ 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 }))] })) }));
4034
+ }
4100
4035
 
4036
+ const RELATIVE_KEY = /^now-(\d+)([mhd])$/;
4037
+ /** Resolve a relative key such as `now-7d` to a `{ from, to }` window ending now. */
4038
+ function relativeKeyToRange(key, now = new Date()) {
4039
+ const match = RELATIVE_KEY.exec(key);
4040
+ if (!match)
4041
+ return null;
4042
+ const amount = Number(match[1]);
4043
+ const unitMs = { m: 60000, h: 3600000, d: 86400000 }[match[2]];
4044
+ return { from: new Date(now.getTime() - amount * unitMs), to: now };
4045
+ }
4046
+ /** `YYYY-MM-DDTHH:mm` in local time, the format the filter components store. */
4047
+ function toDatetimeLocal(iso) {
4048
+ const d = new Date(iso);
4049
+ const pad = (n) => String(n).padStart(2, '0');
4050
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
4051
+ }
4052
+ function toPickerPresets(presets) {
4053
+ return presets
4054
+ .filter((p) => RELATIVE_KEY.test(p.key))
4055
+ .map((p) => ({
4056
+ key: p.key,
4057
+ label: p.label,
4058
+ getRange: () => relativeKeyToRange(p.key),
4059
+ }));
4060
+ }
4101
4061
  /**
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.
4062
+ * TimeRangeDropdown - relative presets plus an absolute range, on datum-ui's
4063
+ * DateTimeRangePicker. The emitted value carries `preset` when a preset was
4064
+ * clicked, which keeps `start=now-7d` style URL state intact.
4106
4065
  */
4066
+ function TimeRangeDropdown({ presets, selectedPreset, onPresetSelect, onCustomRangeApply, customStart, customEnd, disabled = false, className, displayLabel, }) {
4067
+ const pickerPresets = React__namespace.useMemo(() => toPickerPresets(presets), [presets]);
4068
+ const value = React__namespace.useMemo(() => {
4069
+ if (selectedPreset !== 'custom') {
4070
+ const range = relativeKeyToRange(selectedPreset);
4071
+ return range
4072
+ ? { from: range.from.toISOString(), to: range.to.toISOString(), preset: selectedPreset }
4073
+ : null;
4074
+ }
4075
+ if (customStart && customEnd) {
4076
+ return { from: new Date(customStart).toISOString(), to: new Date(customEnd).toISOString() };
4077
+ }
4078
+ return null;
4079
+ }, [selectedPreset, customStart, customEnd]);
4080
+ const handleChange = (next) => {
4081
+ if (!next)
4082
+ return;
4083
+ const preset = next.preset;
4084
+ if (preset) {
4085
+ onPresetSelect(preset);
4086
+ return;
4087
+ }
4088
+ onCustomRangeApply(toDatetimeLocal(next.from), toDatetimeLocal(next.to));
4089
+ };
4090
+ 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 }));
4091
+ }
4107
4092
 
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",
4093
+ const TIME_PRESETS$3 = [
4121
4094
  {
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
4095
+ key: 'last15min',
4096
+ label: 'Last 15 min',
4097
+ getValue: () => ({
4098
+ start: formatISO(subMinutes(new Date())),
4099
+ end: formatISO(new Date()),
4100
+ }),
4131
4101
  },
4132
- [
4133
- ...iconNode.map(([tag, attrs]) => React.createElement(tag, attrs)),
4134
- ...Array.isArray(children) ? children : [children]
4135
- ]
4136
- )
4137
- );
4138
-
4139
- /**
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.
4144
- */
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;
4162
- };
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
4102
  {
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",
4103
+ key: 'last1hour',
4104
+ label: 'Last hour',
4105
+ getValue: () => ({
4106
+ start: formatISO(subHours(new Date(), 1)),
4107
+ end: formatISO(new Date()),
4108
+ }),
4109
+ },
4195
4110
  {
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"
4198
- }
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" }]
4111
+ key: 'last6hours',
4112
+ label: 'Last 6 hours',
4113
+ getValue: () => ({
4114
+ start: formatISO(subHours(new Date(), 6)),
4115
+ end: formatISO(new Date()),
4116
+ }),
4117
+ },
4118
+ {
4119
+ key: 'last24hours',
4120
+ label: 'Last 24 hours',
4121
+ getValue: () => ({
4122
+ start: formatISO(subHours(new Date(), 24)),
4123
+ end: formatISO(new Date()),
4124
+ }),
4125
+ },
4126
+ {
4127
+ key: 'last7days',
4128
+ label: 'Last 7 days',
4129
+ getValue: () => ({
4130
+ start: formatISO(subDays(new Date(), 7)),
4131
+ end: formatISO(new Date()),
4132
+ }),
4133
+ },
4134
+ {
4135
+ key: 'last30days',
4136
+ label: 'Last 30 days',
4137
+ getValue: () => ({
4138
+ start: formatISO(subDays(new Date(), 30)),
4139
+ end: formatISO(new Date()),
4140
+ }),
4141
+ },
4216
4142
  ];
4217
- const Calendar = createLucideIcon("calendar", __iconNode$n);
4218
-
4143
+ /** Debounce delay for text inputs (ms) */
4144
+ const DEBOUNCE_DELAY = 300;
4219
4145
  /**
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.
4146
+ * Helper function to convert ISO string to datetime-local format
4224
4147
  */
4148
+ const formatDatetimeLocal$4 = (isoString) => {
4149
+ const date = new Date(isoString);
4150
+ const year = date.getFullYear();
4151
+ const month = String(date.getMonth() + 1).padStart(2, '0');
4152
+ const day = String(date.getDate()).padStart(2, '0');
4153
+ const hours = String(date.getHours()).padStart(2, '0');
4154
+ const minutes = String(date.getMinutes()).padStart(2, '0');
4155
+ return `${year}-${month}-${day}T${hours}:${minutes}`;
4156
+ };
4157
+ function SimpleQueryBuilder({ client, onFilterChange, initialLimit = 100, className = '', disabled = false, }) {
4158
+ const [isAdvancedExpanded, setIsAdvancedExpanded] = React.useState(false);
4159
+ const [filters, setFilters] = React.useState({
4160
+ verb: '',
4161
+ resourceType: '',
4162
+ namespace: '',
4163
+ resourceName: '',
4164
+ username: '',
4165
+ });
4166
+ const [limit, setLimit] = React.useState(initialLimit);
4167
+ const [advancedFilter, setAdvancedFilter] = React.useState('');
4168
+ const [useAdvancedFilter, setUseAdvancedFilter] = React.useState(false);
4169
+ // Time range state
4170
+ const [selectedPreset, setSelectedPreset] = React.useState('last24hours');
4171
+ const [timeRange, setTimeRange] = React.useState(null);
4172
+ const [customStart, setCustomStart] = React.useState(() => formatDatetimeLocal$4(formatISO(subDays(new Date(), 1))));
4173
+ const [customEnd, setCustomEnd] = React.useState(() => formatDatetimeLocal$4(formatISO(new Date())));
4174
+ // Fetch facets for dynamic filter options
4175
+ const { verbs, resources, namespaces, usernames, isLoading: facetsLoading, error: facetsError } = useAuditLogFacets(client, timeRange);
4176
+ // Log facets error for debugging
4177
+ if (facetsError) {
4178
+ console.error('Failed to load audit log facets:', facetsError);
4179
+ }
4180
+ // Refs for debouncing
4181
+ const debounceTimerRef = React.useRef(null);
4182
+ const isInitialMount = React.useRef(true);
4183
+ // Initialize with default time range and trigger initial query
4184
+ React.useEffect(() => {
4185
+ const defaultRange = TIME_PRESETS$3.find(p => p.key === 'last24hours')?.getValue();
4186
+ if (defaultRange) {
4187
+ setTimeRange(defaultRange);
4188
+ }
4189
+ }, []);
4190
+ const generateCEL = React.useCallback(() => {
4191
+ const parts = [];
4192
+ if (filters.verb) {
4193
+ parts.push(`verb == "${filters.verb}"`);
4194
+ }
4195
+ if (filters.resourceType) {
4196
+ parts.push(`objectRef.resource == "${filters.resourceType}"`);
4197
+ }
4198
+ if (filters.namespace) {
4199
+ parts.push(`objectRef.namespace == "${filters.namespace}"`);
4200
+ }
4201
+ if (filters.resourceName) {
4202
+ parts.push(`objectRef.name.contains("${filters.resourceName}")`);
4203
+ }
4204
+ if (filters.username) {
4205
+ parts.push(`user.username.contains("${filters.username}")`);
4206
+ }
4207
+ return parts.join(' && ');
4208
+ }, [filters]);
4209
+ // Execute query when filters change (with debouncing for text inputs)
4210
+ const executeQuery = React.useCallback(() => {
4211
+ if (!timeRange || disabled)
4212
+ return;
4213
+ const filter = useAdvancedFilter ? advancedFilter : generateCEL();
4214
+ onFilterChange({
4215
+ filter,
4216
+ limit,
4217
+ startTime: timeRange.start,
4218
+ endTime: timeRange.end
4219
+ });
4220
+ }, [useAdvancedFilter, advancedFilter, generateCEL, onFilterChange, limit, timeRange, disabled]);
4221
+ // Auto-execute query when dropdown filters or time range change (immediate)
4222
+ React.useEffect(() => {
4223
+ // Skip the initial mount - we want to wait for timeRange to be set
4224
+ if (isInitialMount.current) {
4225
+ isInitialMount.current = false;
4226
+ return;
4227
+ }
4228
+ // Clear any pending debounced query
4229
+ if (debounceTimerRef.current) {
4230
+ clearTimeout(debounceTimerRef.current);
4231
+ }
4232
+ executeQuery();
4233
+ }, [filters.verb, filters.resourceType, timeRange, limit, useAdvancedFilter]);
4234
+ // Auto-execute query when text filters change (debounced)
4235
+ React.useEffect(() => {
4236
+ if (isInitialMount.current || !timeRange)
4237
+ return;
4238
+ // Clear previous timer
4239
+ if (debounceTimerRef.current) {
4240
+ clearTimeout(debounceTimerRef.current);
4241
+ }
4242
+ // Set new debounced timer
4243
+ debounceTimerRef.current = setTimeout(() => {
4244
+ executeQuery();
4245
+ }, DEBOUNCE_DELAY);
4246
+ return () => {
4247
+ if (debounceTimerRef.current) {
4248
+ clearTimeout(debounceTimerRef.current);
4249
+ }
4250
+ };
4251
+ }, [filters.namespace, filters.resourceName, filters.username, advancedFilter]);
4252
+ const handleFilterChange = React.useCallback((field, value) => {
4253
+ setFilters(prev => ({ ...prev, [field]: value }));
4254
+ }, []);
4255
+ const handleTimePresetSelect = React.useCallback((presetKey) => {
4256
+ const preset = TIME_PRESETS$3.find(p => p.key === presetKey);
4257
+ if (preset) {
4258
+ setSelectedPreset(presetKey);
4259
+ setTimeRange(preset.getValue());
4260
+ }
4261
+ }, []);
4262
+ const handleCustomRangeApply = React.useCallback((start, end) => {
4263
+ setSelectedPreset('custom');
4264
+ setCustomStart(start);
4265
+ setCustomEnd(end);
4266
+ setTimeRange({
4267
+ start: new Date(start).toISOString(),
4268
+ end: new Date(end).toISOString(),
4269
+ });
4270
+ }, []);
4271
+ const handleLimitChange = React.useCallback((newLimit) => {
4272
+ const validLimit = Math.min(Math.max(1, newLimit), 1000);
4273
+ setLimit(validLimit);
4274
+ }, []);
4275
+ const handleAdvancedToggle = React.useCallback(() => {
4276
+ if (!isAdvancedExpanded) {
4277
+ // When expanding, populate advanced filter with generated CEL
4278
+ setAdvancedFilter(generateCEL());
4279
+ }
4280
+ setIsAdvancedExpanded(!isAdvancedExpanded);
4281
+ }, [isAdvancedExpanded, generateCEL]);
4282
+ const handleUseAdvancedChange = React.useCallback((checked) => {
4283
+ setUseAdvancedFilter(checked === true);
4284
+ }, []);
4285
+ // Get display label for time range
4286
+ const getTimeRangeLabel = () => {
4287
+ if (selectedPreset === 'custom') {
4288
+ if (timeRange?.start && timeRange?.end) {
4289
+ const start = new Date(timeRange.start);
4290
+ const end = new Date(timeRange.end);
4291
+ return `${start.toLocaleDateString()} - ${end.toLocaleDateString()}`;
4292
+ }
4293
+ return 'Custom';
4294
+ }
4295
+ const preset = TIME_PRESETS$3.find(p => p.key === selectedPreset);
4296
+ return preset?.label || 'Select time range';
4297
+ };
4298
+ 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
4299
+ .filter(facet => facet.value)
4300
+ .map(facet => ({
4301
+ value: facet.value,
4302
+ label: facet.value,
4303
+ count: facet.count,
4304
+ })), 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
4305
+ .filter(facet => facet.value)
4306
+ .map(facet => ({
4307
+ value: facet.value,
4308
+ label: facet.value,
4309
+ count: facet.count,
4310
+ })), 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
4311
+ .filter(facet => facet.value)
4312
+ .map(facet => ({
4313
+ value: facet.value,
4314
+ label: facet.value,
4315
+ count: facet.count,
4316
+ })), 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
4317
+ .filter(facet => facet.value)
4318
+ .map(facet => ({
4319
+ value: facet.value,
4320
+ label: facet.value,
4321
+ count: facet.count,
4322
+ })), 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 })] }))] }))] }));
4323
+ }
4225
4324
 
4226
-
4227
- const __iconNode$m = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
4228
- const Check = createLucideIcon("check", __iconNode$m);
4229
-
4230
- /**
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.
4235
- */
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);
4325
+ 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}
4305
4326
 
4306
4327
  /**
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.
4328
+ * Concatenates two arrays faster than the array spread operator.
4311
4329
  */
4330
+ const concatArrays = (array1, array2) => {
4331
+ // Pre-allocate for better V8 optimization
4332
+ const combinedArray = new Array(array1.length + array2.length);
4333
+ for (let i = 0; i < array1.length; i++) {
4334
+ combinedArray[i] = array1[i];
4335
+ }
4336
+ for (let i = 0; i < array2.length; i++) {
4337
+ combinedArray[array1.length + i] = array2[i];
4338
+ }
4339
+ return combinedArray;
4340
+ };
4312
4341
 
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"
4342
+ // Factory function ensures consistent object shapes
4343
+ const createClassValidatorObject = (classGroupId, validator) => ({
4344
+ classGroupId,
4345
+ validator
4346
+ });
4347
+ // Factory ensures consistent ClassPartObject shape
4348
+ const createClassPartObject = (nextPart = new Map(), validators = null, classGroupId) => ({
4349
+ nextPart,
4350
+ validators,
4351
+ classGroupId
4352
+ });
4353
+ const CLASS_PART_SEPARATOR = '-';
4354
+ const EMPTY_CONFLICTS = [];
4355
+ // I use two dots here because one dot is used as prefix for class groups in plugins
4356
+ const ARBITRARY_PROPERTY_PREFIX = 'arbitrary..';
4357
+ const createClassGroupUtils = config => {
4358
+ const classMap = createClassMap(config);
4359
+ const {
4360
+ conflictingClassGroups,
4361
+ conflictingClassGroupModifiers
4362
+ } = config;
4363
+ const getClassGroupId = className => {
4364
+ if (className.startsWith('[') && className.endsWith(']')) {
4365
+ return getGroupIdForArbitraryProperty(className);
4377
4366
  }
4378
- ],
4379
- ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
4380
- ];
4381
- const Eye = createLucideIcon("eye", __iconNode$b);
4382
-
4367
+ const classParts = className.split(CLASS_PART_SEPARATOR);
4368
+ // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and skip it.
4369
+ const startIndex = classParts[0] === '' && classParts.length > 1 ? 1 : 0;
4370
+ return getGroupRecursive(classParts, startIndex, classMap);
4371
+ };
4372
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
4373
+ if (hasPostfixModifier) {
4374
+ const modifierConflicts = conflictingClassGroupModifiers[classGroupId];
4375
+ const baseConflicts = conflictingClassGroups[classGroupId];
4376
+ if (modifierConflicts) {
4377
+ if (baseConflicts) {
4378
+ // Merge base conflicts with modifier conflicts
4379
+ return concatArrays(baseConflicts, modifierConflicts);
4380
+ }
4381
+ // Only modifier conflicts
4382
+ return modifierConflicts;
4383
+ }
4384
+ // Fall back to without postfix if no modifier conflicts
4385
+ return baseConflicts || EMPTY_CONFLICTS;
4386
+ }
4387
+ return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;
4388
+ };
4389
+ return {
4390
+ getClassGroupId,
4391
+ getConflictingClassGroupIds
4392
+ };
4393
+ };
4394
+ const getGroupRecursive = (classParts, startIndex, classPartObject) => {
4395
+ const classPathsLength = classParts.length - startIndex;
4396
+ if (classPathsLength === 0) {
4397
+ return classPartObject.classGroupId;
4398
+ }
4399
+ const currentClassPart = classParts[startIndex];
4400
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
4401
+ if (nextClassPartObject) {
4402
+ const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
4403
+ if (result) return result;
4404
+ }
4405
+ const validators = classPartObject.validators;
4406
+ if (validators === null) {
4407
+ return undefined;
4408
+ }
4409
+ // Build classRest string efficiently by joining from startIndex onwards
4410
+ const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);
4411
+ const validatorsLength = validators.length;
4412
+ for (let i = 0; i < validatorsLength; i++) {
4413
+ const validatorObj = validators[i];
4414
+ if (validatorObj.validator(classRest)) {
4415
+ return validatorObj.classGroupId;
4416
+ }
4417
+ }
4418
+ return undefined;
4419
+ };
4383
4420
  /**
4384
- * @license lucide-react v0.577.0 - ISC
4421
+ * Get the class group ID for an arbitrary property.
4385
4422
  *
4386
- * This source code is licensed under the ISC license.
4387
- * See the LICENSE file in the root directory of this source tree.
4423
+ * @param className - The class name to get the group ID for. Is expected to be string starting with `[` and ending with `]`.
4388
4424
  */
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
-
4425
+ const getGroupIdForArbitraryProperty = className => className.slice(1, -1).indexOf(':') === -1 ? undefined : (() => {
4426
+ const content = className.slice(1, -1);
4427
+ const colonIndex = content.indexOf(':');
4428
+ const property = content.slice(0, colonIndex);
4429
+ return property ? ARBITRARY_PROPERTY_PREFIX + property : undefined;
4430
+ })();
4394
4431
  /**
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.
4432
+ * Exported for testing only
4399
4433
  */
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"
4434
+ const createClassMap = config => {
4435
+ const {
4436
+ theme,
4437
+ classGroups
4438
+ } = config;
4439
+ return processClassGroups(classGroups, theme);
4440
+ };
4441
+ // Split into separate functions to maintain monomorphic call sites
4442
+ const processClassGroups = (classGroups, theme) => {
4443
+ const classMap = createClassPartObject();
4444
+ for (const classGroupId in classGroups) {
4445
+ const group = classGroups[classGroupId];
4446
+ processClassesRecursively(group, classMap, classGroupId, theme);
4447
+ }
4448
+ return classMap;
4449
+ };
4450
+ const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
4451
+ const len = classGroup.length;
4452
+ for (let i = 0; i < len; i++) {
4453
+ const classDefinition = classGroup[i];
4454
+ processClassDefinition(classDefinition, classPartObject, classGroupId, theme);
4455
+ }
4456
+ };
4457
+ // Split into separate functions for each type to maintain monomorphic call sites
4458
+ const processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4459
+ if (typeof classDefinition === 'string') {
4460
+ processStringDefinition(classDefinition, classPartObject, classGroupId);
4461
+ return;
4462
+ }
4463
+ if (typeof classDefinition === 'function') {
4464
+ processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);
4465
+ return;
4466
+ }
4467
+ processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);
4468
+ };
4469
+ const processStringDefinition = (classDefinition, classPartObject, classGroupId) => {
4470
+ const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);
4471
+ classPartObjectToEdit.classGroupId = classGroupId;
4472
+ };
4473
+ const processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4474
+ if (isThemeGetter(classDefinition)) {
4475
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
4476
+ return;
4477
+ }
4478
+ if (classPartObject.validators === null) {
4479
+ classPartObject.validators = [];
4480
+ }
4481
+ classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));
4482
+ };
4483
+ const processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4484
+ const entries = Object.entries(classDefinition);
4485
+ const len = entries.length;
4486
+ for (let i = 0; i < len; i++) {
4487
+ const [key, value] = entries[i];
4488
+ processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);
4489
+ }
4490
+ };
4491
+ const getPart = (classPartObject, path) => {
4492
+ let current = classPartObject;
4493
+ const parts = path.split(CLASS_PART_SEPARATOR);
4494
+ const len = parts.length;
4495
+ for (let i = 0; i < len; i++) {
4496
+ const part = parts[i];
4497
+ let next = current.nextPart.get(part);
4498
+ if (!next) {
4499
+ next = createClassPartObject();
4500
+ current.nextPart.set(part, next);
4408
4501
  }
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
- */
4502
+ current = next;
4503
+ }
4504
+ return current;
4505
+ };
4506
+ // Type guard maintains monomorphic check
4507
+ const isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;
4420
4508
 
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];
4509
+ // LRU cache implementation using plain objects for simplicity
4510
+ const createLruCache = maxCacheSize => {
4511
+ if (maxCacheSize < 1) {
4512
+ return {
4513
+ get: () => undefined,
4514
+ set: () => {}
4515
+ };
4571
4516
  }
4572
- return combinedArray;
4573
- };
4574
-
4575
- // Factory function ensures consistent object shapes
4576
- const createClassValidatorObject = (classGroupId, validator) => ({
4577
- classGroupId,
4578
- validator
4579
- });
4580
- // Factory ensures consistent ClassPartObject shape
4581
- const createClassPartObject = (nextPart = new Map(), validators = null, classGroupId) => ({
4582
- nextPart,
4583
- validators,
4584
- classGroupId
4585
- });
4586
- const CLASS_PART_SEPARATOR = '-';
4587
- const EMPTY_CONFLICTS = [];
4588
- // I use two dots here because one dot is used as prefix for class groups in plugins
4589
- const ARBITRARY_PROPERTY_PREFIX = 'arbitrary..';
4590
- const createClassGroupUtils = config => {
4591
- const classMap = createClassMap(config);
4592
- const {
4593
- conflictingClassGroups,
4594
- conflictingClassGroupModifiers
4595
- } = config;
4596
- const getClassGroupId = className => {
4597
- if (className.startsWith('[') && className.endsWith(']')) {
4598
- return getGroupIdForArbitraryProperty(className);
4517
+ let cacheSize = 0;
4518
+ let cache = Object.create(null);
4519
+ let previousCache = Object.create(null);
4520
+ const update = (key, value) => {
4521
+ cache[key] = value;
4522
+ cacheSize++;
4523
+ if (cacheSize > maxCacheSize) {
4524
+ cacheSize = 0;
4525
+ previousCache = cache;
4526
+ cache = Object.create(null);
4599
4527
  }
4600
- const classParts = className.split(CLASS_PART_SEPARATOR);
4601
- // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and skip it.
4602
- const startIndex = classParts[0] === '' && classParts.length > 1 ? 1 : 0;
4603
- return getGroupRecursive(classParts, startIndex, classMap);
4604
4528
  };
4605
- const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
4606
- if (hasPostfixModifier) {
4607
- const modifierConflicts = conflictingClassGroupModifiers[classGroupId];
4608
- const baseConflicts = conflictingClassGroups[classGroupId];
4609
- if (modifierConflicts) {
4610
- if (baseConflicts) {
4611
- // Merge base conflicts with modifier conflicts
4612
- return concatArrays(baseConflicts, modifierConflicts);
4613
- }
4614
- // Only modifier conflicts
4615
- return modifierConflicts;
4616
- }
4617
- // Fall back to without postfix if no modifier conflicts
4618
- return baseConflicts || EMPTY_CONFLICTS;
4619
- }
4620
- return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;
4621
- };
4622
- return {
4623
- getClassGroupId,
4624
- getConflictingClassGroupIds
4625
- };
4626
- };
4627
- const getGroupRecursive = (classParts, startIndex, classPartObject) => {
4628
- const classPathsLength = classParts.length - startIndex;
4629
- if (classPathsLength === 0) {
4630
- return classPartObject.classGroupId;
4631
- }
4632
- const currentClassPart = classParts[startIndex];
4633
- const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
4634
- if (nextClassPartObject) {
4635
- const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
4636
- if (result) return result;
4637
- }
4638
- const validators = classPartObject.validators;
4639
- if (validators === null) {
4640
- return undefined;
4641
- }
4642
- // Build classRest string efficiently by joining from startIndex onwards
4643
- const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);
4644
- const validatorsLength = validators.length;
4645
- for (let i = 0; i < validatorsLength; i++) {
4646
- const validatorObj = validators[i];
4647
- if (validatorObj.validator(classRest)) {
4648
- return validatorObj.classGroupId;
4649
- }
4650
- }
4651
- return undefined;
4652
- };
4653
- /**
4654
- * Get the class group ID for an arbitrary property.
4655
- *
4656
- * @param className - The class name to get the group ID for. Is expected to be string starting with `[` and ending with `]`.
4657
- */
4658
- const getGroupIdForArbitraryProperty = className => className.slice(1, -1).indexOf(':') === -1 ? undefined : (() => {
4659
- const content = className.slice(1, -1);
4660
- const colonIndex = content.indexOf(':');
4661
- const property = content.slice(0, colonIndex);
4662
- return property ? ARBITRARY_PROPERTY_PREFIX + property : undefined;
4663
- })();
4664
- /**
4665
- * Exported for testing only
4666
- */
4667
- const createClassMap = config => {
4668
- const {
4669
- theme,
4670
- classGroups
4671
- } = config;
4672
- return processClassGroups(classGroups, theme);
4673
- };
4674
- // Split into separate functions to maintain monomorphic call sites
4675
- const processClassGroups = (classGroups, theme) => {
4676
- const classMap = createClassPartObject();
4677
- for (const classGroupId in classGroups) {
4678
- const group = classGroups[classGroupId];
4679
- processClassesRecursively(group, classMap, classGroupId, theme);
4680
- }
4681
- return classMap;
4682
- };
4683
- const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
4684
- const len = classGroup.length;
4685
- for (let i = 0; i < len; i++) {
4686
- const classDefinition = classGroup[i];
4687
- processClassDefinition(classDefinition, classPartObject, classGroupId, theme);
4688
- }
4689
- };
4690
- // Split into separate functions for each type to maintain monomorphic call sites
4691
- const processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4692
- if (typeof classDefinition === 'string') {
4693
- processStringDefinition(classDefinition, classPartObject, classGroupId);
4694
- return;
4695
- }
4696
- if (typeof classDefinition === 'function') {
4697
- processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);
4698
- return;
4699
- }
4700
- processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);
4701
- };
4702
- const processStringDefinition = (classDefinition, classPartObject, classGroupId) => {
4703
- const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);
4704
- classPartObjectToEdit.classGroupId = classGroupId;
4705
- };
4706
- const processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4707
- if (isThemeGetter(classDefinition)) {
4708
- processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
4709
- return;
4710
- }
4711
- if (classPartObject.validators === null) {
4712
- classPartObject.validators = [];
4713
- }
4714
- classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));
4715
- };
4716
- const processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
4717
- const entries = Object.entries(classDefinition);
4718
- const len = entries.length;
4719
- for (let i = 0; i < len; i++) {
4720
- const [key, value] = entries[i];
4721
- processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);
4722
- }
4723
- };
4724
- const getPart = (classPartObject, path) => {
4725
- let current = classPartObject;
4726
- const parts = path.split(CLASS_PART_SEPARATOR);
4727
- const len = parts.length;
4728
- for (let i = 0; i < len; i++) {
4729
- const part = parts[i];
4730
- let next = current.nextPart.get(part);
4731
- if (!next) {
4732
- next = createClassPartObject();
4733
- current.nextPart.set(part, next);
4734
- }
4735
- current = next;
4736
- }
4737
- return current;
4738
- };
4739
- // Type guard maintains monomorphic check
4740
- const isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;
4741
-
4742
- // LRU cache implementation using plain objects for simplicity
4743
- const createLruCache = maxCacheSize => {
4744
- if (maxCacheSize < 1) {
4745
- return {
4746
- get: () => undefined,
4747
- set: () => {}
4748
- };
4749
- }
4750
- let cacheSize = 0;
4751
- let cache = Object.create(null);
4752
- let previousCache = Object.create(null);
4753
- const update = (key, value) => {
4754
- cache[key] = value;
4755
- cacheSize++;
4756
- if (cacheSize > maxCacheSize) {
4757
- cacheSize = 0;
4758
- previousCache = cache;
4759
- cache = Object.create(null);
4760
- }
4761
- };
4762
- return {
4763
- get(key) {
4764
- let value = cache[key];
4765
- if (value !== undefined) {
4766
- return value;
4767
- }
4768
- if ((value = previousCache[key]) !== undefined) {
4769
- update(key, value);
4770
- return value;
4771
- }
4772
- },
4773
- set(key, value) {
4774
- if (key in cache) {
4775
- cache[key] = value;
4776
- } else {
4777
- update(key, value);
4529
+ return {
4530
+ get(key) {
4531
+ let value = cache[key];
4532
+ if (value !== undefined) {
4533
+ return value;
4534
+ }
4535
+ if ((value = previousCache[key]) !== undefined) {
4536
+ update(key, value);
4537
+ return value;
4538
+ }
4539
+ },
4540
+ set(key, value) {
4541
+ if (key in cache) {
4542
+ cache[key] = value;
4543
+ } else {
4544
+ update(key, value);
4778
4545
  }
4779
4546
  }
4780
4547
  };
@@ -4904,15 +4671,27 @@ const createConfigUtils = config => ({
4904
4671
  cache: createLruCache(config.cacheSize),
4905
4672
  parseClassName: createParseClassName(config),
4906
4673
  sortModifiers: createSortModifiers(config),
4674
+ postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),
4907
4675
  ...createClassGroupUtils(config)
4908
4676
  });
4677
+ const createPostfixLookupClassGroupIds = config => {
4678
+ const lookup = Object.create(null);
4679
+ const classGroupIds = config.postfixLookupClassGroups;
4680
+ if (classGroupIds) {
4681
+ for (let i = 0; i < classGroupIds.length; i++) {
4682
+ lookup[classGroupIds[i]] = true;
4683
+ }
4684
+ }
4685
+ return lookup;
4686
+ };
4909
4687
  const SPLIT_CLASSES_REGEX = /\s+/;
4910
4688
  const mergeClassList = (classList, configUtils) => {
4911
4689
  const {
4912
4690
  parseClassName,
4913
4691
  getClassGroupId,
4914
4692
  getConflictingClassGroupIds,
4915
- sortModifiers
4693
+ sortModifiers,
4694
+ postfixLookupClassGroupIds
4916
4695
  } = configUtils;
4917
4696
  /**
4918
4697
  * Set of classGroupIds in following format:
@@ -4938,7 +4717,18 @@ const mergeClassList = (classList, configUtils) => {
4938
4717
  continue;
4939
4718
  }
4940
4719
  let hasPostfixModifier = !!maybePostfixModifierPosition;
4941
- let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
4720
+ let classGroupId;
4721
+ if (hasPostfixModifier) {
4722
+ const baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
4723
+ classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
4724
+ const classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
4725
+ if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
4726
+ classGroupId = classGroupIdWithPostfix;
4727
+ hasPostfixModifier = false;
4728
+ }
4729
+ } else {
4730
+ classGroupId = getClassGroupId(baseClassName);
4731
+ }
4942
4732
  if (!classGroupId) {
4943
4733
  if (!hasPostfixModifier) {
4944
4734
  // Not a Tailwind class
@@ -5043,6 +4833,7 @@ const fallbackThemeArr = [];
5043
4833
  const fromTheme = key => {
5044
4834
  const themeGetter = theme => theme[key] || fallbackThemeArr;
5045
4835
  themeGetter.isThemeGetter = true;
4836
+ themeGetter.themeKey = key;
5046
4837
  return themeGetter;
5047
4838
  };
5048
4839
  const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
@@ -5050,7 +4841,7 @@ const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
5050
4841
  const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
5051
4842
  const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
5052
4843
  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)\(.+\)$/;
4844
+ const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix|color|light-dark)\(.+\)$/;
5054
4845
  // Shadow always begins with x and y offset separated by underscore optionally prepended by inset
5055
4846
  const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
5056
4847
  const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
@@ -5069,6 +4860,7 @@ const isNever = () => false;
5069
4860
  const isShadow = value => shadowRegex.test(value);
5070
4861
  const isImage = value => imageRegex.test(value);
5071
4862
  const isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);
4863
+ 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
4864
  const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);
5073
4865
  const isArbitraryValue = value => arbitraryValueRegex.test(value);
5074
4866
  const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
@@ -5173,7 +4965,7 @@ const getDefaultConfig = () => {
5173
4965
  const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
5174
4966
  const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
5175
4967
  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()];
4968
+ const scaleSizingInline = () => [themeContainer, isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5177
4969
  const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
5178
4970
  const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
5179
4971
  const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
@@ -5240,12 +5032,24 @@ const getDefaultConfig = () => {
5240
5032
  * @deprecated since Tailwind CSS v4.0.0
5241
5033
  */
5242
5034
  container: ['container'],
5035
+ /**
5036
+ * Container Type
5037
+ * @see https://tailwindcss.com/docs/responsive-design#container-queries
5038
+ */
5039
+ 'container-type': [{
5040
+ '@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
5041
+ }],
5042
+ /**
5043
+ * Container Name
5044
+ * @see https://tailwindcss.com/docs/responsive-design#named-containers
5045
+ */
5046
+ 'container-named': [isNamedContainerQuery],
5243
5047
  /**
5244
5048
  * Columns
5245
5049
  * @see https://tailwindcss.com/docs/columns
5246
5050
  */
5247
5051
  columns: [{
5248
- columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer]
5052
+ columns: [isNumber, 'auto', isArbitraryValue, isArbitraryVariable, themeContainer]
5249
5053
  }],
5250
5054
  /**
5251
5055
  * Break After
@@ -5881,42 +5685,42 @@ const getDefaultConfig = () => {
5881
5685
  }],
5882
5686
  /**
5883
5687
  * Inline Size
5884
- * @see https://tailwindcss.com/docs/width
5688
+ * @see https://tailwindcss.com/docs/inline-size
5885
5689
  */
5886
5690
  'inline-size': [{
5887
5691
  inline: ['auto', ...scaleSizingInline()]
5888
5692
  }],
5889
5693
  /**
5890
5694
  * Min-Inline Size
5891
- * @see https://tailwindcss.com/docs/min-width
5695
+ * @see https://tailwindcss.com/docs/min-inline-size
5892
5696
  */
5893
5697
  'min-inline-size': [{
5894
5698
  'min-inline': ['auto', ...scaleSizingInline()]
5895
5699
  }],
5896
5700
  /**
5897
5701
  * Max-Inline Size
5898
- * @see https://tailwindcss.com/docs/max-width
5702
+ * @see https://tailwindcss.com/docs/max-inline-size
5899
5703
  */
5900
5704
  'max-inline-size': [{
5901
5705
  'max-inline': ['none', ...scaleSizingInline()]
5902
5706
  }],
5903
5707
  /**
5904
5708
  * Block Size
5905
- * @see https://tailwindcss.com/docs/height
5709
+ * @see https://tailwindcss.com/docs/block-size
5906
5710
  */
5907
5711
  'block-size': [{
5908
5712
  block: ['auto', ...scaleSizingBlock()]
5909
5713
  }],
5910
5714
  /**
5911
5715
  * Min-Block Size
5912
- * @see https://tailwindcss.com/docs/min-height
5716
+ * @see https://tailwindcss.com/docs/min-block-size
5913
5717
  */
5914
5718
  'min-block-size': [{
5915
5719
  'min-block': ['auto', ...scaleSizingBlock()]
5916
5720
  }],
5917
5721
  /**
5918
5722
  * Max-Block Size
5919
- * @see https://tailwindcss.com/docs/max-height
5723
+ * @see https://tailwindcss.com/docs/max-block-size
5920
5724
  */
5921
5725
  'max-block-size': [{
5922
5726
  'max-block': ['none', ...scaleSizingBlock()]
@@ -5966,7 +5770,7 @@ const getDefaultConfig = () => {
5966
5770
  * @see https://tailwindcss.com/docs/max-height
5967
5771
  */
5968
5772
  'max-h': [{
5969
- 'max-h': ['screen', 'lh', ...scaleSizing()]
5773
+ 'max-h': ['screen', 'lh', 'none', ...scaleSizing()]
5970
5774
  }],
5971
5775
  // ------------------
5972
5776
  // --- Typography ---
@@ -6065,7 +5869,7 @@ const getDefaultConfig = () => {
6065
5869
  * @see https://tailwindcss.com/docs/line-height
6066
5870
  */
6067
5871
  leading: [{
6068
- leading: [/** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
5872
+ leading: ['none', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
6069
5873
  themeLeading, ...scaleUnambiguousSpacing()]
6070
5874
  }],
6071
5875
  /**
@@ -6168,6 +5972,13 @@ const getDefaultConfig = () => {
6168
5972
  indent: [{
6169
5973
  indent: scaleUnambiguousSpacing()
6170
5974
  }],
5975
+ /**
5976
+ * Tab Size
5977
+ * @see https://tailwindcss.com/docs/tab-size
5978
+ */
5979
+ 'tab-size': [{
5980
+ tab: [isInteger, isArbitraryVariable, isArbitraryValue]
5981
+ }],
6171
5982
  /**
6172
5983
  * Vertical Alignment
6173
5984
  * @see https://tailwindcss.com/docs/vertical-align
@@ -6265,7 +6076,7 @@ const getDefaultConfig = () => {
6265
6076
  to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']
6266
6077
  }, isInteger, isArbitraryVariable, isArbitraryValue],
6267
6078
  radial: ['', isArbitraryVariable, isArbitraryValue],
6268
- conic: [isInteger, isArbitraryVariable, isArbitraryValue]
6079
+ conic: ['', isInteger, isArbitraryVariable, isArbitraryValue]
6269
6080
  }, isArbitraryVariableImage, isArbitraryImage]
6270
6081
  }],
6271
6082
  /**
@@ -6662,7 +6473,9 @@ const getDefaultConfig = () => {
6662
6473
  shadow: [{
6663
6474
  shadow: [
6664
6475
  // Deprecated since Tailwind CSS v4.0.0
6665
- '', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]
6476
+ '',
6477
+ // Deprecated since Tailwind CSS v4.0.0
6478
+ 'inner', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]
6666
6479
  }],
6667
6480
  /**
6668
6481
  * Box Shadow Color
@@ -7375,6 +7188,13 @@ const getDefaultConfig = () => {
7375
7188
  * @see https://tailwindcss.com/docs/translate
7376
7189
  */
7377
7190
  'translate-none': ['translate-none'],
7191
+ /**
7192
+ * Zoom
7193
+ * @see https://tailwindcss.com/docs/zoom
7194
+ */
7195
+ zoom: [{
7196
+ zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
7197
+ }],
7378
7198
  // ---------------------
7379
7199
  // --- Interactivity ---
7380
7200
  // ---------------------
@@ -7441,6 +7261,34 @@ const getDefaultConfig = () => {
7441
7261
  'scroll-behavior': [{
7442
7262
  scroll: ['auto', 'smooth']
7443
7263
  }],
7264
+ /**
7265
+ * Scrollbar Thumb Color
7266
+ * @see https://tailwindcss.com/docs/scrollbar-color
7267
+ */
7268
+ 'scrollbar-thumb-color': [{
7269
+ 'scrollbar-thumb': scaleColor()
7270
+ }],
7271
+ /**
7272
+ * Scrollbar Track Color
7273
+ * @see https://tailwindcss.com/docs/scrollbar-color
7274
+ */
7275
+ 'scrollbar-track-color': [{
7276
+ 'scrollbar-track': scaleColor()
7277
+ }],
7278
+ /**
7279
+ * Scrollbar Gutter
7280
+ * @see https://tailwindcss.com/docs/scrollbar-gutter
7281
+ */
7282
+ 'scrollbar-gutter': [{
7283
+ 'scrollbar-gutter': ['auto', 'stable', 'both']
7284
+ }],
7285
+ /**
7286
+ * Scrollbar Width
7287
+ * @see https://tailwindcss.com/docs/scrollbar-width
7288
+ */
7289
+ 'scrollbar-w': [{
7290
+ scrollbar: ['auto', 'thin', 'none']
7291
+ }],
7444
7292
  /**
7445
7293
  * Scroll Margin
7446
7294
  * @see https://tailwindcss.com/docs/scroll-margin
@@ -7699,19 +7547,20 @@ const getDefaultConfig = () => {
7699
7547
  }]
7700
7548
  },
7701
7549
  conflictingClassGroups: {
7550
+ 'container-named': ['container-type'],
7702
7551
  overflow: ['overflow-x', 'overflow-y'],
7703
7552
  overscroll: ['overscroll-x', 'overscroll-y'],
7704
7553
  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'],
7554
+ 'inset-x': ['start', 'end', 'right', 'left'],
7555
+ 'inset-y': ['inset-bs', 'inset-be', 'top', 'bottom'],
7707
7556
  flex: ['basis', 'grow', 'shrink'],
7708
7557
  gap: ['gap-x', 'gap-y'],
7709
7558
  p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
7710
- px: ['pr', 'pl'],
7711
- py: ['pt', 'pb'],
7559
+ px: ['ps', 'pe', 'pr', 'pl'],
7560
+ py: ['pbs', 'pbe', 'pt', 'pb'],
7712
7561
  m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
7713
- mx: ['mr', 'ml'],
7714
- my: ['mt', 'mb'],
7562
+ mx: ['ms', 'me', 'mr', 'ml'],
7563
+ my: ['mbs', 'mbe', 'mt', 'mb'],
7715
7564
  size: ['w', 'h'],
7716
7565
  'font-size': ['leading'],
7717
7566
  'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],
@@ -7730,19 +7579,19 @@ const getDefaultConfig = () => {
7730
7579
  'rounded-l': ['rounded-tl', 'rounded-bl'],
7731
7580
  'border-spacing': ['border-spacing-x', 'border-spacing-y'],
7732
7581
  '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'],
7582
+ 'border-w-x': ['border-w-s', 'border-w-e', 'border-w-r', 'border-w-l'],
7583
+ 'border-w-y': ['border-w-bs', 'border-w-be', 'border-w-t', 'border-w-b'],
7735
7584
  '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'],
7585
+ 'border-color-x': ['border-color-s', 'border-color-e', 'border-color-r', 'border-color-l'],
7586
+ 'border-color-y': ['border-color-bs', 'border-color-be', 'border-color-t', 'border-color-b'],
7738
7587
  translate: ['translate-x', 'translate-y', 'translate-none'],
7739
7588
  'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
7740
7589
  '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'],
7590
+ 'scroll-mx': ['scroll-ms', 'scroll-me', 'scroll-mr', 'scroll-ml'],
7591
+ 'scroll-my': ['scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mb'],
7743
7592
  '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'],
7593
+ 'scroll-px': ['scroll-ps', 'scroll-pe', 'scroll-pr', 'scroll-pl'],
7594
+ 'scroll-py': ['scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pb'],
7746
7595
  touch: ['touch-x', 'touch-y', 'touch-pz'],
7747
7596
  'touch-x': ['touch'],
7748
7597
  'touch-y': ['touch'],
@@ -7751,485 +7600,663 @@ const getDefaultConfig = () => {
7751
7600
  conflictingClassGroupModifiers: {
7752
7601
  'font-size': ['leading']
7753
7602
  },
7603
+ postfixLookupClassGroups: ['container-type'],
7754
7604
  orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
7755
7605
  };
7756
7606
  };
7757
7607
  const twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);
7758
7608
 
7759
- function cn(...inputs) {
7760
- return twMerge(clsx(inputs));
7761
- }
7609
+ function cn(...inputs) {
7610
+ return twMerge(clsx(inputs));
7611
+ }
7612
+
7613
+ /**
7614
+ * Get icon for tenant type
7615
+ */
7616
+ function getTenantIcon(type) {
7617
+ switch (type) {
7618
+ case "organization":
7619
+ 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" }) }));
7620
+ case "project":
7621
+ 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" }) }));
7622
+ case "user":
7623
+ 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" }) }));
7624
+ case "platform":
7625
+ 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" }) }));
7626
+ default:
7627
+ return null;
7628
+ }
7629
+ }
7630
+ /**
7631
+ * Get badge variant based on tenant type
7632
+ */
7633
+ function getTenantBadgeVariant(type) {
7634
+ switch (type) {
7635
+ case "organization":
7636
+ return "default";
7637
+ case "project":
7638
+ return "secondary";
7639
+ case "user":
7640
+ return "default";
7641
+ case "platform":
7642
+ return "default";
7643
+ default:
7644
+ return "secondary";
7645
+ }
7646
+ }
7647
+ /**
7648
+ * TenantBadge displays tenant information in a compact badge format
7649
+ * Renders as a clickable link if tenantLinkResolver is provided and returns a URL
7650
+ */
7651
+ function TenantBadge({ tenant, tenantLinkResolver, className = "", size = "default", }) {
7652
+ const icon = getTenantIcon(tenant.type);
7653
+ const variant = getTenantBadgeVariant(tenant.type);
7654
+ const url = tenantLinkResolver?.(tenant);
7655
+ 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 })] }))] }));
7656
+ if (url) {
7657
+ return (jsxRuntime.jsx("a", { href: url, className: "no-underline", onClick: (e) => e.stopPropagation(), title: `View ${tenant.type}: ${tenant.name}`, children: badgeContent }));
7658
+ }
7659
+ return badgeContent;
7660
+ }
7661
+
7662
+ /**
7663
+ * Extract tenant information from audit event annotations if present
7664
+ * Expected annotations: tenant.type and tenant.name
7665
+ */
7666
+ function extractTenantFromAnnotations(event) {
7667
+ const annotations = event.annotations;
7668
+ if (!annotations)
7669
+ return undefined;
7670
+ const tenantType = annotations["tenant.type"];
7671
+ const tenantName = annotations["tenant.name"];
7672
+ if (tenantType && tenantName) {
7673
+ const validTypes = [
7674
+ "platform",
7675
+ "organization",
7676
+ "project",
7677
+ "user",
7678
+ ];
7679
+ if (validTypes.includes(tenantType)) {
7680
+ return {
7681
+ type: tenantType,
7682
+ name: tenantName,
7683
+ };
7684
+ }
7685
+ }
7686
+ return undefined;
7687
+ }
7688
+ /**
7689
+ * AuditEventViewer displays a list of audit events with details
7690
+ */
7691
+ function AuditEventViewer({ events, className = "", onEventSelect, tenantLinkResolver, }) {
7692
+ const [selectedEvent, setSelectedEvent] = React.useState(null);
7693
+ const [expandedEvents, setExpandedEvents] = React.useState(new Set());
7694
+ const toggleEventExpansion = (auditId) => {
7695
+ const newExpanded = new Set(expandedEvents);
7696
+ if (expandedEvents.has(auditId)) {
7697
+ newExpanded.delete(auditId);
7698
+ }
7699
+ else {
7700
+ newExpanded.add(auditId);
7701
+ }
7702
+ setExpandedEvents(newExpanded);
7703
+ };
7704
+ const handleEventClick = (event) => {
7705
+ setSelectedEvent(event);
7706
+ if (onEventSelect) {
7707
+ onEventSelect(event);
7708
+ }
7709
+ };
7710
+ const formatTimestamp = (timestamp) => {
7711
+ if (!timestamp)
7712
+ return "N/A";
7713
+ try {
7714
+ return format(new Date(timestamp), "yyyy-MM-dd HH:mm:ss");
7715
+ }
7716
+ catch {
7717
+ return timestamp;
7718
+ }
7719
+ };
7720
+ const getVerbBadgeVariant = (verb) => {
7721
+ switch (verb?.toLowerCase()) {
7722
+ case "create":
7723
+ return "success";
7724
+ case "update":
7725
+ case "patch":
7726
+ return "warning";
7727
+ case "delete":
7728
+ return "destructive";
7729
+ case "get":
7730
+ case "list":
7731
+ case "watch":
7732
+ return "default";
7733
+ default:
7734
+ return "secondary";
7735
+ }
7736
+ };
7737
+ if (events.length === 0) {
7738
+ 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" }) }));
7739
+ }
7740
+ return (jsxRuntime.jsx("div", { className: `bg-muted rounded-lg border border-border ${className}`, children: jsxRuntime.jsx("div", { className: "p-4", children: events.map((event) => {
7741
+ const auditId = event.auditID || "";
7742
+ const isExpanded = expandedEvents.has(auditId);
7743
+ const tenant = extractTenantFromAnnotations(event);
7744
+ 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
7745
+ ? "border-primary bg-primary/5 shadow-md"
7746
+ : ""}`, 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) => {
7747
+ e.stopPropagation();
7748
+ toggleEventExpansion(auditId);
7749
+ }, 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 &&
7750
+ 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));
7751
+ }) }) }));
7752
+ }
7753
+
7754
+ /**
7755
+ * @license lucide-react v0.577.0 - ISC
7756
+ *
7757
+ * This source code is licensed under the ISC license.
7758
+ * See the LICENSE file in the root directory of this source tree.
7759
+ */
7760
+
7761
+ const mergeClasses = (...classes) => classes.filter((className, index, array) => {
7762
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
7763
+ }).join(" ").trim();
7764
+
7765
+ /**
7766
+ * @license lucide-react v0.577.0 - ISC
7767
+ *
7768
+ * This source code is licensed under the ISC license.
7769
+ * See the LICENSE file in the root directory of this source tree.
7770
+ */
7771
+
7772
+ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
7773
+
7774
+ /**
7775
+ * @license lucide-react v0.577.0 - ISC
7776
+ *
7777
+ * This source code is licensed under the ISC license.
7778
+ * See the LICENSE file in the root directory of this source tree.
7779
+ */
7780
+
7781
+ const toCamelCase = (string) => string.replace(
7782
+ /^([A-Z])|[\s-_]+(\w)/g,
7783
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
7784
+ );
7785
+
7786
+ /**
7787
+ * @license lucide-react v0.577.0 - ISC
7788
+ *
7789
+ * This source code is licensed under the ISC license.
7790
+ * See the LICENSE file in the root directory of this source tree.
7791
+ */
7792
+
7793
+
7794
+ const toPascalCase = (string) => {
7795
+ const camelCase = toCamelCase(string);
7796
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
7797
+ };
7798
+
7799
+ /**
7800
+ * @license lucide-react v0.577.0 - ISC
7801
+ *
7802
+ * This source code is licensed under the ISC license.
7803
+ * See the LICENSE file in the root directory of this source tree.
7804
+ */
7805
+
7806
+ var defaultAttributes = {
7807
+ xmlns: "http://www.w3.org/2000/svg",
7808
+ width: 24,
7809
+ height: 24,
7810
+ viewBox: "0 0 24 24",
7811
+ fill: "none",
7812
+ stroke: "currentColor",
7813
+ strokeWidth: 2,
7814
+ strokeLinecap: "round",
7815
+ strokeLinejoin: "round"
7816
+ };
7817
+
7818
+ /**
7819
+ * @license lucide-react v0.577.0 - ISC
7820
+ *
7821
+ * This source code is licensed under the ISC license.
7822
+ * See the LICENSE file in the root directory of this source tree.
7823
+ */
7824
+
7825
+ const hasA11yProp = (props) => {
7826
+ for (const prop in props) {
7827
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
7828
+ return true;
7829
+ }
7830
+ }
7831
+ return false;
7832
+ };
7833
+
7834
+ /**
7835
+ * @license lucide-react v0.577.0 - ISC
7836
+ *
7837
+ * This source code is licensed under the ISC license.
7838
+ * See the LICENSE file in the root directory of this source tree.
7839
+ */
7840
+
7841
+
7842
+ const Icon = React.forwardRef(
7843
+ ({
7844
+ color = "currentColor",
7845
+ size = 24,
7846
+ strokeWidth = 2,
7847
+ absoluteStrokeWidth,
7848
+ className = "",
7849
+ children,
7850
+ iconNode,
7851
+ ...rest
7852
+ }, ref) => React.createElement(
7853
+ "svg",
7854
+ {
7855
+ ref,
7856
+ ...defaultAttributes,
7857
+ width: size,
7858
+ height: size,
7859
+ stroke: color,
7860
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
7861
+ className: mergeClasses("lucide", className),
7862
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
7863
+ ...rest
7864
+ },
7865
+ [
7866
+ ...iconNode.map(([tag, attrs]) => React.createElement(tag, attrs)),
7867
+ ...Array.isArray(children) ? children : [children]
7868
+ ]
7869
+ )
7870
+ );
7871
+
7872
+ /**
7873
+ * @license lucide-react v0.577.0 - ISC
7874
+ *
7875
+ * This source code is licensed under the ISC license.
7876
+ * See the LICENSE file in the root directory of this source tree.
7877
+ */
7878
+
7879
+
7880
+ const createLucideIcon = (iconName, iconNode) => {
7881
+ const Component = React.forwardRef(
7882
+ ({ className, ...props }, ref) => React.createElement(Icon, {
7883
+ ref,
7884
+ iconNode,
7885
+ className: mergeClasses(
7886
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
7887
+ `lucide-${iconName}`,
7888
+ className
7889
+ ),
7890
+ ...props
7891
+ })
7892
+ );
7893
+ Component.displayName = toPascalCase(iconName);
7894
+ return Component;
7895
+ };
7896
+
7897
+ /**
7898
+ * @license lucide-react v0.577.0 - ISC
7899
+ *
7900
+ * This source code is licensed under the ISC license.
7901
+ * See the LICENSE file in the root directory of this source tree.
7902
+ */
7903
+
7904
+
7905
+ const __iconNode$n = [
7906
+ [
7907
+ "path",
7908
+ {
7909
+ 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",
7910
+ key: "169zse"
7911
+ }
7912
+ ]
7913
+ ];
7914
+ const Activity = createLucideIcon("activity", __iconNode$n);
7915
+
7916
+ /**
7917
+ * @license lucide-react v0.577.0 - ISC
7918
+ *
7919
+ * This source code is licensed under the ISC license.
7920
+ * See the LICENSE file in the root directory of this source tree.
7921
+ */
7922
+
7923
+
7924
+ const __iconNode$m = [
7925
+ ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
7926
+ [
7927
+ "path",
7928
+ {
7929
+ 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",
7930
+ key: "11g9vi"
7931
+ }
7932
+ ]
7933
+ ];
7934
+ const Bell = createLucideIcon("bell", __iconNode$m);
7762
7935
 
7763
7936
  /**
7764
- * Combobox component with type-ahead search and fuzzy matching.
7765
- * Built on cmdk for search functionality and Radix Popover for positioning.
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.
7766
7941
  */
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
- }
7942
+
7943
+
7944
+ const __iconNode$l = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
7945
+ const Check = createLucideIcon("check", __iconNode$l);
7822
7946
 
7823
7947
  /**
7824
- * TimeRangeDropdown - A compact dropdown for selecting time ranges
7948
+ * @license lucide-react v0.577.0 - ISC
7949
+ *
7950
+ * This source code is licensed under the ISC license.
7951
+ * See the LICENSE file in the root directory of this source tree.
7825
7952
  */
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
7953
 
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
- },
7954
+
7955
+ const __iconNode$k = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
7956
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$k);
7957
+
7958
+ /**
7959
+ * @license lucide-react v0.577.0 - ISC
7960
+ *
7961
+ * This source code is licensed under the ISC license.
7962
+ * See the LICENSE file in the root directory of this source tree.
7963
+ */
7964
+
7965
+
7966
+ const __iconNode$j = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
7967
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$j);
7968
+
7969
+ /**
7970
+ * @license lucide-react v0.577.0 - ISC
7971
+ *
7972
+ * This source code is licensed under the ISC license.
7973
+ * See the LICENSE file in the root directory of this source tree.
7974
+ */
7975
+
7976
+
7977
+ const __iconNode$i = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
7978
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$i);
7979
+
7980
+ /**
7981
+ * @license lucide-react v0.577.0 - ISC
7982
+ *
7983
+ * This source code is licensed under the ISC license.
7984
+ * See the LICENSE file in the root directory of this source tree.
7985
+ */
7986
+
7987
+
7988
+ const __iconNode$h = [
7989
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
7990
+ ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
7991
+ ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
7992
+ ];
7993
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$h);
7994
+
7995
+ /**
7996
+ * @license lucide-react v0.577.0 - ISC
7997
+ *
7998
+ * This source code is licensed under the ISC license.
7999
+ * See the LICENSE file in the root directory of this source tree.
8000
+ */
8001
+
8002
+
8003
+ const __iconNode$g = [
8004
+ ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
8005
+ ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
8006
+ ];
8007
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$g);
8008
+
8009
+ /**
8010
+ * @license lucide-react v0.577.0 - ISC
8011
+ *
8012
+ * This source code is licensed under the ISC license.
8013
+ * See the LICENSE file in the root directory of this source tree.
8014
+ */
8015
+
8016
+
8017
+ const __iconNode$f = [
8018
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8019
+ ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
8020
+ ];
8021
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$f);
8022
+
8023
+ /**
8024
+ * @license lucide-react v0.577.0 - ISC
8025
+ *
8026
+ * This source code is licensed under the ISC license.
8027
+ * See the LICENSE file in the root directory of this source tree.
8028
+ */
8029
+
8030
+
8031
+ const __iconNode$e = [
8032
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8033
+ ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
8034
+ ["path", { d: "m9 9 6 6", key: "z0biqf" }]
8035
+ ];
8036
+ const CircleX = createLucideIcon("circle-x", __iconNode$e);
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$d = [
8047
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
8048
+ ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
8049
+ ];
8050
+ const Clock = createLucideIcon("clock", __iconNode$d);
8051
+
8052
+ /**
8053
+ * @license lucide-react v0.577.0 - ISC
8054
+ *
8055
+ * This source code is licensed under the ISC license.
8056
+ * See the LICENSE file in the root directory of this source tree.
8057
+ */
8058
+
8059
+
8060
+ const __iconNode$c = [
8061
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
8062
+ ["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" }]
8063
+ ];
8064
+ const Copy = createLucideIcon("copy", __iconNode$c);
8065
+
8066
+ /**
8067
+ * @license lucide-react v0.577.0 - ISC
8068
+ *
8069
+ * This source code is licensed under the ISC license.
8070
+ * See the LICENSE file in the root directory of this source tree.
8071
+ */
8072
+
8073
+
8074
+ const __iconNode$b = [
8075
+ [
8076
+ "path",
7894
8077
  {
7895
- key: 'last7days',
7896
- label: 'Last 7 days',
7897
- getValue: () => ({
7898
- start: formatISO(subDays(new Date(), 7)),
7899
- end: formatISO(new Date()),
7900
- }),
7901
- },
8078
+ 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",
8079
+ key: "1nclc0"
8080
+ }
8081
+ ],
8082
+ ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
8083
+ ];
8084
+ const Eye = createLucideIcon("eye", __iconNode$b);
8085
+
8086
+ /**
8087
+ * @license lucide-react v0.577.0 - ISC
8088
+ *
8089
+ * This source code is licensed under the ISC license.
8090
+ * See the LICENSE file in the root directory of this source tree.
8091
+ */
8092
+
8093
+
8094
+ const __iconNode$a = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
8095
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$a);
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$9 = [
8106
+ [
8107
+ "path",
7902
8108
  {
7903
- key: 'last30days',
7904
- label: 'Last 30 days',
7905
- getValue: () => ({
7906
- start: formatISO(subDays(new Date(), 30)),
7907
- end: formatISO(new Date()),
7908
- }),
7909
- },
8109
+ 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",
8110
+ key: "1a8usu"
8111
+ }
8112
+ ],
8113
+ ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
7910
8114
  ];
7911
- /** Debounce delay for text inputs (ms) */
7912
- const DEBOUNCE_DELAY = 300;
8115
+ const Pencil = createLucideIcon("pencil", __iconNode$9);
8116
+
7913
8117
  /**
7914
- * Helper function to convert ISO string to datetime-local format
8118
+ * @license lucide-react v0.577.0 - ISC
8119
+ *
8120
+ * This source code is licensed under the ISC license.
8121
+ * See the LICENSE file in the root directory of this source tree.
7915
8122
  */
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
- }
8123
+
8124
+
8125
+ const __iconNode$8 = [
8126
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
8127
+ ["path", { d: "M12 5v14", key: "s699le" }]
8128
+ ];
8129
+ const Plus = createLucideIcon("plus", __iconNode$8);
8092
8130
 
8093
8131
  /**
8094
- * Get icon for tenant type
8132
+ * @license lucide-react v0.577.0 - ISC
8133
+ *
8134
+ * This source code is licensed under the ISC license.
8135
+ * See the LICENSE file in the root directory of this source tree.
8095
8136
  */
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
- }
8137
+
8138
+
8139
+ const __iconNode$7 = [
8140
+ ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
8141
+ ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
8142
+ ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
8143
+ ["path", { d: "M8 16H3v5", key: "1cv678" }]
8144
+ ];
8145
+ const RefreshCw = createLucideIcon("refresh-cw", __iconNode$7);
8146
+
8147
+ /**
8148
+ * @license lucide-react v0.577.0 - ISC
8149
+ *
8150
+ * This source code is licensed under the ISC license.
8151
+ * See the LICENSE file in the root directory of this source tree.
8152
+ */
8153
+
8154
+
8155
+ const __iconNode$6 = [
8156
+ ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
8157
+ ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
8158
+ ];
8159
+ const RotateCw = createLucideIcon("rotate-cw", __iconNode$6);
8160
+
8161
+ /**
8162
+ * @license lucide-react v0.577.0 - ISC
8163
+ *
8164
+ * This source code is licensed under the ISC license.
8165
+ * See the LICENSE file in the root directory of this source tree.
8166
+ */
8167
+
8168
+
8169
+ const __iconNode$5 = [
8170
+ ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
8171
+ ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
8172
+ ];
8173
+ const Search = createLucideIcon("search", __iconNode$5);
8174
+
8110
8175
  /**
8111
- * Get badge variant based on tenant type
8176
+ * @license lucide-react v0.577.0 - ISC
8177
+ *
8178
+ * This source code is licensed under the ISC license.
8179
+ * See the LICENSE file in the root directory of this source tree.
8112
8180
  */
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";
8181
+
8182
+
8183
+ const __iconNode$4 = [
8184
+ ["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" }],
8185
+ [
8186
+ "path",
8187
+ {
8188
+ 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",
8189
+ key: "ohrbg2"
8125
8190
  }
8126
- }
8191
+ ]
8192
+ ];
8193
+ const SquarePen = createLucideIcon("square-pen", __iconNode$4);
8194
+
8127
8195
  /**
8128
- * TenantBadge displays tenant information in a compact badge format
8129
- * Renders as a clickable link if tenantLinkResolver is provided and returns a URL
8196
+ * @license lucide-react v0.577.0 - ISC
8197
+ *
8198
+ * This source code is licensed under the ISC license.
8199
+ * See the LICENSE file in the root directory of this source tree.
8130
8200
  */
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 }));
8138
- }
8139
- return badgeContent;
8140
- }
8201
+
8202
+
8203
+ const __iconNode$3 = [
8204
+ ["path", { d: "M10 11v6", key: "nco0om" }],
8205
+ ["path", { d: "M14 11v6", key: "outv1u" }],
8206
+ ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
8207
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
8208
+ ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
8209
+ ];
8210
+ const Trash2 = createLucideIcon("trash-2", __iconNode$3);
8141
8211
 
8142
8212
  /**
8143
- * Extract tenant information from audit event annotations if present
8144
- * Expected annotations: tenant.type and tenant.name
8213
+ * @license lucide-react v0.577.0 - ISC
8214
+ *
8215
+ * This source code is licensed under the ISC license.
8216
+ * See the LICENSE file in the root directory of this source tree.
8145
8217
  */
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
- }
8218
+
8219
+
8220
+ const __iconNode$2 = [
8221
+ [
8222
+ "path",
8223
+ {
8224
+ 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",
8225
+ key: "wmoenq"
8165
8226
  }
8166
- return undefined;
8167
- }
8227
+ ],
8228
+ ["path", { d: "M12 9v4", key: "juzpu7" }],
8229
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
8230
+ ];
8231
+ const TriangleAlert = createLucideIcon("triangle-alert", __iconNode$2);
8232
+
8168
8233
  /**
8169
- * AuditEventViewer displays a list of audit events with details
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$1 = [
8242
+ ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
8243
+ ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
8244
+ ];
8245
+ const User = createLucideIcon("user", __iconNode$1);
8246
+
8247
+ /**
8248
+ * @license lucide-react v0.577.0 - ISC
8249
+ *
8250
+ * This source code is licensed under the ISC license.
8251
+ * See the LICENSE file in the root directory of this source tree.
8170
8252
  */
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" }) }));
8219
- }
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
- }
8253
+
8254
+
8255
+ const __iconNode = [
8256
+ ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
8257
+ ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
8258
+ ];
8259
+ const X = createLucideIcon("x", __iconNode);
8233
8260
 
8234
8261
  /**
8235
8262
  * FilterChip - A compact pill/chip showing "Label: Values" with clear button
@@ -8354,7 +8381,7 @@ function FilterChip({ label, values, options = [], onValuesChange, onClear, inpu
8354
8381
  }, [options]);
8355
8382
  // Find selected options for chips display
8356
8383
  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" }) })] }));
8384
+ 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
8385
  }
8359
8386
 
8360
8387
  /**
@@ -8371,12 +8398,12 @@ function AddFilterDropdown({ availableFilters, activeFilterIds, onAddFilter, has
8371
8398
  const isFilterActive = (filterId) => activeFilterIds.includes(filterId);
8372
8399
  // Get button label
8373
8400
  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
- }) }) }) })] }));
8401
+ 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) => {
8402
+ const active = isFilterActive(filter.id);
8403
+ 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
8404
+ ? 'cursor-not-allowed opacity-40'
8405
+ : '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));
8406
+ }) }) })] }));
8380
8407
  }
8381
8408
 
8382
8409
  /**
@@ -8400,10 +8427,10 @@ function ActionMultiSelect({ value, onChange, className = '', disabled = false,
8400
8427
  return '1 action';
8401
8428
  return `${value.length} actions`;
8402
8429
  }, [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
- })) }) }) })] }));
8430
+ 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) => {
8431
+ const checked = value.includes(option.value);
8432
+ 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));
8433
+ })) }) })] }));
8407
8434
  }
8408
8435
 
8409
8436
  /**
@@ -8435,7 +8462,7 @@ function UserSelect({ value, options, onChange, className = '', disabled = false
8435
8462
  e.stopPropagation();
8436
8463
  onChange(undefined);
8437
8464
  }, [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" }))] })] }) })] }));
8465
+ 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
8466
  }
8440
8467
 
8441
8468
  /**
@@ -8782,7 +8809,7 @@ function AuditLogFilters({ client, filters, timeRange, onFiltersChange, onTimeRa
8782
8809
  label: facet.value,
8783
8810
  count: facet.count,
8784
8811
  }));
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) => {
8812
+ 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
8813
  const config = FILTER_CONFIGS$2[filterId];
8787
8814
  return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === "typeahead"
8788
8815
  ? getFilterOptions(filterId)
@@ -8918,7 +8945,7 @@ function CopyButton({ value, label }) {
8918
8945
  console.error('Failed to copy:', err);
8919
8946
  }
8920
8947
  };
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}` }) })] }));
8948
+ 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
8949
  }
8923
8950
  /**
8924
8951
  * A label / value row inside a Section. The value is truncated to one
@@ -8996,8 +9023,8 @@ function AuditLogExpandedDetails({ event, compact = true }) {
8996
9023
  const status = event.responseStatus;
8997
9024
  const isOk = status?.code != null && status.code >= 200 && status.code < 300;
8998
9025
  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 ||
9026
+ ? 'text-[var(--success-500)]'
9027
+ : '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
9028
  (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
9029
  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
9030
  }
@@ -9005,22 +9032,21 @@ function AuditLogExpandedDetails({ event, compact = true }) {
9005
9032
  // Number of columns rendered for the audit log table. Used by the colSpan
9006
9033
  // on the expanded-detail row so it spans the full width.
9007
9034
  const AUDIT_LOG_COLUMN_COUNT = 5;
9035
+ const VERB_BADGE_CLASSES = 'text-[0.55rem] h-5 px-2 py-1 leading-3';
9008
9036
  /**
9009
- * Get Tailwind classes for verb badge
9037
+ * Get the badge variant for a verb
9010
9038
  */
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) {
9039
+ function getVerbBadgeVariant(verb) {
9040
+ switch (verb?.toLowerCase()) {
9015
9041
  case 'create':
9016
- return cn(baseClasses, 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300');
9042
+ return 'success';
9017
9043
  case 'update':
9018
9044
  case 'patch':
9019
- return cn(baseClasses, 'bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300');
9045
+ return 'warning';
9020
9046
  case 'delete':
9021
- return cn(baseClasses, 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300');
9047
+ return 'destructive';
9022
9048
  default:
9023
- return cn(baseClasses, 'bg-muted text-muted-foreground');
9049
+ return 'outline';
9024
9050
  }
9025
9051
  }
9026
9052
  /**
@@ -9031,9 +9057,9 @@ function getResponseStatusIndicator(code) {
9031
9057
  return { icon: '?', className: 'text-muted-foreground' };
9032
9058
  }
9033
9059
  if (code >= 200 && code < 300) {
9034
- return { icon: '✓', className: 'text-green-600 dark:text-green-400' };
9060
+ return { icon: '✓', className: 'text-[var(--success-500)]' };
9035
9061
  }
9036
- return { icon: '✗', className: 'text-red-600 dark:text-red-400' };
9062
+ return { icon: '✗', className: 'text-destructive' };
9037
9063
  }
9038
9064
  /**
9039
9065
  * Build human-readable summary
@@ -9074,14 +9100,14 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9074
9100
  verb === 'delete' ? Trash2 :
9075
9101
  verb === 'update' || verb === 'patch' ? Pencil :
9076
9102
  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';
9103
+ const iconBg = verb === 'create' ? 'bg-[var(--success-100)]' :
9104
+ verb === 'delete' ? 'bg-destructive/10' :
9105
+ verb === 'update' || verb === 'patch' ? 'bg-[color-mix(in_oklab,var(--badge-warning)_15%,transparent)]' :
9106
+ 'bg-muted';
9107
+ const iconColor = verb === 'create' ? 'text-[var(--success-500)]' :
9108
+ verb === 'delete' ? 'text-destructive' :
9109
+ verb === 'update' || verb === 'patch' ? 'text-[var(--badge-warning)]' :
9110
+ 'text-muted-foreground';
9085
9111
  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
9112
  display: 'block',
9087
9113
  overflow: 'hidden',
@@ -9090,10 +9116,10 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9090
9116
  cursor: 'help',
9091
9117
  }, 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
9118
  }
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) => {
9119
+ 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
9120
  toggleExpand(e);
9095
9121
  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: {
9122
+ }, "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
9123
  overflow: 'hidden',
9098
9124
  textOverflow: 'ellipsis',
9099
9125
  whiteSpace: 'nowrap',
@@ -9103,7 +9129,7 @@ function AuditLogFeedItem({ event, onEventClick, isSelected = false, className =
9103
9129
  /**
9104
9130
  * React hook for executing audit log queries
9105
9131
  */
9106
- function useAuditLogQuery({ client, autoExecute = false, }) {
9132
+ function useAuditLogQuery({ client, }) {
9107
9133
  const [query, setQuery] = React.useState(null);
9108
9134
  const [events, setEvents] = React.useState([]);
9109
9135
  const [isLoading, setIsLoading] = React.useState(false);
@@ -10270,7 +10296,7 @@ function ActivityExpandedDetails({ activity, compact = false, }) {
10270
10296
  const timestamp = metadata?.creationTimestamp;
10271
10297
  const actorDisplay = actor.displayName || actor.name;
10272
10298
  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] })] })] }));
10299
+ 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
10300
  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
10301
  }
10276
10302
 
@@ -10339,23 +10365,23 @@ function getActionIconClasses(verb) {
10339
10365
  switch (normalizedVerb) {
10340
10366
  case "create":
10341
10367
  return {
10342
- container: "bg-blue-50 dark:bg-blue-950",
10343
- icon: "text-blue-500 dark:text-blue-400",
10368
+ container: "bg-[var(--success-100)]",
10369
+ icon: "text-[var(--success-500)]",
10344
10370
  };
10345
10371
  case "update":
10346
10372
  return {
10347
- container: "bg-green-50 dark:bg-green-950",
10348
- icon: "text-green-600 dark:text-green-400",
10373
+ container: "bg-[var(--info-100)]",
10374
+ icon: "text-[var(--info-500)]",
10349
10375
  };
10350
10376
  case "delete":
10351
10377
  return {
10352
- container: "bg-red-50 dark:bg-red-950",
10353
- icon: "text-red-500 dark:text-red-400",
10378
+ container: "bg-destructive/10",
10379
+ icon: "text-destructive",
10354
10380
  };
10355
10381
  default:
10356
10382
  return {
10357
- container: "bg-slate-100 dark:bg-slate-800",
10358
- icon: "text-slate-500 dark:text-slate-400",
10383
+ container: "bg-muted",
10384
+ icon: "text-muted-foreground",
10359
10385
  };
10360
10386
  }
10361
10387
  }
@@ -10413,7 +10439,7 @@ function ActivityFeedItem({ activity, onResourceClick, resourceLinkResolver, ten
10413
10439
  // surfaced via a hover tooltip on the avatar so the column stays narrow.
10414
10440
  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
10441
  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) => {
10442
+ 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
10443
  // Row-level click toggles expansion. Inner interactive elements
10418
10444
  // (links, avatar, expand button) call e.stopPropagation() so
10419
10445
  // they don't double-fire. If a parent passed onActivityClick,
@@ -10584,6 +10610,18 @@ function useFacets(client, timeRange, filters = {}) {
10584
10610
  };
10585
10611
  }
10586
10612
 
10613
+ /**
10614
+ * SegmentedToggle - a single-select control built on datum-ui's ButtonGroup.
10615
+ * The active segment is a solid primary Button; inactive segments sit on the
10616
+ * neutral (muted) button surface so the control reads in both themes.
10617
+ */
10618
+ function SegmentedToggle({ options, value, onChange, ariaLabel, className, disabled = false, }) {
10619
+ return (jsxRuntime.jsx(buttonGroup.ButtonGroup, { "aria-label": ariaLabel, className: className, children: options.map((option) => {
10620
+ const active = value === option.value;
10621
+ 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));
10622
+ }) }));
10623
+ }
10624
+
10587
10625
  /**
10588
10626
  * Options for the change source toggle
10589
10627
  */
@@ -10607,17 +10645,8 @@ const OPTIONS$1 = [
10607
10645
  /**
10608
10646
  * ChangeSourceToggle provides a segmented control for filtering by change source
10609
10647
  */
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
- }) }));
10648
+ function ChangeSourceToggle({ value, onChange, className, disabled = false, }) {
10649
+ return (jsxRuntime.jsx(SegmentedToggle, { options: OPTIONS$1, value: value, onChange: onChange, ariaLabel: "Filter by change source", className: className, disabled: disabled }));
10621
10650
  }
10622
10651
 
10623
10652
  /**
@@ -10689,7 +10718,7 @@ const getSelectedPreset$1 = (timeRange) => {
10689
10718
  /**
10690
10719
  * ActivityFeedFilters provides filter controls for the activity feed
10691
10720
  */
10692
- function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTimeRangeChange, disabled = false, hiddenFilters = [], className = "", }) {
10721
+ function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTimeRangeChange, disabled = false, hiddenFilters = [], className = "", extraFilters, }) {
10693
10722
  const { resourceKinds, actorNames, apiGroups, resourceNamespaces, error: facetsError, } = useFacets(client, timeRange, filters);
10694
10723
  // Log facets error for debugging
10695
10724
  if (facetsError) {
@@ -10909,12 +10938,12 @@ function ActivityFeedFilters({ client, filters, timeRange, onFiltersChange, onTi
10909
10938
  clearTimeout(searchDebounceRef.current);
10910
10939
  onFiltersChangeRef.current({ ...filtersRef.current, search: undefined });
10911
10940
  }, []);
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) => {
10941
+ 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
10942
  const config = FILTER_CONFIGS$1[filterId];
10914
10943
  return (jsxRuntime.jsx(FilterChip, { label: config.label, values: getFilterValues(filterId), options: config.inputMode === "typeahead"
10915
10944
  ? getFilterOptions(filterId)
10916
10945
  : 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 }), 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() })] }) }));
10946
+ }), 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() })] }) }));
10918
10947
  }
10919
10948
 
10920
10949
  /**
@@ -10984,26 +11013,28 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
10984
11013
  React.useEffect(() => {
10985
11014
  isLoadingRef.current = isLoading;
10986
11015
  }, [isLoading]);
10987
- // Infinite scroll using Intersection Observer
11016
+ // Infinite scroll using Intersection Observer.
11017
+ // The list container is the root only when it actually scrolls. Host apps
11018
+ // such as cloud-portal scroll at the page level, so the container never
11019
+ // overflows; in that case observe against the viewport instead.
10988
11020
  React.useEffect(() => {
10989
11021
  if (!infiniteScroll || !hasMore || !loadMoreTriggerRef.current)
10990
11022
  return;
11023
+ const container = scrollContainerRef.current;
11024
+ const containerScrolls = !!container && container.scrollHeight > container.clientHeight + 1;
10991
11025
  const observer = new IntersectionObserver((entries) => {
10992
11026
  const entry = entries[0];
10993
11027
  if (entry.isIntersecting && !isLoadingRef.current) {
10994
- // Call through the ref to always use the latest function
10995
11028
  loadMoreRef.current();
10996
11029
  }
10997
11030
  }, {
10998
- root: scrollContainerRef.current,
11031
+ root: containerScrolls ? container : null,
10999
11032
  rootMargin: `${loadMoreThreshold}px`,
11000
11033
  threshold: 0,
11001
11034
  });
11002
11035
  observer.observe(loadMoreTriggerRef.current);
11003
- return () => {
11004
- observer.disconnect();
11005
- };
11006
- }, [infiniteScroll, loadMoreThreshold, hasMore]);
11036
+ return () => observer.disconnect();
11037
+ }, [infiniteScroll, loadMoreThreshold, hasMore, activities.length]);
11007
11038
  // Handle filter changes - refresh is automatic via the hook
11008
11039
  const handleFiltersChange = React.useCallback((newFilters) => {
11009
11040
  setFilters(newFilters);
@@ -11043,7 +11074,7 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
11043
11074
  // Parent containers must have proper height constraints (h-screen/h-full + overflow-hidden)
11044
11075
  const effectiveMaxHeight = maxHeight === "none" ? undefined : maxHeight;
11045
11076
  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 &&
11077
+ 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 })), 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
11078
  activities.length === 0 &&
11048
11079
  hasPolicies !== false &&
11049
11080
  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 &&
@@ -11697,7 +11728,7 @@ function useEventsFeed({ client, initialFilters = {}, initialTimeRange = { start
11697
11728
  function getRegarding$1(event) {
11698
11729
  return event.regarding || event.involvedObject || {};
11699
11730
  }
11700
- function getReportingController$1(event) {
11731
+ function getReportingController(event) {
11701
11732
  return event.reportingController || event.reportingComponent || event.source?.component;
11702
11733
  }
11703
11734
  function getReportingInstance(event) {
@@ -11710,7 +11741,7 @@ function getReportingInstance(event) {
11710
11741
  */
11711
11742
  function EventExpandedDetails({ event, compact = true }) {
11712
11743
  const regarding = getRegarding$1(event);
11713
- const reportingController = getReportingController$1(event);
11744
+ const reportingController = getReportingController(event);
11714
11745
  const reportingInstance = getReportingInstance(event);
11715
11746
  const { eventTime, action, metadata, related } = event;
11716
11747
  const firstTimestamp = event.firstTimestamp || event.deprecatedFirstTimestamp;
@@ -11737,12 +11768,6 @@ function getRegarding(event) {
11737
11768
  function getNote(event) {
11738
11769
  return event.note || event.message;
11739
11770
  }
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
11771
  /**
11747
11772
  * Get the event count (handling both new and deprecated field names)
11748
11773
  */
@@ -11778,7 +11803,6 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11778
11803
  const note = getNote(event);
11779
11804
  const count = getCount(event);
11780
11805
  const timestamp = getTimestamp(event);
11781
- getReportingController(event);
11782
11806
  const { type, reason } = event;
11783
11807
  const handleClick = () => {
11784
11808
  onEventClick?.(event);
@@ -11821,11 +11845,11 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11821
11845
  if (variant === 'timeline') {
11822
11846
  const TypeIcon = isWarning ? TriangleAlert : Bell;
11823
11847
  const iconBg = isWarning
11824
- ? 'bg-red-50 dark:bg-red-950'
11825
- : 'bg-blue-50 dark:bg-blue-950';
11848
+ ? 'bg-destructive/10'
11849
+ : 'bg-[var(--info-100)]';
11826
11850
  const iconColor = isWarning
11827
- ? 'text-red-500 dark:text-red-400'
11828
- : 'text-blue-500 dark:text-blue-400';
11851
+ ? 'text-destructive'
11852
+ : 'text-[var(--info-500)]';
11829
11853
  const objectLabel = regarding.namespace
11830
11854
  ? `${regarding.kind || 'Unknown'} · ${regarding.namespace}/${regarding.name || ''}`
11831
11855
  : `${regarding.kind || 'Unknown'} · ${regarding.name || ''}`;
@@ -11838,18 +11862,16 @@ function EventFeedItem({ event, onEventClick, onResourceClick, isSelected = fals
11838
11862
  cursor: 'help',
11839
11863
  }, 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
11864
  }
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) => {
11865
+ 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
11866
  toggleExpand(e);
11843
11867
  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: {
11868
+ }, "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
11869
  overflow: 'hidden',
11848
11870
  textOverflow: 'ellipsis',
11849
11871
  whiteSpace: 'nowrap',
11850
11872
  }, 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
11873
  ? `${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] }));
11874
+ : `${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
11875
  }
11854
11876
 
11855
11877
  /**
@@ -11962,11 +11984,8 @@ const OPTIONS = [
11962
11984
  /**
11963
11985
  * EventTypeToggle provides a segmented control for filtering by event type
11964
11986
  */
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
- }) }));
11987
+ function EventTypeToggle({ value, onChange, className, disabled = false, }) {
11988
+ return (jsxRuntime.jsx(SegmentedToggle, { options: OPTIONS, value: value, onChange: onChange, ariaLabel: "Filter by event type", className: className, disabled: disabled }));
11970
11989
  }
11971
11990
 
11972
11991
  /**
@@ -12210,7 +12229,7 @@ function EventsFeedFilters({ client, filters, timeRange, onFiltersChange, onTime
12210
12229
  search: value || undefined,
12211
12230
  });
12212
12231
  }, [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) => {
12232
+ 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
12233
  const config = FILTER_CONFIGS[filterId];
12215
12234
  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
12235
  }), 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 +12297,7 @@ function EventsFeed({ client, initialFilters = {}, initialTimeRange = { start: "
12278
12297
  : `flex-1 min-h-0 flex flex-col p-3 gap-0 ${className}`;
12279
12298
  // Build list classes - use flex-1 min-h-0 for flex-based scrolling
12280
12299
  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
12300
+ 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
12301
  ? 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
12302
  : 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
12303
  ? 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 +12477,14 @@ function PolicyList({ client, onViewPolicy, onEditPolicy, onCreatePolicy, groupB
12458
12477
  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
12478
  const rules = countRules(policy);
12460
12479
  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"
12480
+ 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"
12481
+ ? "text-destructive"
12463
12482
  : 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"
12483
+ ? "text-[var(--badge-warning)]"
12484
+ : "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
12485
+ ? "bg-muted text-muted-foreground"
12467
12486
  : "", 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"
12487
+ ? "bg-muted text-muted-foreground"
12469
12488
  : "", children: rules.event }) })] }, policy.metadata?.name));
12470
12489
  }) })] }) }))] }, group.apiGroup))) }))] })] }));
12471
12490
  }
@@ -12913,7 +12932,7 @@ function PolicyRuleListItem({ rule, ruleType, index, onEdit, onDelete, onMoveUp,
12913
12932
  flex items-center gap-2 p-2 rounded-md border transition-all duration-200
12914
12933
  border-border bg-background hover:bg-muted/50
12915
12934
  ${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" }) })] })] }));
12935
+ `, 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
12936
  }
12918
12937
 
12919
12938
  /**
@@ -13034,7 +13053,7 @@ const registeredLanguages = new Set();
13034
13053
  * Lazy-loaded Monaco editor for CEL expressions and templates
13035
13054
  * Provides autocomplete based on available field paths
13036
13055
  */
13037
- function CelEditor({ value, onChange, language = 'cel', availableFields = [], placeholder = '', height = '100px', className, error = false, readOnly = false, 'data-testid': testId, }) {
13056
+ function CelEditor({ value, onChange, language = 'cel', availableFields = [], height = '100px', className, error = false, readOnly = false, 'data-testid': testId, }) {
13038
13057
  const [Editor, setEditor] = React.useState(null);
13039
13058
  const [loadError, setLoadError] = React.useState(null);
13040
13059
  const [isLoading, setIsLoading] = React.useState(true);
@@ -13193,7 +13212,7 @@ function CelEditor({ value, onChange, language = 'cel', availableFields = [], pl
13193
13212
  */
13194
13213
  function requiresBracketNotation(key) {
13195
13214
  // Keys with dots, slashes, or other special characters need bracket notation
13196
- return /[.\/\-:]/.test(key) || /^\d/.test(key);
13215
+ return /[./\-:]/.test(key) || /^\d/.test(key);
13197
13216
  }
13198
13217
  /**
13199
13218
  * Build the CEL path for a key, using bracket notation when needed
@@ -13400,7 +13419,7 @@ function PolicyRuleEditorDialog({ open, onOpenChange, rule, ruleType, existingNa
13400
13419
  const [previewError, setPreviewError] = React.useState(null);
13401
13420
  // Sample data for autocomplete (fetched once when dialog opens)
13402
13421
  const [sampleData, setSampleData] = React.useState([]);
13403
- const [sampleDataLoading, setSampleDataLoading] = React.useState(false);
13422
+ const [, setSampleDataLoading] = React.useState(false);
13404
13423
  // Extract field paths from sample data OR preview data for autocomplete
13405
13424
  const availableFields = React.useMemo(() => {
13406
13425
  // First try to use preview data if available
@@ -13849,10 +13868,10 @@ function PolicyEditor({ client, policyName, onSaveSuccess, onCancel, onResourceC
13849
13868
  };
13850
13869
  const policyStatus = getPolicyStatus();
13851
13870
  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'
13871
+ ? 'bg-[var(--success-500)]'
13853
13872
  : 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"] })) })] })] }) })] }) }));
13873
+ ? 'bg-destructive'
13874
+ : '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
13875
  }
13857
13876
 
13858
13877
  /**
@@ -13936,12 +13955,12 @@ function PolicyDetailView({ client, policyName, onEdit, onResourceClick, classNa
13936
13955
  const policyStatus = getPolicyStatus();
13937
13956
  const isUnhealthy = policyStatus && policyStatus.status !== 'ready';
13938
13957
  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'
13958
+ ? 'bg-[var(--success-500)]'
13940
13959
  : policyStatus?.status === 'error'
13941
- ? 'bg-red-500'
13960
+ ? 'bg-destructive'
13942
13961
  : 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 }) }))] }) }));
13962
+ ? 'bg-[var(--badge-warning)]'
13963
+ : '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
13964
  }
13946
13965
 
13947
13966
  /**
@@ -14041,7 +14060,7 @@ function PolicyEditView({ client, policyName, onSaveSuccess, onCancel, className
14041
14060
  };
14042
14061
  const policyStatus = getPolicyStatus();
14043
14062
  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"] })) })] })] }) })] }) }));
14063
+ 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
14064
  }
14046
14065
 
14047
14066
  /**
@@ -14122,8 +14141,8 @@ function PolicyRuleEditor({ rule, index, ruleType, isHighlighted = false, onChan
14122
14141
  onChange({ ...rule, summary: example });
14123
14142
  };
14124
14143
  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))) })] })] }))] })] })] }));
14144
+ ? 'border-[var(--success-500)] bg-[var(--success-100)]'
14145
+ : '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
14146
  }
14128
14147
 
14129
14148
  /**
@@ -14781,7 +14800,7 @@ function ReindexJobList({ client, onViewJob, onCreateJob, watch = true, classNam
14781
14800
  const bTime = b.metadata?.creationTimestamp || '';
14782
14801
  return bTime.localeCompare(aTime);
14783
14802
  });
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) => {
14803
+ 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
14804
  const duration = getReindexJobDuration(job);
14786
14805
  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
14806
  }) })] }) }))] })] }));
@@ -14793,11 +14812,11 @@ function ReindexJobList({ client, onViewJob, onCreateJob, watch = true, classNam
14793
14812
  function getPhaseIcon(phase) {
14794
14813
  switch (phase) {
14795
14814
  case 'Succeeded':
14796
- return jsxRuntime.jsx(CircleCheck, { className: "h-8 w-8 text-green-500" });
14815
+ return jsxRuntime.jsx(CircleCheck, { className: "h-8 w-8 text-[var(--success-500)]" });
14797
14816
  case 'Failed':
14798
- return jsxRuntime.jsx(CircleX, { className: "h-8 w-8 text-red-500" });
14817
+ return jsxRuntime.jsx(CircleX, { className: "h-8 w-8 text-destructive" });
14799
14818
  case 'Running':
14800
- return jsxRuntime.jsx(LoaderCircle, { className: "h-8 w-8 text-blue-500 animate-spin" });
14819
+ return jsxRuntime.jsx(LoaderCircle, { className: "h-8 w-8 text-[var(--info-500)] animate-spin" });
14801
14820
  case 'Pending':
14802
14821
  default:
14803
14822
  return jsxRuntime.jsx(Clock, { className: "h-8 w-8 text-muted-foreground" });
@@ -14878,7 +14897,7 @@ function ReindexJobDetailView({ client, jobName, onDelete, watch = true, classNa
14878
14897
  const duration = job ? getReindexJobDuration(job) : null;
14879
14898
  const statusMessage = job ? getReindexJobStatusMessage(job) : '';
14880
14899
  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))) })] }))] }))] }));
14900
+ 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
14901
  }
14883
14902
 
14884
14903
  const TIME_RANGE_OPTIONS$1 = [
@@ -14981,76 +15000,11 @@ function ReindexJobDialog({ client, policyName, open, onOpenChange, onSuccess, e
14981
15000
  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
15001
  }
14983
15002
 
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))) })] })] }) }) })] }));
15003
+ function MultiCombobox({ options, values, onValuesChange, placeholder = 'Select…',
15004
+ // searchPlaceholder is accepted for API compatibility but MultiSelect has no counterpart.
15005
+ emptyMessage = 'No results', disabled, loading, className, maxDisplayed = 3, }) {
15006
+ const items = React__namespace.useMemo(() => options.map((o) => ({ value: o.value, label: o.label })), [options]);
15007
+ return (jsxRuntime.jsx(multiSelect.MultiSelect, { className: className, options: items, value: values, onValueChange: onValuesChange, placeholder: placeholder, emptyContent: emptyMessage, isLoading: loading, disabled: disabled, maxCount: maxDisplayed }));
15054
15008
  }
15055
15009
 
15056
15010
  /**
@@ -15760,7 +15714,7 @@ class ActivityApiClient {
15760
15714
  const reader = response.body.getReader();
15761
15715
  const decoder = new TextDecoder();
15762
15716
  let buffer = '';
15763
- while (true) {
15717
+ for (;;) {
15764
15718
  const { done, value } = await reader.read();
15765
15719
  if (done) {
15766
15720
  options?.onClose?.();
@@ -16160,7 +16114,7 @@ class ActivityApiClient {
16160
16114
  const reader = response.body.getReader();
16161
16115
  const decoder = new TextDecoder();
16162
16116
  let buffer = '';
16163
- while (true) {
16117
+ for (;;) {
16164
16118
  const { done, value } = await reader.read();
16165
16119
  if (done) {
16166
16120
  options?.onClose?.();
@@ -16276,7 +16230,7 @@ class ActivityApiClient {
16276
16230
  const reader = response.body.getReader();
16277
16231
  const decoder = new TextDecoder();
16278
16232
  let buffer = '';
16279
- while (true) {
16233
+ for (;;) {
16280
16234
  const { done, value } = await reader.read();
16281
16235
  if (done) {
16282
16236
  options?.onClose?.();
@@ -16635,6 +16589,7 @@ exports.ActionToggle = ActionToggle;
16635
16589
  exports.ActivityApiClient = ActivityApiClient;
16636
16590
  exports.ActivityExpandedDetails = ActivityExpandedDetails;
16637
16591
  exports.ActivityFeed = ActivityFeed;
16592
+ exports.ActivityFeedFilters = ActivityFeedFilters;
16638
16593
  exports.ActivityFeedItem = ActivityFeedItem;
16639
16594
  exports.ActivityFeedItemSkeleton = ActivityFeedItemSkeleton;
16640
16595
  exports.ActivityFeedSummary = ActivityFeedSummary;