@agent-native/dispatch 0.38.15 → 0.38.16-nightly-20260927213438

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 (94) hide show
  1. package/dist/actions/create-workspace-resource.d.ts +13 -13
  2. package/dist/actions/provider-api-register.d.ts +12 -12
  3. package/dist/components/automation-create-dialog.js +4 -4
  4. package/dist/components/automation-create-dialog.js.map +1 -1
  5. package/dist/components/layout/Header.js +1 -1
  6. package/dist/components/layout/Header.js.map +1 -1
  7. package/dist/components/layout/Layout.d.ts +7 -0
  8. package/dist/components/layout/Layout.d.ts.map +1 -1
  9. package/dist/components/layout/Layout.js +19 -4
  10. package/dist/components/layout/Layout.js.map +1 -1
  11. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  12. package/dist/components/messaging-setup-panel.js +7 -28
  13. package/dist/components/messaging-setup-panel.js.map +1 -1
  14. package/dist/components/transactional-email-send-log.js +1 -1
  15. package/dist/components/transactional-email-send-log.js.map +1 -1
  16. package/dist/components/ui/alert-dialog.d.ts +1 -20
  17. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  18. package/dist/components/ui/alert-dialog.js +1 -26
  19. package/dist/components/ui/alert-dialog.js.map +1 -1
  20. package/dist/components/ui/button.d.ts +1 -11
  21. package/dist/components/ui/button.d.ts.map +1 -1
  22. package/dist/components/ui/button.js +1 -33
  23. package/dist/components/ui/button.js.map +1 -1
  24. package/dist/components/ui/carousel.d.ts +2 -2
  25. package/dist/components/ui/carousel.d.ts.map +1 -1
  26. package/dist/components/ui/input.d.ts +1 -3
  27. package/dist/components/ui/input.d.ts.map +1 -1
  28. package/dist/components/ui/input.js +1 -8
  29. package/dist/components/ui/input.js.map +1 -1
  30. package/dist/components/ui/sidebar.d.ts +4 -2
  31. package/dist/components/ui/sidebar.d.ts.map +1 -1
  32. package/dist/components/ui/switch.d.ts +1 -4
  33. package/dist/components/ui/switch.d.ts.map +1 -1
  34. package/dist/components/ui/switch.js +1 -7
  35. package/dist/components/ui/switch.js.map +1 -1
  36. package/dist/components/ui/tabs.d.ts +1 -7
  37. package/dist/components/ui/tabs.d.ts.map +1 -1
  38. package/dist/components/ui/tabs.js +1 -12
  39. package/dist/components/ui/tabs.js.map +1 -1
  40. package/dist/components/ui/toggle.d.ts +1 -12
  41. package/dist/components/ui/toggle.d.ts.map +1 -1
  42. package/dist/components/ui/toggle.js +1 -25
  43. package/dist/components/ui/toggle.js.map +1 -1
  44. package/dist/components/usage-alerts-panel.d.ts.map +1 -1
  45. package/dist/components/usage-alerts-panel.js +1 -1
  46. package/dist/components/usage-alerts-panel.js.map +1 -1
  47. package/dist/components/workspace-app-search.d.ts.map +1 -1
  48. package/dist/components/workspace-app-search.js +1 -1
  49. package/dist/components/workspace-app-search.js.map +1 -1
  50. package/dist/routes/pages/automations.d.ts.map +1 -1
  51. package/dist/routes/pages/automations.js +2 -2
  52. package/dist/routes/pages/automations.js.map +1 -1
  53. package/dist/routes/pages/metrics.d.ts.map +1 -1
  54. package/dist/routes/pages/metrics.js +1 -1
  55. package/dist/routes/pages/metrics.js.map +1 -1
  56. package/dist/routes/pages/settings.d.ts +9 -0
  57. package/dist/routes/pages/settings.d.ts.map +1 -1
  58. package/dist/routes/pages/settings.js +65 -12
  59. package/dist/routes/pages/settings.js.map +1 -1
  60. package/dist/routes/pages/thread-debug.js +1 -1
  61. package/dist/routes/pages/thread-debug.js.map +1 -1
  62. package/dist/routes/pages/vault.d.ts.map +1 -1
  63. package/dist/routes/pages/vault.js +2 -2
  64. package/dist/routes/pages/vault.js.map +1 -1
  65. package/dist/server/lib/usage-metrics-store.js +2 -3
  66. package/dist/server/lib/usage-metrics-store.js.map +1 -1
  67. package/dist/server/plugins/db.d.ts.map +1 -1
  68. package/dist/server/plugins/db.js +44 -0
  69. package/dist/server/plugins/db.js.map +1 -1
  70. package/package.json +4 -4
  71. package/src/components/automation-create-dialog.tsx +6 -6
  72. package/src/components/layout/Header.tsx +2 -2
  73. package/src/components/layout/Layout.spec.tsx +28 -0
  74. package/src/components/layout/Layout.tsx +73 -43
  75. package/src/components/messaging-setup-panel.spec.tsx +5 -1
  76. package/src/components/messaging-setup-panel.tsx +9 -45
  77. package/src/components/transactional-email-send-log.tsx +1 -1
  78. package/src/components/ui/alert-dialog.tsx +1 -139
  79. package/src/components/ui/button.tsx +1 -56
  80. package/src/components/ui/input.tsx +1 -22
  81. package/src/components/ui/switch.tsx +1 -27
  82. package/src/components/ui/tabs.tsx +1 -53
  83. package/src/components/ui/toggle.tsx +1 -43
  84. package/src/components/usage-alerts-panel.tsx +6 -12
  85. package/src/components/workspace-app-search.tsx +2 -1
  86. package/src/routes/pages/automations.tsx +4 -2
  87. package/src/routes/pages/metrics.tsx +2 -1
  88. package/src/routes/pages/settings.spec.tsx +179 -0
  89. package/src/routes/pages/settings.tsx +179 -119
  90. package/src/routes/pages/thread-debug.tsx +1 -1
  91. package/src/routes/pages/vault.tsx +3 -2
  92. package/src/server/lib/usage-metrics-store.spec.ts +1 -0
  93. package/src/server/lib/usage-metrics-store.ts +2 -2
  94. package/src/server/plugins/db.ts +49 -0
@@ -1 +1 @@
1
- {"version":3,"file":"usage-alerts-panel.d.ts","sourceRoot":"","sources":["../../src/components/usage-alerts-panel.tsx"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AA6LD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,UAAe,GAChB,EAAE,qBAAqB,mDAqOvB"}
1
+ {"version":3,"file":"usage-alerts-panel.d.ts","sourceRoot":"","sources":["../../src/components/usage-alerts-panel.tsx"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAuLD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,UAAe,GAChB,EAAE,qBAAqB,mDAqOvB"}
@@ -58,7 +58,7 @@ function defaultDraft() {
58
58
  }
59
59
  function AlertEditor({ draft, appOptions, isExisting, onChange, onSave, onCancel, isPending, }) {
60
60
  const t = useT();
61
- return (_jsxs("div", { className: "grid gap-3 rounded-md border bg-background/60 p-3 sm:grid-cols-2 lg:grid-cols-5", children: [_jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "App" }), _jsxs(Select, { value: draft.appId || "all", onValueChange: (value) => onChange({ appId: value === "all" ? "" : value }), disabled: isExisting, children: [_jsx(SelectTrigger, { className: "h-9 text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), appOptions.map((app) => (_jsx(SelectItem, { value: app.id, children: app.label }, app.id)))] })] })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "Unit" }), _jsxs(Select, { value: draft.unit, onValueChange: (value) => onChange({ unit: value }), children: [_jsx(SelectTrigger, { className: "h-9 text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "usd", children: "Dollars" }), _jsx(SelectItem, { value: "builder-credits", children: "Credits" }), _jsx(SelectItem, { value: "tokens", children: "Tokens" })] })] })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: t("dispatch.pages.usageAlertThreshold") }), _jsx(Input, { type: "number", min: "0.01", step: draft.unit === "tokens" ? "1" : "0.01", value: draft.limit, onChange: (event) => onChange({ limit: event.target.value }), className: "h-9 text-sm" })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "Period" }), _jsxs(Select, { value: draft.period, onValueChange: (value) => onChange({ period: value }), children: [_jsx(SelectTrigger, { className: "h-9 text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "day", children: "Per day" }), _jsx(SelectItem, { value: "month", children: "Per month" })] })] })] }), _jsxs("div", { className: "flex flex-wrap items-end gap-3 pb-1 text-xs text-muted-foreground", children: [_jsxs("label", { className: "inline-flex items-center gap-2", children: [_jsx(Checkbox, { checked: draft.inApp, onCheckedChange: (checked) => onChange({ inApp: checked === true }) }), "In app"] }), _jsxs("label", { className: "inline-flex items-center gap-2", children: [_jsx(Checkbox, { checked: draft.email, onCheckedChange: (checked) => onChange({ email: checked === true }) }), "Email"] }), _jsx(Button, { type: "button", size: "sm", className: "ms-auto h-8", onClick: onSave, disabled: isPending, children: "Save" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-8", onClick: onCancel, children: "Cancel" })] })] }));
61
+ return (_jsxs("div", { className: "grid gap-3 rounded-md border bg-background/60 p-3 sm:grid-cols-2 lg:grid-cols-5", children: [_jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "App" }), _jsxs(Select, { value: draft.appId || "all", onValueChange: (value) => onChange({ appId: value === "all" ? "" : value }), disabled: isExisting, children: [_jsx(SelectTrigger, { className: "text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), appOptions.map((app) => (_jsx(SelectItem, { value: app.id, children: app.label }, app.id)))] })] })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "Unit" }), _jsxs(Select, { value: draft.unit, onValueChange: (value) => onChange({ unit: value }), children: [_jsx(SelectTrigger, { className: "text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "usd", children: "Dollars" }), _jsx(SelectItem, { value: "builder-credits", children: "Credits" }), _jsx(SelectItem, { value: "tokens", children: "Tokens" })] })] })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: t("dispatch.pages.usageAlertThreshold") }), _jsx(Input, { type: "number", min: "0.01", step: draft.unit === "tokens" ? "1" : "0.01", value: draft.limit, onChange: (event) => onChange({ limit: event.target.value }), className: "text-sm" })] }), _jsxs("label", { className: "space-y-1.5 text-xs text-muted-foreground", children: [_jsx("span", { children: "Period" }), _jsxs(Select, { value: draft.period, onValueChange: (value) => onChange({ period: value }), children: [_jsx(SelectTrigger, { className: "text-sm", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "day", children: "Per day" }), _jsx(SelectItem, { value: "month", children: "Per month" })] })] })] }), _jsxs("div", { className: "flex flex-wrap items-end gap-3 pb-1 text-xs text-muted-foreground", children: [_jsxs("label", { className: "inline-flex items-center gap-2", children: [_jsx(Checkbox, { checked: draft.inApp, onCheckedChange: (checked) => onChange({ inApp: checked === true }) }), "In app"] }), _jsxs("label", { className: "inline-flex items-center gap-2", children: [_jsx(Checkbox, { checked: draft.email, onCheckedChange: (checked) => onChange({ email: checked === true }) }), "Email"] }), _jsx(Button, { type: "button", size: "sm", className: "ms-auto", onClick: onSave, disabled: isPending, children: "Save" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancel, children: "Cancel" })] })] }));
62
62
  }
63
63
  export function UsageAlertsPanel({ scope, appOptions = [], }) {
64
64
  const t = useT();
@@ -1 +1 @@
1
- {"version":3,"file":"usage-alerts-panel.js","sourceRoot":"","sources":["../../src/components/usage-alerts-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { UsageAlertRule } from \"@agent-native/core\";\nimport {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconBell, IconMail, IconPencil, IconX } from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport { Checkbox } from \"./ui/checkbox\";\nimport { Input } from \"./ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./ui/select\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { Switch } from \"./ui/switch\";\n\nexport interface UsageAlertAppOption {\n id: string;\n label: string;\n}\n\ninterface UsageAlertsPanelProps {\n scope: \"user\" | \"workspace\";\n appOptions?: UsageAlertAppOption[];\n}\n\ntype AlertUnit = \"usd\" | \"builder-credits\" | \"tokens\";\ntype AlertChannel = \"in-app\" | \"email\";\n\ninterface AlertDraft {\n ruleId?: string;\n appId: string;\n unit: AlertUnit;\n period: \"day\" | \"month\";\n limit: string;\n inApp: boolean;\n email: boolean;\n}\n\nfunction asRules(value: unknown): UsageAlertRule[] {\n if (Array.isArray(value)) return value as UsageAlertRule[];\n if (value && typeof value === \"object\") {\n const rules = (value as { rules?: unknown }).rules;\n if (Array.isArray(rules)) return rules as UsageAlertRule[];\n }\n return [];\n}\n\nfunction formatAlertValue(rule: UsageAlertRule, value: number): string {\n if (rule.unit === \"usd\") {\n return value.toLocaleString(undefined, {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 2,\n });\n }\n return (\n value.toLocaleString(undefined, {\n maximumFractionDigits: rule.unit === \"builder-credits\" ? 2 : 0,\n }) +\n \" \" +\n (rule.unit === \"builder-credits\" ? \"credits\" : \"tokens\")\n );\n}\n\nfunction draftFromRule(rule: UsageAlertRule): AlertDraft {\n return {\n ruleId: rule.id,\n appId: rule.appId ?? \"\",\n unit: rule.unit,\n period: rule.period,\n limit: String(rule.limit),\n inApp: rule.channels.includes(\"in-app\"),\n email: rule.channels.includes(\"email\"),\n };\n}\n\nfunction defaultDraft(): AlertDraft {\n return {\n appId: \"\",\n unit: \"usd\",\n period: \"day\",\n limit: \"100\",\n inApp: true,\n email: true,\n };\n}\n\nfunction AlertEditor({\n draft,\n appOptions,\n isExisting,\n onChange,\n onSave,\n onCancel,\n isPending,\n}: {\n draft: AlertDraft;\n appOptions: UsageAlertAppOption[];\n isExisting: boolean;\n onChange: (patch: Partial<AlertDraft>) => void;\n onSave: () => void;\n onCancel: () => void;\n isPending: boolean;\n}) {\n const t = useT();\n\n return (\n <div className=\"grid gap-3 rounded-md border bg-background/60 p-3 sm:grid-cols-2 lg:grid-cols-5\">\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>App</span>\n <Select\n value={draft.appId || \"all\"}\n onValueChange={(value) =>\n onChange({ appId: value === \"all\" ? \"\" : value })\n }\n disabled={isExisting}\n >\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n {appOptions.map((app) => (\n <SelectItem key={app.id} value={app.id}>\n {app.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>Unit</span>\n <Select\n value={draft.unit}\n onValueChange={(value) => onChange({ unit: value as AlertUnit })}\n >\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"usd\">Dollars</SelectItem>\n <SelectItem value=\"builder-credits\">Credits</SelectItem>\n <SelectItem value=\"tokens\">Tokens</SelectItem>\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>{t(\"dispatch.pages.usageAlertThreshold\")}</span>\n <Input\n type=\"number\"\n min=\"0.01\"\n step={draft.unit === \"tokens\" ? \"1\" : \"0.01\"}\n value={draft.limit}\n onChange={(event) => onChange({ limit: event.target.value })}\n className=\"h-9 text-sm\"\n />\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>Period</span>\n <Select\n value={draft.period}\n onValueChange={(value) =>\n onChange({ period: value as \"day\" | \"month\" })\n }\n >\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"day\">Per day</SelectItem>\n <SelectItem value=\"month\">Per month</SelectItem>\n </SelectContent>\n </Select>\n </label>\n <div className=\"flex flex-wrap items-end gap-3 pb-1 text-xs text-muted-foreground\">\n <label className=\"inline-flex items-center gap-2\">\n <Checkbox\n checked={draft.inApp}\n onCheckedChange={(checked) => onChange({ inApp: checked === true })}\n />\n In app\n </label>\n <label className=\"inline-flex items-center gap-2\">\n <Checkbox\n checked={draft.email}\n onCheckedChange={(checked) => onChange({ email: checked === true })}\n />\n Email\n </label>\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"ms-auto h-8\"\n onClick={onSave}\n disabled={isPending}\n >\n Save\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8\"\n onClick={onCancel}\n >\n Cancel\n </Button>\n </div>\n </div>\n );\n}\n\nexport function UsageAlertsPanel({\n scope,\n appOptions = [],\n}: UsageAlertsPanelProps) {\n const t = useT();\n const query = useActionQuery(\"get-usage-alerts\", { scope });\n const mutation = useActionMutation(\"manage-usage-alert\", {\n onSuccess: () => {\n setEditing(null);\n toast.success(\"Usage alert updated\");\n },\n onError: (error) => toast.error(String(error)),\n });\n const [editing, setEditing] = useState<AlertDraft | null>(null);\n const rules = asRules(query.data);\n const appLabels = useMemo(\n () => new Map(appOptions.map((app) => [app.id, app.label])),\n [appOptions],\n );\n\n function saveDraft() {\n if (!editing) return;\n const limit = Number(editing.limit);\n const channels: AlertChannel[] = [];\n if (editing.inApp) channels.push(\"in-app\");\n if (editing.email) channels.push(\"email\");\n if (!Number.isFinite(limit) || limit <= 0) {\n toast.error(\"Enter a positive threshold.\");\n return;\n }\n if (channels.length === 0) {\n toast.error(\"Choose at least one delivery channel.\");\n return;\n }\n mutation.mutate({\n operation: \"save\",\n scope,\n ruleId: editing.ruleId,\n appId: editing.appId || null,\n unit: editing.unit,\n period: editing.period,\n limit,\n channels,\n enabled: true,\n });\n }\n\n return (\n <section className=\"rounded-lg bg-card\">\n <div className=\"flex items-start justify-between gap-3 border-b px-4 py-3\">\n <div>\n <h2 className=\"text-sm font-semibold text-foreground\">\n Usage alerts\n </h2>\n <p className=\"mt-1 max-w-2xl text-xs leading-5 text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertDescription\")}\n </p>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setEditing(defaultDraft())}\n disabled={mutation.isPending}\n >\n Add alert\n </Button>\n </div>\n\n <div className=\"divide-y\">\n {query.isLoading && rules.length === 0 ? (\n <div className=\"space-y-3 px-4 py-5\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-2/3 max-w-sm\" />\n <Skeleton className=\"h-3 w-1/2 max-w-xs\" />\n </div>\n ))}\n </div>\n ) : null}\n {query.isError ? (\n <div className=\"px-4 py-6 text-sm text-destructive\">\n Usage alerts are unavailable for this scope.{\" \"}\n {query.error instanceof Error ? query.error.message : \"Try again.\"}\n </div>\n ) : null}\n {!query.isLoading && !query.isError && rules.length === 0 ? (\n <div className=\"px-4 py-6 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertEmpty\")}\n </div>\n ) : null}\n {rules.map((rule) => {\n const isEditing = editing?.ruleId === rule.id;\n const target = rule.appId\n ? appLabels.get(rule.appId) || rule.appId\n : \"All apps\";\n return (\n <div key={rule.id} className=\"px-4 py-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {target}\n </span>\n {rule.isDefault ? (\n <Badge variant=\"secondary\">Default</Badge>\n ) : null}\n <Badge\n variant={\n rule.status === \"triggered\" ? \"destructive\" : \"outline\"\n }\n >\n {rule.status === \"triggered\"\n ? t(\"dispatch.pages.usageAlertReached\")\n : rule.status === \"dismissed\"\n ? \"Dismissed\"\n : \"On track\"}\n </Badge>\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertCurrentAndThreshold\", {\n current: formatAlertValue(rule, rule.current),\n threshold: formatAlertValue(rule, rule.limit),\n period: t(\n rule.period === \"day\"\n ? \"dispatch.pages.usageAlertDay\"\n : \"dispatch.pages.usageAlertMonth\",\n ),\n })}\n {rule.percent > 0 ? \" · \" + rule.percent + \"%\" : \"\"}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch\n checked={rule.enabled}\n onCheckedChange={(checked) =>\n mutation.mutate({\n operation: \"set-enabled\",\n scope,\n ruleId: rule.id,\n enabled: checked,\n })\n }\n aria-label={\n (rule.enabled ? \"Disable \" : \"Enable \") +\n target +\n \" usage alert\"\n }\n disabled={mutation.isPending}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setEditing(draftFromRule(rule))}\n aria-label={\"Edit \" + target + \" usage alert\"}\n disabled={mutation.isPending}\n >\n <IconPencil className=\"size-4\" />\n </Button>\n {rule.status === \"triggered\" ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() =>\n mutation.mutate({\n operation: \"dismiss\",\n scope,\n ruleId: rule.id,\n })\n }\n aria-label={\"Dismiss \" + target + \" usage alert\"}\n disabled={mutation.isPending}\n >\n <IconX className=\"size-4\" />\n </Button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n {rule.channels.includes(\"in-app\") ? (\n <span className=\"inline-flex items-center gap-1\">\n <IconBell className=\"size-3.5\" /> In app\n </span>\n ) : null}\n {rule.channels.includes(\"email\") ? (\n <span className=\"inline-flex items-center gap-1\">\n <IconMail className=\"size-3.5\" /> Email\n </span>\n ) : null}\n </div>\n {isEditing && editing ? (\n <div className=\"mt-4\">\n <AlertEditor\n draft={editing}\n appOptions={appOptions}\n isExisting\n onChange={(patch) =>\n setEditing((current) =>\n current ? { ...current, ...patch } : current,\n )\n }\n onSave={saveDraft}\n onCancel={() => setEditing(null)}\n isPending={mutation.isPending}\n />\n </div>\n ) : null}\n </div>\n );\n })}\n {editing && !editing.ruleId ? (\n <div className=\"px-4 py-4\">\n <AlertEditor\n draft={editing}\n appOptions={appOptions}\n isExisting={false}\n onChange={(patch) =>\n setEditing((current) =>\n current ? { ...current, ...patch } : current,\n )\n }\n onSave={saveDraft}\n onCancel={() => setEditing(null)}\n isPending={mutation.isPending}\n />\n </div>\n ) : null}\n </div>\n </section>\n );\n}\n"]}
1
+ {"version":3,"file":"usage-alerts-panel.js","sourceRoot":"","sources":["../../src/components/usage-alerts-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { UsageAlertRule } from \"@agent-native/core\";\nimport {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconBell, IconMail, IconPencil, IconX } from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport { Checkbox } from \"./ui/checkbox\";\nimport { Input } from \"./ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./ui/select\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { Switch } from \"./ui/switch\";\n\nexport interface UsageAlertAppOption {\n id: string;\n label: string;\n}\n\ninterface UsageAlertsPanelProps {\n scope: \"user\" | \"workspace\";\n appOptions?: UsageAlertAppOption[];\n}\n\ntype AlertUnit = \"usd\" | \"builder-credits\" | \"tokens\";\ntype AlertChannel = \"in-app\" | \"email\";\n\ninterface AlertDraft {\n ruleId?: string;\n appId: string;\n unit: AlertUnit;\n period: \"day\" | \"month\";\n limit: string;\n inApp: boolean;\n email: boolean;\n}\n\nfunction asRules(value: unknown): UsageAlertRule[] {\n if (Array.isArray(value)) return value as UsageAlertRule[];\n if (value && typeof value === \"object\") {\n const rules = (value as { rules?: unknown }).rules;\n if (Array.isArray(rules)) return rules as UsageAlertRule[];\n }\n return [];\n}\n\nfunction formatAlertValue(rule: UsageAlertRule, value: number): string {\n if (rule.unit === \"usd\") {\n return value.toLocaleString(undefined, {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 2,\n });\n }\n return (\n value.toLocaleString(undefined, {\n maximumFractionDigits: rule.unit === \"builder-credits\" ? 2 : 0,\n }) +\n \" \" +\n (rule.unit === \"builder-credits\" ? \"credits\" : \"tokens\")\n );\n}\n\nfunction draftFromRule(rule: UsageAlertRule): AlertDraft {\n return {\n ruleId: rule.id,\n appId: rule.appId ?? \"\",\n unit: rule.unit,\n period: rule.period,\n limit: String(rule.limit),\n inApp: rule.channels.includes(\"in-app\"),\n email: rule.channels.includes(\"email\"),\n };\n}\n\nfunction defaultDraft(): AlertDraft {\n return {\n appId: \"\",\n unit: \"usd\",\n period: \"day\",\n limit: \"100\",\n inApp: true,\n email: true,\n };\n}\n\nfunction AlertEditor({\n draft,\n appOptions,\n isExisting,\n onChange,\n onSave,\n onCancel,\n isPending,\n}: {\n draft: AlertDraft;\n appOptions: UsageAlertAppOption[];\n isExisting: boolean;\n onChange: (patch: Partial<AlertDraft>) => void;\n onSave: () => void;\n onCancel: () => void;\n isPending: boolean;\n}) {\n const t = useT();\n\n return (\n <div className=\"grid gap-3 rounded-md border bg-background/60 p-3 sm:grid-cols-2 lg:grid-cols-5\">\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>App</span>\n <Select\n value={draft.appId || \"all\"}\n onValueChange={(value) =>\n onChange({ appId: value === \"all\" ? \"\" : value })\n }\n disabled={isExisting}\n >\n <SelectTrigger className=\"text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n {appOptions.map((app) => (\n <SelectItem key={app.id} value={app.id}>\n {app.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>Unit</span>\n <Select\n value={draft.unit}\n onValueChange={(value) => onChange({ unit: value as AlertUnit })}\n >\n <SelectTrigger className=\"text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"usd\">Dollars</SelectItem>\n <SelectItem value=\"builder-credits\">Credits</SelectItem>\n <SelectItem value=\"tokens\">Tokens</SelectItem>\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>{t(\"dispatch.pages.usageAlertThreshold\")}</span>\n <Input\n type=\"number\"\n min=\"0.01\"\n step={draft.unit === \"tokens\" ? \"1\" : \"0.01\"}\n value={draft.limit}\n onChange={(event) => onChange({ limit: event.target.value })}\n className=\"text-sm\"\n />\n </label>\n <label className=\"space-y-1.5 text-xs text-muted-foreground\">\n <span>Period</span>\n <Select\n value={draft.period}\n onValueChange={(value) =>\n onChange({ period: value as \"day\" | \"month\" })\n }\n >\n <SelectTrigger className=\"text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"day\">Per day</SelectItem>\n <SelectItem value=\"month\">Per month</SelectItem>\n </SelectContent>\n </Select>\n </label>\n <div className=\"flex flex-wrap items-end gap-3 pb-1 text-xs text-muted-foreground\">\n <label className=\"inline-flex items-center gap-2\">\n <Checkbox\n checked={draft.inApp}\n onCheckedChange={(checked) => onChange({ inApp: checked === true })}\n />\n In app\n </label>\n <label className=\"inline-flex items-center gap-2\">\n <Checkbox\n checked={draft.email}\n onCheckedChange={(checked) => onChange({ email: checked === true })}\n />\n Email\n </label>\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"ms-auto\"\n onClick={onSave}\n disabled={isPending}\n >\n Save\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n}\n\nexport function UsageAlertsPanel({\n scope,\n appOptions = [],\n}: UsageAlertsPanelProps) {\n const t = useT();\n const query = useActionQuery(\"get-usage-alerts\", { scope });\n const mutation = useActionMutation(\"manage-usage-alert\", {\n onSuccess: () => {\n setEditing(null);\n toast.success(\"Usage alert updated\");\n },\n onError: (error) => toast.error(String(error)),\n });\n const [editing, setEditing] = useState<AlertDraft | null>(null);\n const rules = asRules(query.data);\n const appLabels = useMemo(\n () => new Map(appOptions.map((app) => [app.id, app.label])),\n [appOptions],\n );\n\n function saveDraft() {\n if (!editing) return;\n const limit = Number(editing.limit);\n const channels: AlertChannel[] = [];\n if (editing.inApp) channels.push(\"in-app\");\n if (editing.email) channels.push(\"email\");\n if (!Number.isFinite(limit) || limit <= 0) {\n toast.error(\"Enter a positive threshold.\");\n return;\n }\n if (channels.length === 0) {\n toast.error(\"Choose at least one delivery channel.\");\n return;\n }\n mutation.mutate({\n operation: \"save\",\n scope,\n ruleId: editing.ruleId,\n appId: editing.appId || null,\n unit: editing.unit,\n period: editing.period,\n limit,\n channels,\n enabled: true,\n });\n }\n\n return (\n <section className=\"rounded-lg bg-card\">\n <div className=\"flex items-start justify-between gap-3 border-b px-4 py-3\">\n <div>\n <h2 className=\"text-sm font-semibold text-foreground\">\n Usage alerts\n </h2>\n <p className=\"mt-1 max-w-2xl text-xs leading-5 text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertDescription\")}\n </p>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setEditing(defaultDraft())}\n disabled={mutation.isPending}\n >\n Add alert\n </Button>\n </div>\n\n <div className=\"divide-y\">\n {query.isLoading && rules.length === 0 ? (\n <div className=\"space-y-3 px-4 py-5\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-2/3 max-w-sm\" />\n <Skeleton className=\"h-3 w-1/2 max-w-xs\" />\n </div>\n ))}\n </div>\n ) : null}\n {query.isError ? (\n <div className=\"px-4 py-6 text-sm text-destructive\">\n Usage alerts are unavailable for this scope.{\" \"}\n {query.error instanceof Error ? query.error.message : \"Try again.\"}\n </div>\n ) : null}\n {!query.isLoading && !query.isError && rules.length === 0 ? (\n <div className=\"px-4 py-6 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertEmpty\")}\n </div>\n ) : null}\n {rules.map((rule) => {\n const isEditing = editing?.ruleId === rule.id;\n const target = rule.appId\n ? appLabels.get(rule.appId) || rule.appId\n : \"All apps\";\n return (\n <div key={rule.id} className=\"px-4 py-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {target}\n </span>\n {rule.isDefault ? (\n <Badge variant=\"secondary\">Default</Badge>\n ) : null}\n <Badge\n variant={\n rule.status === \"triggered\" ? \"destructive\" : \"outline\"\n }\n >\n {rule.status === \"triggered\"\n ? t(\"dispatch.pages.usageAlertReached\")\n : rule.status === \"dismissed\"\n ? \"Dismissed\"\n : \"On track\"}\n </Badge>\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.usageAlertCurrentAndThreshold\", {\n current: formatAlertValue(rule, rule.current),\n threshold: formatAlertValue(rule, rule.limit),\n period: t(\n rule.period === \"day\"\n ? \"dispatch.pages.usageAlertDay\"\n : \"dispatch.pages.usageAlertMonth\",\n ),\n })}\n {rule.percent > 0 ? \" · \" + rule.percent + \"%\" : \"\"}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch\n checked={rule.enabled}\n onCheckedChange={(checked) =>\n mutation.mutate({\n operation: \"set-enabled\",\n scope,\n ruleId: rule.id,\n enabled: checked,\n })\n }\n aria-label={\n (rule.enabled ? \"Disable \" : \"Enable \") +\n target +\n \" usage alert\"\n }\n disabled={mutation.isPending}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setEditing(draftFromRule(rule))}\n aria-label={\"Edit \" + target + \" usage alert\"}\n disabled={mutation.isPending}\n >\n <IconPencil className=\"size-4\" />\n </Button>\n {rule.status === \"triggered\" ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() =>\n mutation.mutate({\n operation: \"dismiss\",\n scope,\n ruleId: rule.id,\n })\n }\n aria-label={\"Dismiss \" + target + \" usage alert\"}\n disabled={mutation.isPending}\n >\n <IconX className=\"size-4\" />\n </Button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n {rule.channels.includes(\"in-app\") ? (\n <span className=\"inline-flex items-center gap-1\">\n <IconBell className=\"size-3.5\" /> In app\n </span>\n ) : null}\n {rule.channels.includes(\"email\") ? (\n <span className=\"inline-flex items-center gap-1\">\n <IconMail className=\"size-3.5\" /> Email\n </span>\n ) : null}\n </div>\n {isEditing && editing ? (\n <div className=\"mt-4\">\n <AlertEditor\n draft={editing}\n appOptions={appOptions}\n isExisting\n onChange={(patch) =>\n setEditing((current) =>\n current ? { ...current, ...patch } : current,\n )\n }\n onSave={saveDraft}\n onCancel={() => setEditing(null)}\n isPending={mutation.isPending}\n />\n </div>\n ) : null}\n </div>\n );\n })}\n {editing && !editing.ruleId ? (\n <div className=\"px-4 py-4\">\n <AlertEditor\n draft={editing}\n appOptions={appOptions}\n isExisting={false}\n onChange={(patch) =>\n setEditing((current) =>\n current ? { ...current, ...patch } : current,\n )\n }\n onSave={saveDraft}\n onCancel={() => setEditing(null)}\n isPending={mutation.isPending}\n />\n </div>\n ) : null}\n </div>\n </section>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-app-search.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-search.tsx"],"names":[],"mappings":"AAQA,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAgDA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,mDAuBA"}
1
+ {"version":3,"file":"workspace-app-search.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-search.tsx"],"names":[],"mappings":"AAQA,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAiDA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,mDAuBA"}
@@ -14,7 +14,7 @@ export function WorkspaceAppSearch({ query, onQueryChange, className, }) {
14
14
  const placeholder = t("dispatch.pages.searchAppsPlaceholder", {
15
15
  defaultValue: "Search apps",
16
16
  });
17
- return (_jsxs("div", { role: "search", className: cn("flex items-center gap-2", className), children: [_jsxs("div", { className: "relative min-w-0 flex-1", children: [_jsx("label", { htmlFor: inputId, className: "sr-only", children: label }), _jsx(IconSearch, { size: 16, "aria-hidden": "true", className: "pointer-events-none absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { id: inputId, value: query, onChange: (event) => onQueryChange(event.target.value), placeholder: placeholder, className: "h-9 bg-background ps-9", autoComplete: "off" })] }), query ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "shrink-0 gap-1.5 text-muted-foreground", onClick: () => onQueryChange(""), children: [_jsx(IconX, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: t("dispatch.pages.clearAppSearch", {
17
+ return (_jsxs("div", { role: "search", className: cn("flex items-center gap-2", className), children: [_jsxs("div", { className: "relative min-w-0 flex-1", children: [_jsx("label", { htmlFor: inputId, className: "sr-only", children: label }), _jsx(IconSearch, { size: 16, "aria-hidden": "true", className: "pointer-events-none absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { id: inputId, size: "sm", value: query, onChange: (event) => onQueryChange(event.target.value), placeholder: placeholder, className: "bg-background ps-9", autoComplete: "off" })] }), query ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "shrink-0 gap-1.5 text-muted-foreground", onClick: () => onQueryChange(""), children: [_jsx(IconX, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: t("dispatch.pages.clearAppSearch", {
18
18
  defaultValue: "Clear",
19
19
  }) })] })) : null] }));
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-app-search.js","sourceRoot":"","sources":["../../src/components/workspace-app-search.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,SAAS,GAKV;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,CAAC,2BAA2B,EAAE;QAC3C,YAAY,EAAE,aAAa;KAC5B,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,CAAC,CAAC,sCAAsC,EAAE;QAC5D,YAAY,EAAE,aAAa;KAC5B,CAAC,CAAC;IAEH,OAAO,CACL,eAAK,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,aACpE,eAAK,SAAS,EAAC,yBAAyB,aACtC,gBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,SAAS,YACzC,KAAK,GACA,EACR,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,iBACI,MAAM,EAClB,SAAS,EAAC,qFAAqF,GAC/F,EACF,KAAC,KAAK,IACJ,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,wBAAwB,EAClC,YAAY,EAAC,KAAK,GAClB,IACE,EACL,KAAK,CAAC,CAAC,CAAC,CACP,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,wCAAwC,EAClD,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,aAEhC,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,EACtC,yBACG,CAAC,CAAC,+BAA+B,EAAE;4BAClC,YAAY,EAAE,OAAO;yBACtB,CAAC,GACG,IACA,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACtC,KAAK,EACL,OAAO,GAIR;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,+DAA+D,aAC5E,YAAG,SAAS,EAAC,qCAAqC,YAC/C,CAAC,CAAC,4BAA4B,EAAE;oBAC/B,YAAY,EAAE,2BAA2B;iBAC1C,CAAC,GACA,EACJ,aAAG,SAAS,EAAC,8DAA8D,uBACvE,KAAK,cACL,EACJ,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,OAAO,YAEf,CAAC,CAAC,+BAA+B,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,GAC9D,IACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { IconSearch, IconX } from \"@tabler/icons-react\";\nimport { useId } from \"react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\n\nexport function WorkspaceAppSearch({\n query,\n onQueryChange,\n className,\n}: {\n query: string;\n onQueryChange: (query: string) => void;\n className?: string;\n}) {\n const t = useT();\n const inputId = useId();\n const label = t(\"dispatch.pages.searchApps\", {\n defaultValue: \"Search apps\",\n });\n const placeholder = t(\"dispatch.pages.searchAppsPlaceholder\", {\n defaultValue: \"Search apps\",\n });\n\n return (\n <div role=\"search\" className={cn(\"flex items-center gap-2\", className)}>\n <div className=\"relative min-w-0 flex-1\">\n <label htmlFor={inputId} className=\"sr-only\">\n {label}\n </label>\n <IconSearch\n size={16}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n id={inputId}\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n placeholder={placeholder}\n className=\"h-9 bg-background ps-9\"\n autoComplete=\"off\"\n />\n </div>\n {query ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"shrink-0 gap-1.5 text-muted-foreground\"\n onClick={() => onQueryChange(\"\")}\n >\n <IconX size={14} aria-hidden=\"true\" />\n <span>\n {t(\"dispatch.pages.clearAppSearch\", {\n defaultValue: \"Clear\",\n })}\n </span>\n </Button>\n ) : null}\n </div>\n );\n}\n\nexport function WorkspaceAppSearchEmpty({\n query,\n onClear,\n}: {\n query: string;\n onClear: () => void;\n}) {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-8 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noAppsMatch\", {\n defaultValue: \"No apps match your search\",\n })}\n </p>\n <p className=\"mx-auto mt-1 max-w-md truncate text-xs text-muted-foreground\">\n “{query}”\n </p>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-4\"\n onClick={onClear}\n >\n {t(\"dispatch.pages.clearAppSearch\", { defaultValue: \"Clear search\" })}\n </Button>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace-app-search.js","sourceRoot":"","sources":["../../src/components/workspace-app-search.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,SAAS,GAKV;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,CAAC,2BAA2B,EAAE;QAC3C,YAAY,EAAE,aAAa;KAC5B,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,CAAC,CAAC,sCAAsC,EAAE;QAC5D,YAAY,EAAE,aAAa;KAC5B,CAAC,CAAC;IAEH,OAAO,CACL,eAAK,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,aACpE,eAAK,SAAS,EAAC,yBAAyB,aACtC,gBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,SAAS,YACzC,KAAK,GACA,EACR,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,iBACI,MAAM,EAClB,SAAS,EAAC,qFAAqF,GAC/F,EACF,KAAC,KAAK,IACJ,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,oBAAoB,EAC9B,YAAY,EAAC,KAAK,GAClB,IACE,EACL,KAAK,CAAC,CAAC,CAAC,CACP,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,wCAAwC,EAClD,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,aAEhC,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,EACtC,yBACG,CAAC,CAAC,+BAA+B,EAAE;4BAClC,YAAY,EAAE,OAAO;yBACtB,CAAC,GACG,IACA,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACtC,KAAK,EACL,OAAO,GAIR;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,+DAA+D,aAC5E,YAAG,SAAS,EAAC,qCAAqC,YAC/C,CAAC,CAAC,4BAA4B,EAAE;oBAC/B,YAAY,EAAE,2BAA2B;iBAC1C,CAAC,GACA,EACJ,aAAG,SAAS,EAAC,8DAA8D,uBACvE,KAAK,cACL,EACJ,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,MAAM,EAChB,OAAO,EAAE,OAAO,YAEf,CAAC,CAAC,+BAA+B,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,GAC9D,IACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { IconSearch, IconX } from \"@tabler/icons-react\";\nimport { useId } from \"react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\n\nexport function WorkspaceAppSearch({\n query,\n onQueryChange,\n className,\n}: {\n query: string;\n onQueryChange: (query: string) => void;\n className?: string;\n}) {\n const t = useT();\n const inputId = useId();\n const label = t(\"dispatch.pages.searchApps\", {\n defaultValue: \"Search apps\",\n });\n const placeholder = t(\"dispatch.pages.searchAppsPlaceholder\", {\n defaultValue: \"Search apps\",\n });\n\n return (\n <div role=\"search\" className={cn(\"flex items-center gap-2\", className)}>\n <div className=\"relative min-w-0 flex-1\">\n <label htmlFor={inputId} className=\"sr-only\">\n {label}\n </label>\n <IconSearch\n size={16}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n id={inputId}\n size=\"sm\"\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n placeholder={placeholder}\n className=\"bg-background ps-9\"\n autoComplete=\"off\"\n />\n </div>\n {query ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"shrink-0 gap-1.5 text-muted-foreground\"\n onClick={() => onQueryChange(\"\")}\n >\n <IconX size={14} aria-hidden=\"true\" />\n <span>\n {t(\"dispatch.pages.clearAppSearch\", {\n defaultValue: \"Clear\",\n })}\n </span>\n </Button>\n ) : null}\n </div>\n );\n}\n\nexport function WorkspaceAppSearchEmpty({\n query,\n onClear,\n}: {\n query: string;\n onClear: () => void;\n}) {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-8 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noAppsMatch\", {\n defaultValue: \"No apps match your search\",\n })}\n </p>\n <p className=\"mx-auto mt-1 max-w-md truncate text-xs text-muted-foreground\">\n “{query}”\n </p>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-4\"\n onClick={onClear}\n >\n {t(\"dispatch.pages.clearAppSearch\", { defaultValue: \"Clear search\" })}\n </Button>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,IAAI;;IAEnB;AAkGD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDAqQvC"}
1
+ {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,IAAI;;IAEnB;AAkGD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDAuQvC"}
@@ -118,10 +118,10 @@ export default function AutomationsRoute() {
118
118
  next.set("automationId", automationIdentity(item));
119
119
  setSearchParams(next);
120
120
  }
121
- return (_jsx(DispatchShell, { title: "Automations", description: "Create schedule, webhook, or app-event automations, then inspect their checks and past runs.", children: _jsxs("section", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-3", children: [_jsxs("div", { className: "relative w-full max-w-sm", children: [_jsx(IconSearch, { size: 15, "aria-hidden": "true", className: "pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search automations", "aria-label": "Search automations", className: "h-8 pl-8 text-xs" })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(IconSettingsAutomation, { size: 16, className: "shrink-0" }), _jsxs("span", { children: [enabledCount, " enabled", errorCount > 0 ? ` · ${errorCount} errors` : ""] })] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsxs(Select, { value: view, onValueChange: (value) => {
121
+ return (_jsx(DispatchShell, { title: "Automations", description: "Create schedule, webhook, or app-event automations, then inspect their checks and past runs.", children: _jsxs("section", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-3", children: [_jsxs("div", { className: "relative w-full max-w-sm", children: [_jsx(IconSearch, { size: 15, "aria-hidden": "true", className: "pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { size: "sm", value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search automations", "aria-label": "Search automations", className: "pl-8 text-xs" })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(IconSettingsAutomation, { size: 16, className: "shrink-0" }), _jsxs("span", { children: [enabledCount, " enabled", errorCount > 0 ? ` · ${errorCount} errors` : ""] })] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsxs(Select, { value: view, onValueChange: (value) => {
122
122
  if (value === "dispatch" || value === "all")
123
123
  setView(value);
124
- }, children: [_jsx(SelectTrigger, { className: "h-8 w-[10.5rem] text-xs", "aria-label": "Automation view", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "dispatch", children: "Dispatch automations" }), _jsx(SelectItem, { value: "all", children: "All apps" })] })] }), _jsx(CreateAutomationButton, { onCreated: () => {
124
+ }, children: [_jsx(SelectTrigger, { size: "sm", className: "w-[10.5rem] text-xs", "aria-label": "Automation view", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "dispatch", children: "Dispatch automations" }), _jsx(SelectItem, { value: "all", children: "All apps" })] })] }), _jsx(CreateAutomationButton, { onCreated: () => {
125
125
  toast.success("Automation created");
126
126
  void queryClient.invalidateQueries({
127
127
  queryKey: AUTOMATIONS_QUERY_KEY,
@@ -1 +1 @@
1
- {"version":3,"file":"automations.js","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EACL,cAAc,EACd,eAAe,EACf,QAAQ,EACR,UAAU,EACV,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EACL,MAAM,EACN,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAEhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAG7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAErC,MAAM,qBAAqB,GAAG,CAAC,sBAAsB,CAAU,CAAC;AAEhE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,IAAI,EAAkC;IACzD,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,8BAA8B,EAC9B,IAAI,KAAK,SAAS,IAAI,gBAAgB,EACtC,IAAI,KAAK,SAAS,IAAI,cAAc,EACpC,IAAI,KAAK,QAAQ,IAAI,gBAAgB,EACrC,IAAI,KAAK,OAAO,IAAI,wBAAwB,EAC5C,IAAI,KAAK,SAAS,IAAI,YAAY,CACnC,GACD,CACH,CAAC;AACJ,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAChE,OAAO,QAAQ,CAA2B;QACxC,QAAQ,EAAE,CAAC,GAAG,qBAAqB,EAAE,OAAO,CAAC;QAC7C,OAAO,EAAE,uBAAuB;QAChC,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QAC/B,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,4BAA4B;QACxC,QAAQ,EAAE,KAAK,EAAE,KAAwC,EAAE,EAAE;YAC3D,MAAM,WAAW,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,WAAW,CAAC,cAAc,CAA2B;gBACrE,QAAQ,EAAE,qBAAqB;aAChC,CAAC,CAAC;YAEH,WAAW,CAAC,cAAc,CACxB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,EACnC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjB,kBAAkB,CAAC,IAAI,CAAC,KAAK,kBAAkB,CAAC,KAAK,CAAC;gBACpD,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;gBACrC,CAAC,CAAC,IAAI,CACT,CACJ,CAAC;YAEF,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YAChC,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;gBACxD,WAAW,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC3C,CAAC;YACD,KAAK,CAAC,KAAK,CACT,gCACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;QACJ,CAAC;QACD,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,WAAW,CAAC,cAAc,CACxB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,EACnC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjB,kBAAkB,CAAC,IAAI,CAAC,KAAK,kBAAkB,CAAC,OAAO,CAAC;gBACtD,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CACT,CACJ,CAAC;QACJ,CAAC;QACD,SAAS,EAAE,GAAG,EAAE;YACd,KAAK,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAC1E,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,sBAAsB,CAAC,EAAE,SAAS,EAA6B;IACtE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO,CACL,8BACE,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,aAC5C,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,GAAI,sBAEf,EACT,KAAC,sBAAsB,IACrB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,GAAG,EAAE;oBACd,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,SAAS,EAAE,CAAC;gBACd,CAAC,GACD,IACD,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB;IACtC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAe,EAAE,CAAC;IAC1D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAqB,UAAU,CAAC,CAAC;IACjE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,cAAc,EAAE,CAAC;IAC1C,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAC/C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,IAAI,EAAE,CAAC;IAChD,MAAM,kBAAkB,GAAG,OAAO,CAChC,GAAG,EAAE,CACH,IAAI,KAAK,KAAK;QACZ,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAC3D,CAAC,WAAW,EAAE,IAAI,CAAC,CACpB,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,EACzC,CAAC,kBAAkB,CAAC,CACrB,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC7B;YACE,IAAI,CAAC,IAAI;YACT,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,QAAQ;YACb,IAAI,CAAC,mBAAmB;YACxB,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,IAAI;YACT,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,MAAM;SACZ;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC;aACT,WAAW,EAAE;aACb,QAAQ,CAAC,UAAU,CAAC,CACxB,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACrB,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC9E,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAC1C,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,OAAO;QACZ,CAAC,IAAI,CAAC,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CACjE,CAAC,MAAM,CAAC;IACT,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,SAAS;QACtD,CAAC,CAAC,gBAAgB,CAAC,SAAS;YAC1B,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,SAAS,CAAC;YAChD,CAAC,CAAC,IAAI;QACR,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,oBAAoB,GAAG,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,oBAAoB;QACxC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CACZ,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,oBAAoB,CAC5D,IAAI,IAAI,CAAC;QACZ,CAAC,CAAC,IAAI,CAAC;IAET,SAAS,gBAAgB,CAAC,IAA4B;QACpD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QACnD,eAAe,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAC,aAAa,EACnB,WAAW,EAAC,8FAA8F,YAE1G,mBAAS,SAAS,EAAC,qBAAqB,aACtC,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,kDAAkD,aAC/D,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,iBACI,MAAM,EAClB,SAAS,EAAC,sFAAsF,GAChG,EACF,KAAC,KAAK,IACJ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACjD,WAAW,EAAC,oBAAoB,gBACrB,oBAAoB,EAC/B,SAAS,EAAC,kBAAkB,GAC5B,IACE,EACN,eAAK,SAAS,EAAC,uDAAuD,aACpE,KAAC,sBAAsB,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,UAAU,GAAG,EACzD,2BACG,YAAY,cACZ,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,UAAU,SAAS,CAAC,CAAC,CAAC,EAAE,IAC3C,IACH,IACF,EACN,eAAK,SAAS,EAAC,+CAA+C,aAC5D,MAAC,MAAM,IACL,KAAK,EAAE,IAAI,EACX,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;wCACvB,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK;4CAAE,OAAO,CAAC,KAAK,CAAC,CAAC;oCAC9D,CAAC,aAED,KAAC,aAAa,IACZ,SAAS,EAAC,yBAAyB,gBACxB,iBAAiB,YAE5B,KAAC,WAAW,KAAG,GACD,EAChB,MAAC,aAAa,eACZ,KAAC,UAAU,IAAC,KAAK,EAAC,UAAU,qCAAkC,EAC9D,KAAC,UAAU,IAAC,KAAK,EAAC,KAAK,yBAAsB,IAC/B,IACT,EACT,KAAC,sBAAsB,IACrB,SAAS,EAAE,GAAG,EAAE;wCACd,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;wCACpC,KAAK,WAAW,CAAC,iBAAiB,CAAC;4CACjC,QAAQ,EAAE,qBAAqB;yCAChC,CAAC,CAAC;oCACL,CAAC,GACD,IACE,IACF,EAEN,eAAK,SAAS,EAAC,6DAA6D,aAC1E,cAAK,SAAS,EAAC,qCAAqC,YACjD,gBAAgB,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACpD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1C,eAAiB,SAAS,EAAC,WAAW,aACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,KAF9B,KAAK,CAGT,CACP,CAAC,CACH,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gCACpB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;gCACtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;gCAC3C,MAAM,UAAU,GACd,qBAAqB,KAAK,kBAAkB,CAAC,IAAI,CAAC,CAAC;gCACrD,MAAM,UAAU,GACd,aAAa,KAAK,IAAI;oCACtB,kBAAkB,CAAC,aAAa,CAAC;wCAC/B,kBAAkB,CAAC,IAAI,CAAC,CAAC;gCAC7B,OAAO,CACL,eAEE,SAAS,EAAE,EAAE,CACX,uEAAuE,EACvE,UAAU,IAAI,cAAc,CAC7B,aAED,eAAK,SAAS,EAAC,SAAS,aACtB,kBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,8JAA8J,kBAC1J,UAAU,EACxB,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAErC,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,SAAS,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAI,EAChC,eAAM,SAAS,EAAC,8CAA8C,YAC3D,IAAI,CAAC,IAAI,GACL,IACH,EACN,cAAK,SAAS,EAAC,6CAA6C,YACzD,gBAAgB,CAAC,IAAI,CAAC,GACnB,EACN,eAAK,SAAS,EAAC,uEAAuE,aACpF,oCAAY,iBAAiB,CAAC,IAAI,CAAC,IAAQ,EAC3C,oCAAY,iBAAiB,CAAC,IAAI,CAAC,IAAQ,EAC3C,yBAAO,oBAAoB,CAAC,IAAI,CAAC,GAAQ,EACxC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAChB,uCAAe,mBAAmB,CAAC,IAAI,CAAC,IAAQ,CACjD,CAAC,CAAC,CAAC,IAAI,IACJ,IACC,EACR,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAChB,eAAK,SAAS,EAAC,6EAA6E,aAC1F,eAAM,SAAS,EAAC,qBAAqB,YAClC,IAAI,CAAC,SAAS,GACV,EACP,MAAC,IAAI,IACH,EAAE,EAAE,0BAA0B,CAAC,IAAI,CAAC,EACpC,SAAS,EAAC,wGAAwG,gBACtG,gBAAgB,IAAI,CAAC,IAAI,kBAAkB,aAEvD,KAAC,cAAc,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,oCAE1C,IACH,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,eAAK,SAAS,EAAC,+BAA+B,aAC5C,KAAC,KAAK,IACJ,OAAO,EACL,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAEtD,SAAS,EAAC,KAAK,YAEd,MAAM,CAAC,KAAK,GACP,EACR,KAAC,MAAM,IACL,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EACvB,QAAQ,EAAE,CAAC,SAAS,IAAI,UAAU,gBACtB,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,eAAe,IAAI,CAAC,IAAI,EAAE,EAC5E,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE,CAC3B,gBAAgB,CAAC,MAAM,CAAC;wDACtB,KAAK,EAAE,IAAI,CAAC,KAAK;wDACjB,IAAI,EAAE,IAAI,CAAC,IAAI;wDACf,OAAO,EAAE,OAAO;qDACjB,CAAC,GAEJ,IACE,KApED,IAAI,CAAC,EAAE,CAqER,CACP,CAAC;4BACJ,CAAC,CAAC,CACH,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,sDAAsD,YAClE,KAAK;oCACJ,CAAC,CAAC,0BAA0B;oCAC5B,CAAC,CAAC,IAAI,KAAK,KAAK;wCACd,CAAC,CAAC,oGAAoG;wCACtG,CAAC,CAAC,mFAAmF,GACrF,CACP,GACG,EAEL,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,sBAAsB,IACrB,UAAU,EAAE,aAAa,EACzB,UAAU,EACR,qBAAqB,KAAK,kBAAkB,CAAC,aAAa,CAAC,EAE7D,QAAQ,EAAE,GAAG,EAAE,CACb,gBAAgB,CAAC,MAAM,CAAC;gCACtB,KAAK,EAAE,aAAa,CAAC,KAAK;gCAC1B,IAAI,EAAE,aAAa,CAAC,IAAI;gCACxB,OAAO,EAAE,CAAC,aAAa,CAAC,OAAO;6BAChC,CAAC,GAEJ,CACH,CAAC,CAAC,CAAC,CACF,eAAK,SAAS,EAAC,iHAAiH,aAC9H,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,WAAW,EAAE,GAAG,EAChB,SAAS,EAAC,uBAAuB,GACjC,EACF,YAAG,SAAS,EAAC,0CAA0C,qCAEnD,EACJ,YAAG,SAAS,EAAC,6CAA6C,kFAGtD,IACA,CACP,IACG,IACE,GACI,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { useChangeVersions } from \"@agent-native/core/client/hooks\";\nimport {\n IconFileSearch,\n IconListDetails,\n IconPlus,\n IconSearch,\n IconSettingsAutomation,\n} from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { Link, useSearchParams } from \"react-router\";\nimport { toast } from \"sonner\";\n\nimport { AutomationCreateDialog } from \"../../components/automation-create-dialog\";\nimport { AutomationDetailsPanel } from \"../../components/automation-details-panel\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastCheck,\n automationLastRun,\n automationNextRun,\n automationScopeLabel,\n automationStatus,\n automationTarget,\n automationTroubleshootPath,\n belongsToDispatch,\n sortAutomations,\n type AutomationStatusTone,\n} from \"../../lib/automation-display\";\nimport {\n listDispatchAutomations,\n setDispatchAutomationEnabled,\n type DispatchAutomationItem,\n type SetDispatchAutomationEnabledInput,\n} from \"../../lib/automations\";\nimport { cn } from \"../../lib/utils\";\n\nconst AUTOMATIONS_QUERY_KEY = [\"dispatch-automations\"] as const;\n\nexport function meta() {\n return [{ title: \"Automations — Dispatch\" }];\n}\n\nfunction StatusDot({ tone }: { tone: AutomationStatusTone }) {\n return (\n <span\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n tone === \"success\" && \"bg-emerald-500\",\n tone === \"warning\" && \"bg-amber-500\",\n tone === \"danger\" && \"bg-destructive\",\n tone === \"muted\" && \"bg-muted-foreground/35\",\n tone === \"default\" && \"bg-primary\",\n )}\n />\n );\n}\n\nfunction useAutomations() {\n const version = useChangeVersions([\"action\", \"screen-refresh\"]);\n return useQuery<DispatchAutomationItem[]>({\n queryKey: [...AUTOMATIONS_QUERY_KEY, version],\n queryFn: listDispatchAutomations,\n placeholderData: (prev) => prev,\n staleTime: 5_000,\n });\n}\n\nfunction useToggleAutomation() {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: setDispatchAutomationEnabled,\n onMutate: async (input: SetDispatchAutomationEnabledInput) => {\n await queryClient.cancelQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n const snapshots = queryClient.getQueriesData<DispatchAutomationItem[]>({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(input)\n ? { ...item, enabled: input.enabled }\n : item,\n ),\n );\n\n return { snapshots };\n },\n onError: (err, _input, context) => {\n for (const [queryKey, data] of context?.snapshots ?? []) {\n queryClient.setQueryData(queryKey, data);\n }\n toast.error(\n `Could not update automation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n },\n onSuccess: (updated) => {\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(updated)\n ? updated\n : item,\n ),\n );\n },\n onSettled: () => {\n void queryClient.invalidateQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n },\n });\n}\n\nfunction CreateAutomationButton({ onCreated }: { onCreated: () => void }) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <IconPlus size={14} />\n New automation\n </Button>\n <AutomationCreateDialog\n open={open}\n onOpenChange={setOpen}\n onCreated={() => {\n setOpen(false);\n onCreated();\n }}\n />\n </>\n );\n}\n\nexport default function AutomationsRoute() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [view, setView] = useState<\"dispatch\" | \"all\">(\"dispatch\");\n const [query, setQuery] = useState(\"\");\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const queryClient = useQueryClient();\n const automations = automationsQuery.data ?? [];\n const visibleAutomations = useMemo(\n () =>\n view === \"all\"\n ? automations\n : automations.filter((item) => belongsToDispatch(item)),\n [automations, view],\n );\n const ordered = useMemo(\n () => sortAutomations(visibleAutomations),\n [visibleAutomations],\n );\n const filtered = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return ordered;\n return ordered.filter((item) =>\n [\n item.name,\n item.event,\n item.schedule,\n item.scheduleDescription,\n item.webhookPath,\n item.body,\n item.model,\n item.domain,\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase()\n .includes(normalized),\n );\n }, [ordered, query]);\n const enabledCount = visibleAutomations.filter((item) => item.enabled).length;\n const errorCount = visibleAutomations.filter(\n (item) =>\n item.enabled &&\n (item.lastStatus === \"error\" || item.lastStatus === \"skipped\"),\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n const selectedAutomationId = searchParams.get(\"automationId\");\n const detailsTarget = selectedAutomationId\n ? (filtered.find(\n (item) => automationIdentity(item) === selectedAutomationId,\n ) ?? null)\n : null;\n\n function selectAutomation(item: DispatchAutomationItem) {\n const next = new URLSearchParams(searchParams);\n next.set(\"automationId\", automationIdentity(item));\n setSearchParams(next);\n }\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"Create schedule, webhook, or app-event automations, then inspect their checks and past runs.\"\n >\n <section className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-3\">\n <div className=\"relative w-full max-w-sm\">\n <IconSearch\n size={15}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search automations\"\n aria-label=\"Search automations\"\n className=\"h-8 pl-8 text-xs\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconSettingsAutomation size={16} className=\"shrink-0\" />\n <span>\n {enabledCount} enabled\n {errorCount > 0 ? ` · ${errorCount} errors` : \"\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <Select\n value={view}\n onValueChange={(value) => {\n if (value === \"dispatch\" || value === \"all\") setView(value);\n }}\n >\n <SelectTrigger\n className=\"h-8 w-[10.5rem] text-xs\"\n aria-label=\"Automation view\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"dispatch\">Dispatch automations</SelectItem>\n <SelectItem value=\"all\">All apps</SelectItem>\n </SelectContent>\n </Select>\n <CreateAutomationButton\n onCreated={() => {\n toast.success(\"Automation created\");\n void queryClient.invalidateQueries({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(24rem,32rem)]\">\n <div className=\"min-w-0 divide-y rounded-lg bg-card\">\n {automationsQuery.isLoading && ordered.length === 0 ? (\n Array.from({ length: 4 }).map((_, index) => (\n <div key={index} className=\"px-4 py-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-28\" />\n </div>\n ))\n ) : filtered.length > 0 ? (\n filtered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n const isSelected =\n detailsTarget !== null &&\n automationIdentity(detailsTarget) ===\n automationIdentity(item);\n return (\n <div\n key={item.id}\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors\",\n isSelected && \"bg-accent/40\",\n )}\n >\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card\"\n aria-pressed={isSelected}\n onClick={() => selectAutomation(item)}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <StatusDot tone={status.tone} />\n <span className=\"truncate text-sm font-medium text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"mt-1 truncate text-xs text-muted-foreground\">\n {automationTarget(item)}\n </div>\n <div className=\"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground\">\n <span>Last {automationLastRun(item)}</span>\n <span>Next {automationNextRun(item)}</span>\n <span>{automationScopeLabel(item)}</span>\n {item.lastCheck ? (\n <span>Checked {automationLastCheck(item)}</span>\n ) : null}\n </div>\n </button>\n {item.lastError ? (\n <div className=\"mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs text-destructive\">\n <span className=\"min-w-0 break-words\">\n {item.lastError}\n </span>\n <Link\n to={automationTroubleshootPath(item)}\n className=\"inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline\"\n aria-label={`Troubleshoot ${item.name} in Thread Debug`}\n >\n <IconFileSearch size={13} aria-hidden=\"true\" />\n Troubleshoot in Thread Debug\n </Link>\n </div>\n ) : null}\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge\n variant={\n status.tone === \"danger\" ? \"destructive\" : \"outline\"\n }\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n <Switch\n checked={!!item.enabled}\n disabled={!canUpdate || isToggling}\n aria-label={`${item.enabled ? \"Disable\" : \"Enable\"} automation ${item.name}`}\n onCheckedChange={(checked) =>\n toggleAutomation.mutate({\n owner: item.owner,\n path: item.path,\n enabled: checked,\n })\n }\n />\n </div>\n </div>\n );\n })\n ) : (\n <div className=\"px-4 py-10 text-center text-sm text-muted-foreground\">\n {query\n ? \"No matching automations.\"\n : view === \"all\"\n ? \"No automations yet. Create one here, or ask Dispatch to set up a scheduled or event-triggered job.\"\n : \"No Dispatch automations yet. Switch to All apps to inspect workspace automations.\"}\n </div>\n )}\n </div>\n\n {detailsTarget ? (\n <AutomationDetailsPanel\n automation={detailsTarget}\n isToggling={\n pendingToggleIdentity === automationIdentity(detailsTarget)\n }\n onToggle={() =>\n toggleAutomation.mutate({\n owner: detailsTarget.owner,\n path: detailsTarget.path,\n enabled: !detailsTarget.enabled,\n })\n }\n />\n ) : (\n <div className=\"flex min-h-[34rem] flex-col items-center justify-center rounded-lg border border-dashed bg-card p-6 text-center\">\n <IconListDetails\n size={24}\n strokeWidth={1.6}\n className=\"text-muted-foreground\"\n />\n <p className=\"mt-3 text-sm font-medium text-foreground\">\n Select an automation\n </p>\n <p className=\"mt-1 max-w-xs text-sm text-muted-foreground\">\n Inspect its prompt, configuration, capabilities, and run\n history.\n </p>\n </div>\n )}\n </div>\n </section>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"automations.js","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useChangeVersions } from \"@agent-native/core/client/hooks\";\nimport {\n IconFileSearch,\n IconListDetails,\n IconPlus,\n IconSearch,\n IconSettingsAutomation,\n} from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { Link, useSearchParams } from \"react-router\";\nimport { toast } from \"sonner\";\n\nimport { AutomationCreateDialog } from \"../../components/automation-create-dialog\";\nimport { AutomationDetailsPanel } from \"../../components/automation-details-panel\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastCheck,\n automationLastRun,\n automationNextRun,\n automationScopeLabel,\n automationStatus,\n automationTarget,\n automationTroubleshootPath,\n belongsToDispatch,\n sortAutomations,\n type AutomationStatusTone,\n} from \"../../lib/automation-display\";\nimport {\n listDispatchAutomations,\n setDispatchAutomationEnabled,\n type DispatchAutomationItem,\n type SetDispatchAutomationEnabledInput,\n} from \"../../lib/automations\";\nimport { cn } from \"../../lib/utils\";\n\nconst AUTOMATIONS_QUERY_KEY = [\"dispatch-automations\"] as const;\n\nexport function meta() {\n return [{ title: \"Automations — Dispatch\" }];\n}\n\nfunction StatusDot({ tone }: { tone: AutomationStatusTone }) {\n return (\n <span\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n tone === \"success\" && \"bg-emerald-500\",\n tone === \"warning\" && \"bg-amber-500\",\n tone === \"danger\" && \"bg-destructive\",\n tone === \"muted\" && \"bg-muted-foreground/35\",\n tone === \"default\" && \"bg-primary\",\n )}\n />\n );\n}\n\nfunction useAutomations() {\n const version = useChangeVersions([\"action\", \"screen-refresh\"]);\n return useQuery<DispatchAutomationItem[]>({\n queryKey: [...AUTOMATIONS_QUERY_KEY, version],\n queryFn: listDispatchAutomations,\n placeholderData: (prev) => prev,\n staleTime: 5_000,\n });\n}\n\nfunction useToggleAutomation() {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: setDispatchAutomationEnabled,\n onMutate: async (input: SetDispatchAutomationEnabledInput) => {\n await queryClient.cancelQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n const snapshots = queryClient.getQueriesData<DispatchAutomationItem[]>({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(input)\n ? { ...item, enabled: input.enabled }\n : item,\n ),\n );\n\n return { snapshots };\n },\n onError: (err, _input, context) => {\n for (const [queryKey, data] of context?.snapshots ?? []) {\n queryClient.setQueryData(queryKey, data);\n }\n toast.error(\n `Could not update automation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n },\n onSuccess: (updated) => {\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(updated)\n ? updated\n : item,\n ),\n );\n },\n onSettled: () => {\n void queryClient.invalidateQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n },\n });\n}\n\nfunction CreateAutomationButton({ onCreated }: { onCreated: () => void }) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <IconPlus size={14} />\n New automation\n </Button>\n <AutomationCreateDialog\n open={open}\n onOpenChange={setOpen}\n onCreated={() => {\n setOpen(false);\n onCreated();\n }}\n />\n </>\n );\n}\n\nexport default function AutomationsRoute() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [view, setView] = useState<\"dispatch\" | \"all\">(\"dispatch\");\n const [query, setQuery] = useState(\"\");\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const queryClient = useQueryClient();\n const automations = automationsQuery.data ?? [];\n const visibleAutomations = useMemo(\n () =>\n view === \"all\"\n ? automations\n : automations.filter((item) => belongsToDispatch(item)),\n [automations, view],\n );\n const ordered = useMemo(\n () => sortAutomations(visibleAutomations),\n [visibleAutomations],\n );\n const filtered = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return ordered;\n return ordered.filter((item) =>\n [\n item.name,\n item.event,\n item.schedule,\n item.scheduleDescription,\n item.webhookPath,\n item.body,\n item.model,\n item.domain,\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase()\n .includes(normalized),\n );\n }, [ordered, query]);\n const enabledCount = visibleAutomations.filter((item) => item.enabled).length;\n const errorCount = visibleAutomations.filter(\n (item) =>\n item.enabled &&\n (item.lastStatus === \"error\" || item.lastStatus === \"skipped\"),\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n const selectedAutomationId = searchParams.get(\"automationId\");\n const detailsTarget = selectedAutomationId\n ? (filtered.find(\n (item) => automationIdentity(item) === selectedAutomationId,\n ) ?? null)\n : null;\n\n function selectAutomation(item: DispatchAutomationItem) {\n const next = new URLSearchParams(searchParams);\n next.set(\"automationId\", automationIdentity(item));\n setSearchParams(next);\n }\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"Create schedule, webhook, or app-event automations, then inspect their checks and past runs.\"\n >\n <section className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-3\">\n <div className=\"relative w-full max-w-sm\">\n <IconSearch\n size={15}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n size=\"sm\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search automations\"\n aria-label=\"Search automations\"\n className=\"pl-8 text-xs\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconSettingsAutomation size={16} className=\"shrink-0\" />\n <span>\n {enabledCount} enabled\n {errorCount > 0 ? ` · ${errorCount} errors` : \"\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <Select\n value={view}\n onValueChange={(value) => {\n if (value === \"dispatch\" || value === \"all\") setView(value);\n }}\n >\n <SelectTrigger\n size=\"sm\"\n className=\"w-[10.5rem] text-xs\"\n aria-label=\"Automation view\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"dispatch\">Dispatch automations</SelectItem>\n <SelectItem value=\"all\">All apps</SelectItem>\n </SelectContent>\n </Select>\n <CreateAutomationButton\n onCreated={() => {\n toast.success(\"Automation created\");\n void queryClient.invalidateQueries({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(24rem,32rem)]\">\n <div className=\"min-w-0 divide-y rounded-lg bg-card\">\n {automationsQuery.isLoading && ordered.length === 0 ? (\n Array.from({ length: 4 }).map((_, index) => (\n <div key={index} className=\"px-4 py-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-28\" />\n </div>\n ))\n ) : filtered.length > 0 ? (\n filtered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n const isSelected =\n detailsTarget !== null &&\n automationIdentity(detailsTarget) ===\n automationIdentity(item);\n return (\n <div\n key={item.id}\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors\",\n isSelected && \"bg-accent/40\",\n )}\n >\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card\"\n aria-pressed={isSelected}\n onClick={() => selectAutomation(item)}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <StatusDot tone={status.tone} />\n <span className=\"truncate text-sm font-medium text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"mt-1 truncate text-xs text-muted-foreground\">\n {automationTarget(item)}\n </div>\n <div className=\"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground\">\n <span>Last {automationLastRun(item)}</span>\n <span>Next {automationNextRun(item)}</span>\n <span>{automationScopeLabel(item)}</span>\n {item.lastCheck ? (\n <span>Checked {automationLastCheck(item)}</span>\n ) : null}\n </div>\n </button>\n {item.lastError ? (\n <div className=\"mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs text-destructive\">\n <span className=\"min-w-0 break-words\">\n {item.lastError}\n </span>\n <Link\n to={automationTroubleshootPath(item)}\n className=\"inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline\"\n aria-label={`Troubleshoot ${item.name} in Thread Debug`}\n >\n <IconFileSearch size={13} aria-hidden=\"true\" />\n Troubleshoot in Thread Debug\n </Link>\n </div>\n ) : null}\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge\n variant={\n status.tone === \"danger\" ? \"destructive\" : \"outline\"\n }\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n <Switch\n checked={!!item.enabled}\n disabled={!canUpdate || isToggling}\n aria-label={`${item.enabled ? \"Disable\" : \"Enable\"} automation ${item.name}`}\n onCheckedChange={(checked) =>\n toggleAutomation.mutate({\n owner: item.owner,\n path: item.path,\n enabled: checked,\n })\n }\n />\n </div>\n </div>\n );\n })\n ) : (\n <div className=\"px-4 py-10 text-center text-sm text-muted-foreground\">\n {query\n ? \"No matching automations.\"\n : view === \"all\"\n ? \"No automations yet. Create one here, or ask Dispatch to set up a scheduled or event-triggered job.\"\n : \"No Dispatch automations yet. Switch to All apps to inspect workspace automations.\"}\n </div>\n )}\n </div>\n\n {detailsTarget ? (\n <AutomationDetailsPanel\n automation={detailsTarget}\n isToggling={\n pendingToggleIdentity === automationIdentity(detailsTarget)\n }\n onToggle={() =>\n toggleAutomation.mutate({\n owner: detailsTarget.owner,\n path: detailsTarget.path,\n enabled: !detailsTarget.enabled,\n })\n }\n />\n ) : (\n <div className=\"flex min-h-[34rem] flex-col items-center justify-center rounded-lg border border-dashed bg-card p-6 text-center\">\n <IconListDetails\n size={24}\n strokeWidth={1.6}\n className=\"text-muted-foreground\"\n />\n <p className=\"mt-3 text-sm font-medium text-foreground\">\n Select an automation\n </p>\n <p className=\"mt-1 max-w-xs text-sm text-muted-foreground\">\n Inspect its prompt, configuration, capabilities, and run\n history.\n </p>\n </div>\n )}\n </div>\n </section>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/metrics.tsx"],"names":[],"mappings":"AAoDA,wBAAgB,IAAI;;IAEnB;AAiqCD,MAAM,CAAC,OAAO,UAAU,YAAY,oDA+RnC"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/metrics.tsx"],"names":[],"mappings":"AAoDA,wBAAgB,IAAI;;IAEnB;AAkqCD,MAAM,CAAC,OAAO,UAAU,YAAY,oDA+RnC"}
@@ -171,7 +171,7 @@ function ScopeSelector({ value, onChange, }) {
171
171
  ].map(([scope, label]) => (_jsx(Button, { type: "button", variant: value === scope ? "secondary" : "ghost", size: "sm", className: "h-7 px-3 text-xs", "aria-pressed": value === scope, onClick: () => onChange(scope), children: label }, scope))) }));
172
172
  }
173
173
  function UserSelector({ value, users, onChange, }) {
174
- return (_jsxs(Select, { value: value ?? "all", onValueChange: (nextValue) => onChange(nextValue === "all" ? null : nextValue), children: [_jsx(SelectTrigger, { className: "h-8 w-[210px] text-xs", "aria-label": "Filter usage by user", children: _jsx(SelectValue, { placeholder: "All users" }) }), _jsx(SelectContent, { children: _jsxs(SelectGroup, { children: [_jsx(SelectItem, { value: "all", children: "All users" }), users.map((user) => (_jsx(SelectItem, { value: user.email, children: user.email }, user.email)))] }) })] }));
174
+ return (_jsxs(Select, { value: value ?? "all", onValueChange: (nextValue) => onChange(nextValue === "all" ? null : nextValue), children: [_jsx(SelectTrigger, { size: "sm", className: "w-[210px] text-xs", "aria-label": "Filter usage by user", children: _jsx(SelectValue, { placeholder: "All users" }) }), _jsx(SelectContent, { children: _jsxs(SelectGroup, { children: [_jsx(SelectItem, { value: "all", children: "All users" }), users.map((user) => (_jsx(SelectItem, { value: user.email, children: user.email }, user.email)))] }) })] }));
175
175
  }
176
176
  function UsageTrend({ rows, billing, }) {
177
177
  const chartData = completeUsageTrendRows(rows).map((row) => ({