@agent-native/dispatch 0.14.3 → 0.14.5
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.
- package/README.md +114 -128
- package/dist/actions/list_apps.d.ts +1 -0
- package/dist/actions/list_apps.js +16 -8
- package/dist/actions/list_apps.js.map +1 -1
- package/dist/actions/set-mcp-app-access.js +1 -4
- package/dist/actions/set-mcp-app-access.js.map +1 -1
- package/dist/components/action-query-error.d.ts +8 -0
- package/dist/components/action-query-error.d.ts.map +1 -0
- package/dist/components/action-query-error.js +10 -0
- package/dist/components/action-query-error.js.map +1 -0
- package/dist/components/app-keys-popover.d.ts +4 -0
- package/dist/components/app-keys-popover.d.ts.map +1 -1
- package/dist/components/app-keys-popover.js +26 -14
- package/dist/components/app-keys-popover.js.map +1 -1
- package/dist/components/dispatch-control-plane.d.ts.map +1 -1
- package/dist/components/dispatch-control-plane.js +31 -27
- package/dist/components/dispatch-control-plane.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/layout/Layout.d.ts +1 -0
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +19 -21
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/task-queue-health.d.ts.map +1 -1
- package/dist/components/task-queue-health.js +9 -1
- package/dist/components/task-queue-health.js.map +1 -1
- package/dist/components/ui/sheet.js +1 -1
- package/dist/components/ui/sheet.js.map +1 -1
- package/dist/components/ui/toast.js +1 -1
- package/dist/components/ui/toast.js.map +1 -1
- package/dist/components/workspace-app-card.d.ts.map +1 -1
- package/dist/components/workspace-app-card.js +8 -5
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/components/workspace-resource-effective-stack.d.ts.map +1 -1
- package/dist/components/workspace-resource-effective-stack.js +6 -1
- package/dist/components/workspace-resource-effective-stack.js.map +1 -1
- package/dist/components/workspace-resource-impact-preview.d.ts.map +1 -1
- package/dist/components/workspace-resource-impact-preview.js +6 -1
- package/dist/components/workspace-resource-impact-preview.js.map +1 -1
- package/dist/routes/pages/$appId.d.ts.map +1 -1
- package/dist/routes/pages/$appId.js +6 -1
- package/dist/routes/pages/$appId.js.map +1 -1
- package/dist/routes/pages/agents.d.ts.map +1 -1
- package/dist/routes/pages/agents.js +5 -8
- package/dist/routes/pages/agents.js.map +1 -1
- package/dist/routes/pages/approval.d.ts.map +1 -1
- package/dist/routes/pages/approval.js +6 -1
- package/dist/routes/pages/approval.js.map +1 -1
- package/dist/routes/pages/approvals.d.ts.map +1 -1
- package/dist/routes/pages/approvals.js +8 -5
- package/dist/routes/pages/approvals.js.map +1 -1
- package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
- package/dist/routes/pages/apps.$appId.js +4 -2
- package/dist/routes/pages/apps.$appId.js.map +1 -1
- package/dist/routes/pages/apps.d.ts.map +1 -1
- package/dist/routes/pages/apps.js +10 -42
- package/dist/routes/pages/apps.js.map +1 -1
- package/dist/routes/pages/audit.d.ts.map +1 -1
- package/dist/routes/pages/audit.js +4 -2
- package/dist/routes/pages/audit.js.map +1 -1
- package/dist/routes/pages/automations.d.ts.map +1 -1
- package/dist/routes/pages/automations.js +0 -1
- package/dist/routes/pages/automations.js.map +1 -1
- package/dist/routes/pages/chat.d.ts.map +1 -1
- package/dist/routes/pages/chat.js +16 -2
- package/dist/routes/pages/chat.js.map +1 -1
- package/dist/routes/pages/destinations.d.ts.map +1 -1
- package/dist/routes/pages/destinations.js +5 -3
- package/dist/routes/pages/destinations.js.map +1 -1
- package/dist/routes/pages/identities.d.ts.map +1 -1
- package/dist/routes/pages/identities.js +5 -3
- package/dist/routes/pages/identities.js.map +1 -1
- package/dist/routes/pages/integrations.d.ts.map +1 -1
- package/dist/routes/pages/integrations.js +9 -3
- package/dist/routes/pages/integrations.js.map +1 -1
- package/dist/routes/pages/metrics.d.ts.map +1 -1
- package/dist/routes/pages/metrics.js +1 -1
- package/dist/routes/pages/metrics.js.map +1 -1
- package/dist/routes/pages/thread-debug.d.ts.map +1 -1
- package/dist/routes/pages/thread-debug.js +7 -6
- package/dist/routes/pages/thread-debug.js.map +1 -1
- package/dist/routes/pages/vault.d.ts.map +1 -1
- package/dist/routes/pages/vault.js +23 -7
- package/dist/routes/pages/vault.js.map +1 -1
- package/dist/routes/pages/workspace.d.ts.map +1 -1
- package/dist/routes/pages/workspace.js +9 -3
- package/dist/routes/pages/workspace.js.map +1 -1
- package/dist/server/lib/dispatch-store.d.ts.map +1 -1
- package/dist/server/lib/dispatch-store.js +2 -2
- package/dist/server/lib/dispatch-store.js.map +1 -1
- package/dist/server/lib/mcp-access-store.d.ts.map +1 -1
- package/dist/server/lib/mcp-access-store.js +30 -2
- package/dist/server/lib/mcp-access-store.js.map +1 -1
- package/dist/server/plugins/agent-chat.d.ts +1 -1
- package/package.json +2 -2
- package/src/actions/list_apps.spec.ts +52 -0
- package/src/actions/list_apps.ts +16 -8
- package/src/actions/set-mcp-app-access.spec.ts +73 -0
- package/src/actions/set-mcp-app-access.ts +1 -5
- package/src/components/action-query-error.spec.tsx +56 -0
- package/src/components/action-query-error.tsx +32 -0
- package/src/components/app-keys-popover.spec.tsx +85 -0
- package/src/components/app-keys-popover.tsx +76 -50
- package/src/components/dispatch-control-plane.spec.tsx +106 -0
- package/src/components/dispatch-control-plane.tsx +71 -115
- package/src/components/index.ts +1 -0
- package/src/components/layout/Layout.spec.tsx +42 -2
- package/src/components/layout/Layout.tsx +22 -27
- package/src/components/task-queue-health.tsx +9 -1
- package/src/components/ui/sheet.tsx +1 -1
- package/src/components/ui/toast.tsx +1 -1
- package/src/components/workspace-app-card.spec.tsx +80 -0
- package/src/components/workspace-app-card.tsx +36 -25
- package/src/components/workspace-resource-effective-stack.tsx +13 -1
- package/src/components/workspace-resource-impact-preview.tsx +12 -1
- package/src/routes/pages/$appId.tsx +17 -1
- package/src/routes/pages/agents.tsx +24 -11
- package/src/routes/pages/approval.tsx +16 -4
- package/src/routes/pages/approvals.tsx +108 -89
- package/src/routes/pages/apps.$appId.tsx +9 -2
- package/src/routes/pages/apps.tsx +13 -177
- package/src/routes/pages/audit.tsx +29 -20
- package/src/routes/pages/automations.tsx +0 -1
- package/src/routes/pages/chat.spec.tsx +94 -0
- package/src/routes/pages/chat.tsx +30 -10
- package/src/routes/pages/destinations.tsx +75 -62
- package/src/routes/pages/identities.tsx +74 -63
- package/src/routes/pages/integrations.tsx +17 -10
- package/src/routes/pages/metrics.tsx +0 -1
- package/src/routes/pages/thread-debug.tsx +18 -12
- package/src/routes/pages/vault.tsx +59 -26
- package/src/routes/pages/workspace.tsx +69 -55
- package/src/server/lib/approval-fencing.spec.ts +113 -2
- package/src/server/lib/dispatch-store.ts +2 -0
- package/src/server/lib/mcp-access-store.spec.ts +116 -4
- package/src/server/lib/mcp-access-store.ts +37 -2
- package/src/server/lib/mcp-gateway.spec.ts +79 -3
- package/src/styles/dispatch.css +5 -5
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { IconApps,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useActionQuery, useT } from "@agent-native/core/client";
|
|
3
|
+
import { IconApps, IconChevronDown, IconEyeOff, IconPlus, } from "@tabler/icons-react";
|
|
4
4
|
import { useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { ActionQueryError } from "../../components/action-query-error.js";
|
|
6
6
|
import { CreateAppPopover } from "../../components/create-app-popover.js";
|
|
7
7
|
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
8
8
|
import { Button } from "../../components/ui/button.js";
|
|
@@ -13,31 +13,20 @@ import { cn } from "../../lib/utils.js";
|
|
|
13
13
|
export function meta() {
|
|
14
14
|
return [{ title: "Apps — Dispatch" }];
|
|
15
15
|
}
|
|
16
|
-
const TEMPLATE_ICONS = {
|
|
17
|
-
Mail: IconMail,
|
|
18
|
-
CalendarMonth: IconCalendarMonth,
|
|
19
|
-
FileText: IconFileText,
|
|
20
|
-
Presentation: IconPresentation,
|
|
21
|
-
ScreenShare: IconScreenShare,
|
|
22
|
-
Brain: IconBrain,
|
|
23
|
-
Photo: IconPhoto,
|
|
24
|
-
ChartBar: IconChartBar,
|
|
25
|
-
ClipboardList: IconClipboardList,
|
|
26
|
-
Brush: IconBrush,
|
|
27
|
-
};
|
|
28
16
|
export default function AppsRoute() {
|
|
29
17
|
const t = useT();
|
|
30
18
|
const [showHidden, setShowHidden] = useState(false);
|
|
31
|
-
const
|
|
32
|
-
|
|
19
|
+
const appsQuery = useActionQuery("list-workspace-apps", {
|
|
20
|
+
includeAgentCards: false,
|
|
21
|
+
includeArchived: true,
|
|
22
|
+
});
|
|
23
|
+
const { data: apps = [], isLoading: appsLoading } = appsQuery;
|
|
33
24
|
const { data: workspace } = useActionQuery("get-workspace-info", {}, { staleTime: 60_000 });
|
|
34
|
-
const { data: templates = [], isLoading: templatesLoading } = useActionQuery("list-available-workspace-templates", {}, { refetchInterval: 5_000 });
|
|
35
25
|
const ws = workspace;
|
|
36
26
|
const workspaceLabel = ws?.displayName ?? ws?.name ?? null;
|
|
37
27
|
const allApps = apps.filter((app) => !app.isDispatch);
|
|
38
28
|
const visibleApps = allApps.filter((app) => !app.archived);
|
|
39
29
|
const archivedApps = allApps.filter((app) => app.archived);
|
|
40
|
-
const typedTemplates = templates;
|
|
41
30
|
const showAppSkeletons = appsLoading && allApps.length === 0;
|
|
42
31
|
return (_jsx(DispatchShell, { title: t("dispatch.nav.apps"), description: workspaceLabel
|
|
43
32
|
? t("dispatch.pages.appsDescriptionWithWorkspace", {
|
|
@@ -53,13 +42,7 @@ export default function AppsRoute() {
|
|
|
53
42
|
? ` · ${t("dispatch.pages.hiddenCount", {
|
|
54
43
|
count: archivedApps.length,
|
|
55
44
|
})}`
|
|
56
|
-
: ""] })] })] }), visibleApps.length > 0 ? (_jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { size: "sm", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), t("dispatch.pages.createApp")] }) })) : null] }), showAppSkeletons ? (_jsx(AppsSkeletonGrid, {})) : visibleApps.length > 0 ? (_jsx("div", { className: "grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3", children: visibleApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: "h-full" }, app.id))) })) : (_jsx(EmptyAppsState, {}))] }),
|
|
57
|
-
? t("dispatch.pages.checkingTemplates")
|
|
58
|
-
: t("dispatch.pages.templatesAvailable", {
|
|
59
|
-
count: typedTemplates.length,
|
|
60
|
-
}) })] })] }), _jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1.5", children: [templatesOpen
|
|
61
|
-
? t("dispatch.pages.hide")
|
|
62
|
-
: t("dispatch.pages.show"), _jsx(IconChevronDown, { size: 14, className: cn("transition-transform", templatesOpen && "rotate-180") })] }) })] }), _jsx(CollapsibleContent, { children: templatesLoading && typedTemplates.length === 0 ? (_jsx(AppsSkeletonGrid, {})) : (_jsx("div", { className: "grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3", children: typedTemplates.map((template) => (_jsx(AddTemplateCard, { template: template }, template.name))) })) })] }) })) : null, archivedApps.length > 0 ? (_jsx(Collapsible, { open: showHidden, onOpenChange: setShowHidden, children: _jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-t pt-4", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconEyeOff, { size: 16, className: "shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.hiddenApps") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.hiddenAppCount", {
|
|
45
|
+
: ""] })] })] }), visibleApps.length > 0 ? (_jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { size: "sm", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), t("dispatch.pages.createApp")] }) })) : null] }), appsQuery.isError ? (_jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() })) : showAppSkeletons ? (_jsx(AppsSkeletonGrid, {})) : visibleApps.length > 0 ? (_jsx("div", { className: "grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3", children: visibleApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: "h-full" }, app.id))) })) : (_jsx(EmptyAppsState, {}))] }), archivedApps.length > 0 ? (_jsx(Collapsible, { open: showHidden, onOpenChange: setShowHidden, children: _jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-t pt-4", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconEyeOff, { size: 16, className: "shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.hiddenApps") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.hiddenAppCount", {
|
|
63
46
|
count: archivedApps.length,
|
|
64
47
|
}) })] })] }), _jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1.5", children: [showHidden
|
|
65
48
|
? t("dispatch.pages.hide")
|
|
@@ -72,19 +55,4 @@ function EmptyAppsState() {
|
|
|
72
55
|
const t = useT();
|
|
73
56
|
return (_jsxs("div", { className: "rounded-lg border border-dashed bg-card px-4 py-10 text-center", children: [_jsx("div", { className: "mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: _jsx(IconApps, { size: 18 }) }), _jsx("h3", { className: "mt-3 text-sm font-semibold text-foreground", children: t("dispatch.pages.noWorkspaceApps") }), _jsx("p", { className: "mx-auto mt-1 max-w-sm text-sm text-muted-foreground", children: t("dispatch.pages.noWorkspaceAppsDescription") }), _jsx("div", { className: "mt-4", children: _jsx(CreateAppPopover, { trigger: _jsxs(Button, { size: "sm", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), t("dispatch.pages.createApp")] }) }) })] }));
|
|
74
57
|
}
|
|
75
|
-
function AddTemplateCard({ template }) {
|
|
76
|
-
const Icon = TEMPLATE_ICONS[template.icon] ?? IconSparkles;
|
|
77
|
-
const scaffold = useActionMutation("scaffold-workspace-app", {
|
|
78
|
-
onSuccess: (result) => {
|
|
79
|
-
toast.success(`Scaffolded apps/${result?.appId || template.name}. The gateway will pick it up shortly.`);
|
|
80
|
-
},
|
|
81
|
-
onError: (err) => {
|
|
82
|
-
toast.error(`Could not scaffold ${template.label}: ${err instanceof Error ? err.message : String(err)}`);
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
return (_jsxs("div", { className: "group relative flex h-full min-h-36 items-stretch gap-3 rounded-lg border bg-card p-4 transition hover:border-foreground/30", children: [_jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center self-start rounded-md", style: {
|
|
86
|
-
backgroundColor: `rgb(${template.colorRgb} / 0.12)`,
|
|
87
|
-
color: template.color,
|
|
88
|
-
}, children: _jsx(Icon, { size: 18 }) }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("div", { className: "flex min-w-0 items-center gap-2", children: _jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: template.label }) }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: template.hint }), _jsx("div", { className: "mt-auto pt-3", children: _jsx(Button, { size: "sm", variant: "outline", disabled: scaffold.isPending, onClick: () => scaffold.mutate({ template: template.name }), children: scaffold.isPending ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { size: 14, className: "mr-1.5 animate-spin" }), "Adding..."] })) : (_jsxs(_Fragment, { children: [_jsx(IconPlus, { size: 14, className: "mr-1.5" }), "Add to workspace"] })) }) })] })] }));
|
|
89
|
-
}
|
|
90
58
|
//# sourceMappingURL=apps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useActionMutation,\n useActionQuery,\n useT,\n} from \"@agent-native/core/client\";\nimport {\n IconApps,\n IconBrain,\n IconBrush,\n IconCalendarMonth,\n IconChartBar,\n IconChevronDown,\n IconClipboardList,\n IconEyeOff,\n IconFileText,\n IconLoader2,\n IconMail,\n IconPhoto,\n IconPlus,\n IconPresentation,\n IconScreenShare,\n IconSparkles,\n IconStack3,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport { cn } from \"../../lib/utils\";\nimport type { WorkspaceAppSummary } from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\ninterface AvailableTemplate {\n name: string;\n label: string;\n hint: string;\n icon: string;\n color: string;\n colorRgb: string;\n core: boolean;\n}\n\nconst TEMPLATE_ICONS: Record<string, typeof IconMail> = {\n Mail: IconMail,\n CalendarMonth: IconCalendarMonth,\n FileText: IconFileText,\n Presentation: IconPresentation,\n ScreenShare: IconScreenShare,\n Brain: IconBrain,\n Photo: IconPhoto,\n ChartBar: IconChartBar,\n ClipboardList: IconClipboardList,\n Brush: IconBrush,\n};\n\nexport default function AppsRoute() {\n const t = useT();\n const [showHidden, setShowHidden] = useState(false);\n const [templatesOpen, setTemplatesOpen] = useState(false);\n const { data: apps = [], isLoading: appsLoading } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false, includeArchived: true },\n );\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const { data: templates = [], isLoading: templatesLoading } = useActionQuery(\n \"list-available-workspace-templates\",\n {},\n { refetchInterval: 5_000 },\n );\n\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n (app) => !app.isDispatch,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const archivedApps = allApps.filter((app) => app.archived);\n const typedTemplates = templates as AvailableTemplate[];\n const showAppSkeletons = appsLoading && allApps.length === 0;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {workspaceLabel\n ? t(\"dispatch.pages.appsInWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.workspaceApps\")}\n </h2>\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.activeCount\", {\n count: visibleApps.length,\n })}\n {archivedApps.length > 0\n ? ` · ${t(\"dispatch.pages.hiddenCount\", {\n count: archivedApps.length,\n })}`\n : \"\"}\n </p>\n </div>\n </div>\n {visibleApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.createApp\")}\n </Button>\n }\n />\n ) : null}\n </div>\n\n {showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : visibleApps.length > 0 ? (\n <div className=\"grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {visibleApps.map((app) => (\n <WorkspaceAppCard key={app.id} app={app} className=\"h-full\" />\n ))}\n </div>\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {typedTemplates.length > 0 || templatesLoading ? (\n <Collapsible open={templatesOpen} onOpenChange={setTemplatesOpen}>\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconStack3\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.templates\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {templatesLoading\n ? t(\"dispatch.pages.checkingTemplates\")\n : t(\"dispatch.pages.templatesAvailable\", {\n count: typedTemplates.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {templatesOpen\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n templatesOpen && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n {templatesLoading && typedTemplates.length === 0 ? (\n <AppsSkeletonGrid />\n ) : (\n <div className=\"grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {typedTemplates.map((template) => (\n <AddTemplateCard\n key={template.name}\n template={template}\n />\n ))}\n </div>\n )}\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n {archivedApps.length > 0 ? (\n <Collapsible open={showHidden} onOpenChange={setShowHidden}>\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showHidden && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <div className=\"grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {archivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className=\"h-full\"\n />\n ))}\n </div>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1 space-y-3\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-24\" />\n <div className=\"space-y-2 pt-1\">\n <Skeleton className=\"h-3 w-full\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n </div>\n <Skeleton className=\"h-7 w-7 rounded-md\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.createApp\")}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction AddTemplateCard({ template }: { template: AvailableTemplate }) {\n const Icon = TEMPLATE_ICONS[template.icon] ?? IconSparkles;\n const scaffold = useActionMutation(\"scaffold-workspace-app\", {\n onSuccess: (result: any) => {\n toast.success(\n `Scaffolded apps/${result?.appId || template.name}. The gateway will pick it up shortly.`,\n );\n },\n onError: (err) => {\n toast.error(\n `Could not scaffold ${template.label}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n },\n });\n\n return (\n <div className=\"group relative flex h-full min-h-36 items-stretch gap-3 rounded-lg border bg-card p-4 transition hover:border-foreground/30\">\n <div\n className=\"flex h-9 w-9 shrink-0 items-center justify-center self-start rounded-md\"\n style={{\n backgroundColor: `rgb(${template.colorRgb} / 0.12)`,\n color: template.color,\n }}\n >\n <Icon size={18} />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <h3 className=\"truncate text-sm font-semibold text-foreground\">\n {template.label}\n </h3>\n </div>\n <p className=\"mt-1 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {template.hint}\n </p>\n <div className=\"mt-auto pt-3\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={scaffold.isPending}\n onClick={() => scaffold.mutate({ template: template.name })}\n >\n {scaffold.isPending ? (\n <>\n <IconLoader2 size={14} className=\"mr-1.5 animate-spin\" />\n Adding...\n </>\n ) : (\n <>\n <IconPlus size={14} className=\"mr-1.5\" />\n Add to workspace\n </>\n )}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery, useT } from \"@agent-native/core/client\";\nimport {\n IconApps,\n IconChevronDown,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport { cn } from \"../../lib/utils\";\nimport type { WorkspaceAppSummary } from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRoute() {\n const t = useT();\n const [showHidden, setShowHidden] = useState(false);\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n (app) => !app.isDispatch,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const archivedApps = allApps.filter((app) => app.archived);\n const showAppSkeletons = appsLoading && allApps.length === 0;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {workspaceLabel\n ? t(\"dispatch.pages.appsInWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.workspaceApps\")}\n </h2>\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.activeCount\", {\n count: visibleApps.length,\n })}\n {archivedApps.length > 0\n ? ` · ${t(\"dispatch.pages.hiddenCount\", {\n count: archivedApps.length,\n })}`\n : \"\"}\n </p>\n </div>\n </div>\n {visibleApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.createApp\")}\n </Button>\n }\n />\n ) : null}\n </div>\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : visibleApps.length > 0 ? (\n <div className=\"grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {visibleApps.map((app) => (\n <WorkspaceAppCard key={app.id} app={app} className=\"h-full\" />\n ))}\n </div>\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {archivedApps.length > 0 ? (\n <Collapsible open={showHidden} onOpenChange={setShowHidden}>\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showHidden && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <div className=\"grid auto-rows-fr gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {archivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className=\"h-full\"\n />\n ))}\n </div>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1 space-y-3\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-24\" />\n <div className=\"space-y-2 pt-1\">\n <Skeleton className=\"h-3 w-full\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n </div>\n <Skeleton className=\"h-7 w-7 rounded-md\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.createApp\")}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/audit.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/audit.tsx"],"names":[],"mappings":"AAKA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,oDAyCjC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useActionQuery } from "@agent-native/core/client";
|
|
3
|
+
import { ActionQueryError } from "../../components/action-query-error.js";
|
|
3
4
|
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
4
5
|
export function meta() {
|
|
5
6
|
return [{ title: "Audit — Dispatch" }];
|
|
6
7
|
}
|
|
7
8
|
export default function AuditRoute() {
|
|
8
|
-
const
|
|
9
|
-
|
|
9
|
+
const query = useActionQuery("list-dispatch-audit", { limit: 100 });
|
|
10
|
+
const { data } = query;
|
|
11
|
+
return (_jsx(DispatchShell, { title: "Audit", description: "Change history for routes, settings, and approvals.", children: _jsx("section", { className: "rounded-2xl border bg-card p-5", children: query.isError ? (_jsx(ActionQueryError, { error: query.error, onRetry: () => void query.refetch() })) : (_jsxs("div", { className: "space-y-3", children: [(data || []).map((event) => (_jsxs("div", { className: "rounded-xl border bg-muted/30 px-4 py-3", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: event.summary }), _jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [event.actor, " \u00B7 ", event.action, " \u00B7", " ", new Date(event.createdAt).toLocaleString()] })] }, event.id))), (data?.length || 0) === 0 && (_jsx("div", { className: "rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground", children: "No audit entries yet." }))] })) }) }));
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=audit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/routes/pages/audit.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,UAAU;IAChC,MAAM,
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/routes/pages/audit.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,UAAU;IAChC,MAAM,KAAK,GAAG,cAAc,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAEvB,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAC,OAAO,EACb,WAAW,EAAC,qDAAqD,YAEjE,kBAAS,SAAS,EAAC,gCAAgC,YAChD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CACf,KAAC,gBAAgB,IACf,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,GACnC,CACH,CAAC,CAAC,CAAC,CACF,eAAK,SAAS,EAAC,WAAW,aACvB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,CAChC,eAEE,SAAS,EAAC,yCAAyC,aAEnD,cAAK,SAAS,EAAC,qCAAqC,YACjD,KAAK,CAAC,OAAO,GACV,EACN,eAAK,SAAS,EAAC,oCAAoC,aAChD,KAAK,CAAC,KAAK,cAAK,KAAK,CAAC,MAAM,aAAI,GAAG,EACnC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,IACvC,KATD,KAAK,CAAC,EAAE,CAUT,CACP,CAAC,EACD,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAC5B,cAAK,SAAS,EAAC,yEAAyE,sCAElF,CACP,IACG,CACP,GACO,GACI,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\n\nexport function meta() {\n return [{ title: \"Audit — Dispatch\" }];\n}\n\nexport default function AuditRoute() {\n const query = useActionQuery(\"list-dispatch-audit\", { limit: 100 });\n const { data } = query;\n\n return (\n <DispatchShell\n title=\"Audit\"\n description=\"Change history for routes, settings, and approvals.\"\n >\n <section className=\"rounded-2xl border bg-card p-5\">\n {query.isError ? (\n <ActionQueryError\n error={query.error}\n onRetry={() => void query.refetch()}\n />\n ) : (\n <div className=\"space-y-3\">\n {(data || []).map((event: any) => (\n <div\n key={event.id}\n className=\"rounded-xl border bg-muted/30 px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {event.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {event.actor} · {event.action} ·{\" \"}\n {new Date(event.createdAt).toLocaleString()}\n </div>\n </div>\n ))}\n {(data?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n No audit entries yet.\n </div>\n )}\n </div>\n )}\n </section>\n </DispatchShell>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAuCA,wBAAgB,IAAI;;IAEnB;
|
|
1
|
+
{"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAuCA,wBAAgB,IAAI;;IAEnB;AAmID,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDA0GvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automations.js","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n PromptComposer,\n sendToAgentChat,\n useChangeVersions,\n} from \"@agent-native/core/client\";\nimport { IconPlus, IconSettingsAutomation } from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastRun,\n automationNextRun,\n automationStatus,\n automationTarget,\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 refetchInterval: 15_000,\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() {\n const [open, setOpen] = useState(false);\n const [scope, setScope] = useState<\"personal\" | \"organization\">(\"personal\");\n\n function handleSubmit(text: string) {\n const trimmed = text.trim();\n if (!trimmed) return;\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n sendToAgentChat({\n message: trimmed,\n context: `The user wants to create a new automation. Scope: ${scope}. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`,\n submit: true,\n newTab: true,\n });\n setOpen(false);\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size=\"sm\">\n <IconPlus size={14} />\n New automation\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-[min(100vw-2rem,24rem)] p-3\">\n <p className=\"pb-2 text-sm font-semibold text-foreground\">\n New automation\n </p>\n <PromptComposer\n autoFocus\n placeholder=\"Describe what you want to automate...\"\n draftScope=\"dispatch-automations:create\"\n onSubmit={handleSubmit}\n />\n <select\n value={scope}\n onChange={(event) =>\n setScope(event.target.value as \"personal\" | \"organization\")\n }\n className=\"mt-2 w-full cursor-pointer rounded-md border border-input bg-background px-3 py-1.5 text-xs text-foreground\"\n >\n <option value=\"personal\">Personal</option>\n <option value=\"organization\">Organization</option>\n </select>\n </PopoverContent>\n </Popover>\n );\n}\n\nexport default function AutomationsRoute() {\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const automations = automationsQuery.data ?? [];\n const ordered = useMemo(() => sortAutomations(automations), [automations]);\n const enabledCount = automations.filter((item) => item.enabled).length;\n const errorCount = automations.filter(\n (item) => item.enabled && item.lastStatus === \"error\",\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"See scheduled and event-triggered jobs, pause them, or ask the agent to create one.\"\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 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 <CreateAutomationButton />\n </div>\n\n <div className=\"divide-y rounded-lg border 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 ) : ordered.length > 0 ? (\n ordered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n return (\n <div\n key={item.id}\n className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3\"\n >\n <div className=\"min-w-0\">\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 </div>\n {item.lastError ? (\n <div className=\"mt-1 truncate text-xs text-destructive\">\n {item.lastError}\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 No automations yet. Create one here, or ask Dispatch to set up a\n scheduled or event-triggered job.\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 {\n PromptComposer,\n sendToAgentChat,\n useChangeVersions,\n} from \"@agent-native/core/client\";\nimport { IconPlus, IconSettingsAutomation } from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastRun,\n automationNextRun,\n automationStatus,\n automationTarget,\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() {\n const [open, setOpen] = useState(false);\n const [scope, setScope] = useState<\"personal\" | \"organization\">(\"personal\");\n\n function handleSubmit(text: string) {\n const trimmed = text.trim();\n if (!trimmed) return;\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n sendToAgentChat({\n message: trimmed,\n context: `The user wants to create a new automation. Scope: ${scope}. Use manage-automations with action=define to create it. Ask clarifying questions if needed about what event to trigger on, conditions, and what actions to take.`,\n submit: true,\n newTab: true,\n });\n setOpen(false);\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size=\"sm\">\n <IconPlus size={14} />\n New automation\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-[min(100vw-2rem,24rem)] p-3\">\n <p className=\"pb-2 text-sm font-semibold text-foreground\">\n New automation\n </p>\n <PromptComposer\n autoFocus\n placeholder=\"Describe what you want to automate...\"\n draftScope=\"dispatch-automations:create\"\n onSubmit={handleSubmit}\n />\n <select\n value={scope}\n onChange={(event) =>\n setScope(event.target.value as \"personal\" | \"organization\")\n }\n className=\"mt-2 w-full cursor-pointer rounded-md border border-input bg-background px-3 py-1.5 text-xs text-foreground\"\n >\n <option value=\"personal\">Personal</option>\n <option value=\"organization\">Organization</option>\n </select>\n </PopoverContent>\n </Popover>\n );\n}\n\nexport default function AutomationsRoute() {\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const automations = automationsQuery.data ?? [];\n const ordered = useMemo(() => sortAutomations(automations), [automations]);\n const enabledCount = automations.filter((item) => item.enabled).length;\n const errorCount = automations.filter(\n (item) => item.enabled && item.lastStatus === \"error\",\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"See scheduled and event-triggered jobs, pause them, or ask the agent to create one.\"\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 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 <CreateAutomationButton />\n </div>\n\n <div className=\"divide-y rounded-lg border 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 ) : ordered.length > 0 ? (\n ordered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n return (\n <div\n key={item.id}\n className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3\"\n >\n <div className=\"min-w-0\">\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 </div>\n {item.lastError ? (\n <div className=\"mt-1 truncate text-xs text-destructive\">\n {item.lastError}\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 No automations yet. Create one here, or ask Dispatch to set up a\n scheduled or event-triggered job.\n </div>\n )}\n </div>\n </section>\n </DispatchShell>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"AAoFA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,oDA6HhC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { AgentChatSurface, appBasePath, appPath, markAgentChatHomeHandoff, } from "@agent-native/core/client";
|
|
2
|
+
import { AgentChatSurface, appBasePath, appPath, markAgentChatHomeHandoff, useT, } from "@agent-native/core/client";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, } from "react";
|
|
4
4
|
import { useLocation, useNavigate } from "react-router";
|
|
5
5
|
import { submitOverviewPrompt } from "../../lib/overview-chat.js";
|
|
@@ -51,6 +51,7 @@ export function meta() {
|
|
|
51
51
|
return [{ title: "Chat — Dispatch" }];
|
|
52
52
|
}
|
|
53
53
|
export default function ChatRoute() {
|
|
54
|
+
const t = useT();
|
|
54
55
|
const location = useLocation();
|
|
55
56
|
const navigate = useNavigate();
|
|
56
57
|
const routeThreadId = threadIdFromPath(location.pathname);
|
|
@@ -110,6 +111,19 @@ export default function ChatRoute() {
|
|
|
110
111
|
window.addEventListener("agentNative.chatRunning", handleChatRunning);
|
|
111
112
|
return () => window.removeEventListener("agentNative.chatRunning", handleChatRunning);
|
|
112
113
|
}, []);
|
|
113
|
-
return (_jsx("div", { className: "flex h-full min-h-0 flex-col bg-background", children: _jsx(DispatchAgentChatSurface, { mode: "page", chatViewTransition: true, className: "dispatch-chat-panel", defaultMode: "chat", storageKey: "dispatch", threadUrlSync: threadUrlSync, showHeader: false, showTabBar: false, dynamicSuggestions: false, suggestions: [], emptyStateText:
|
|
114
|
+
return (_jsx("div", { className: "flex h-full min-h-0 flex-col bg-background", children: _jsx(DispatchAgentChatSurface, { mode: "page", chatViewTransition: true, className: "dispatch-chat-panel", defaultMode: "chat", storageKey: "dispatch", threadUrlSync: threadUrlSync, showHeader: false, showTabBar: false, dynamicSuggestions: false, suggestions: [], emptyStateText: t("dispatch.pages.chatAcrossAppsDescription", {
|
|
115
|
+
defaultValue: "Route work, inspect status, or create something new from one place.",
|
|
116
|
+
}), emptyStateDisplay: "hidden", ...(!prompt?.message
|
|
117
|
+
? {
|
|
118
|
+
centerComposerWhenEmpty: true,
|
|
119
|
+
composerLayoutVariant: "hero",
|
|
120
|
+
}
|
|
121
|
+
: {}), composerPlaceholder: t("dispatch.pages.chatPromptPlaceholder", {
|
|
122
|
+
defaultValue: "Ask Dispatch...",
|
|
123
|
+
}), composerSlot: !prompt?.message ? (_jsxs("div", { className: "dispatch-chat-intro", children: [_jsx("h1", { children: t("dispatch.pages.chatAcrossApps", {
|
|
124
|
+
defaultValue: "Chat across your apps",
|
|
125
|
+
}) }), _jsx("p", { children: t("dispatch.pages.chatAcrossAppsDescription", {
|
|
126
|
+
defaultValue: "Route work, inspect status, or create something new from one place.",
|
|
127
|
+
}) })] })) : null }) }));
|
|
114
128
|
}
|
|
115
129
|
//# sourceMappingURL=chat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n AgentChatSurface,\n appBasePath,\n appPath,\n markAgentChatHomeHandoff,\n} from \"@agent-native/core/client\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ComponentProps,\n} from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\n\nimport { submitOverviewPrompt } from \"../../lib/overview-chat\";\n\nfunction chatThreadPath(threadId: string | null): string {\n return threadId ? `/chat/${encodeURIComponent(threadId)}` : \"/chat\";\n}\n\nfunction stripBasePath(pathname: string): string {\n const basePath = appBasePath();\n if (!basePath) return pathname;\n if (pathname === basePath) return \"/\";\n if (pathname.startsWith(`${basePath}/`)) {\n return pathname.slice(basePath.length) || \"/\";\n }\n return pathname;\n}\n\n// The chat surface renders for both `/chat` and the `/chat/:threadId` deep\n// link. The thread id is read from the pathname (not `useParams`) because the\n// param is owned by the nested deep-link route, not this leaf component.\nfunction threadIdFromPath(pathname: string): string | null {\n const match = stripBasePath(pathname).match(/^\\/chat\\/([^/]+)/);\n if (!match) return null;\n try {\n const value = decodeURIComponent(match[1]).trim();\n return value || null;\n } catch {\n return null;\n }\n}\n\n// Mirror the basename handling Dispatch's nav links use: pass a router-local\n// path when the live URL is already under the mount, otherwise prefix it.\nfunction dispatchNavTarget(path: string): string {\n if (typeof window === \"undefined\") return path;\n const basePath = appBasePath();\n if (!basePath) return path;\n const pathname = window.location.pathname;\n const routerHasBasename =\n pathname === basePath || pathname.startsWith(`${basePath}/`);\n return routerHasBasename ? path : appPath(path);\n}\n\ninterface DispatchThreadUrlSync {\n routeThreadId: string | null;\n getPath: (threadId: string | null) => string;\n navigate: (path: string, options?: { replace?: boolean }) => void;\n}\n\ntype DispatchAgentChatSurfaceProps = ComponentProps<typeof AgentChatSurface> & {\n threadUrlSync?: DispatchThreadUrlSync;\n};\n\nfunction DispatchAgentChatSurface(props: DispatchAgentChatSurfaceProps) {\n return <AgentChatSurface {...props} />;\n}\n\ninterface DispatchChatLocationState {\n dispatchPrompt?: {\n id?: string | number;\n message?: string;\n selectedModel?: string | null;\n };\n dispatchThread?: {\n id?: string | number;\n threadId?: string;\n };\n}\n\nexport function meta() {\n return [{ title: \"Chat — Dispatch\" }];\n}\n\nexport default function ChatRoute() {\n const location = useLocation();\n const navigate = useNavigate();\n const routeThreadId = threadIdFromPath(location.pathname);\n const handledStateIds = useRef(new Set<string>());\n\n const navigateThreadUrl = useCallback(\n (path: string, options?: { replace?: boolean }) =>\n navigate(dispatchNavTarget(path), options),\n [navigate],\n );\n const threadUrlSync = useMemo<DispatchThreadUrlSync>(\n () => ({\n routeThreadId: routeThreadId ?? null,\n getPath: chatThreadPath,\n navigate: navigateThreadUrl,\n }),\n [routeThreadId, navigateThreadUrl],\n );\n const state = location.state as DispatchChatLocationState | null;\n const prompt = state?.dispatchPrompt;\n const thread = state?.dispatchThread;\n\n useEffect(() => {\n const message = prompt?.message?.trim();\n const threadId = thread?.threadId?.trim();\n if (!message && !threadId) return;\n\n const stateId = String(\n prompt?.id ?? thread?.id ?? `${message ?? \"\"}:${threadId ?? \"\"}`,\n );\n if (handledStateIds.current.has(stateId)) return;\n handledStateIds.current.add(stateId);\n\n const timer = window.setTimeout(() => {\n if (threadId) {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:open-thread\", {\n detail: { threadId },\n }),\n );\n }\n if (message) {\n submitOverviewPrompt(message, prompt?.selectedModel, {\n openSidebar: false,\n });\n }\n navigate(`${location.pathname}${location.search}${location.hash}`, {\n replace: true,\n state: null,\n });\n }, 0);\n\n return () => window.clearTimeout(timer);\n }, [\n location.hash,\n location.pathname,\n location.search,\n navigate,\n prompt?.id,\n prompt?.message,\n prompt?.selectedModel,\n thread?.id,\n thread?.threadId,\n ]);\n\n useEffect(() => {\n function handleChatRunning(event: Event) {\n const detail = (event as CustomEvent).detail;\n if (detail?.isRunning === true) markAgentChatHomeHandoff(\"dispatch\");\n }\n\n window.addEventListener(\"agentNative.chatRunning\", handleChatRunning);\n return () =>\n window.removeEventListener(\"agentNative.chatRunning\", handleChatRunning);\n }, []);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col bg-background\">\n <DispatchAgentChatSurface\n mode=\"page\"\n chatViewTransition\n className=\"dispatch-chat-panel\"\n defaultMode=\"chat\"\n storageKey=\"dispatch\"\n threadUrlSync={threadUrlSync}\n showHeader={false}\n showTabBar={false}\n dynamicSuggestions={false}\n suggestions={[]}\n emptyStateText=\"Ask Dispatch to create apps, route work, or manage the workspace.\"\n emptyStateDisplay=\"hidden\"\n centerComposerWhenEmpty\n composerLayoutVariant=\"hero\"\n composerPlaceholder=\"Ask Dispatch...\"\n composerSlot={\n <div className=\"dispatch-chat-intro\">\n <h1>What should Dispatch do next?</h1>\n <p>\n Create apps, manage shared keys, and route work across agents.\n </p>\n </div>\n }\n />\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,wBAAwB,EACxB,IAAI,GACL,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,GAEP,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,SAAS,cAAc,CAAC,QAAuB;IAC7C,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACtE,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/B,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACtC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,0EAA0E;AAC1E,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1C,MAAM,iBAAiB,GACrB,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC/D,OAAO,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAYD,SAAS,wBAAwB,CAAC,KAAoC;IACpE,OAAO,KAAC,gBAAgB,OAAK,KAAK,GAAI,CAAC;AACzC,CAAC;AAcD,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,GAAG,EAAU,CAAC,CAAC;IAElD,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,IAAY,EAAE,OAA+B,EAAE,EAAE,CAChD,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAC5C,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,aAAa,GAAG,OAAO,CAC3B,GAAG,EAAE,CAAC,CAAC;QACL,aAAa,EAAE,aAAa,IAAI,IAAI;QACpC,OAAO,EAAE,cAAc;QACvB,QAAQ,EAAE,iBAAiB;KAC5B,CAAC,EACF,CAAC,aAAa,EAAE,iBAAiB,CAAC,CACnC,CAAC;IACF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAyC,CAAC;IACjE,MAAM,MAAM,GAAG,KAAK,EAAE,cAAc,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,EAAE,cAAc,CAAC;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE,OAAO;QAElC,MAAM,OAAO,GAAG,MAAM,CACpB,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,GAAG,OAAO,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE,EAAE,CACjE,CAAC;QACF,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO;QACjD,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACnC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,wBAAwB,EAAE;oBACxC,MAAM,EAAE,EAAE,QAAQ,EAAE;iBACrB,CAAC,CACH,CAAC;YACJ,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE;oBACnD,WAAW,EAAE,KAAK;iBACnB,CAAC,CAAC;YACL,CAAC;YACD,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE;gBACjE,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;QACL,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,EAAE;QACD,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,QAAQ;QACjB,QAAQ,CAAC,MAAM;QACf,QAAQ;QACR,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,OAAO;QACf,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,iBAAiB,CAAC,KAAY;YACrC,MAAM,MAAM,GAAI,KAAqB,CAAC,MAAM,CAAC;YAC7C,IAAI,MAAM,EAAE,SAAS,KAAK,IAAI;gBAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,CAAC;QACtE,OAAO,GAAG,EAAE,CACV,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,CAAC;IAC7E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,cAAK,SAAS,EAAC,4CAA4C,YACzD,KAAC,wBAAwB,IACvB,IAAI,EAAC,MAAM,EACX,kBAAkB,QAClB,SAAS,EAAC,qBAAqB,EAC/B,WAAW,EAAC,MAAM,EAClB,UAAU,EAAC,UAAU,EACrB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,KAAK,EACjB,UAAU,EAAE,KAAK,EACjB,kBAAkB,EAAE,KAAK,EACzB,WAAW,EAAE,EAAE,EACf,cAAc,EAAE,CAAC,CAAC,0CAA0C,EAAE;gBAC5D,YAAY,EACV,qEAAqE;aACxE,CAAC,EACF,iBAAiB,EAAC,QAAQ,KACtB,CAAC,CAAC,MAAM,EAAE,OAAO;gBACnB,CAAC,CAAC;oBACE,uBAAuB,EAAE,IAAI;oBAC7B,qBAAqB,EAAE,MAAe;iBACvC;gBACH,CAAC,CAAC,EAAE,CAAC,EACP,mBAAmB,EAAE,CAAC,CAAC,sCAAsC,EAAE;gBAC7D,YAAY,EAAE,iBAAiB;aAChC,CAAC,EACF,YAAY,EACV,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CACjB,eAAK,SAAS,EAAC,qBAAqB,aAClC,uBACG,CAAC,CAAC,+BAA+B,EAAE;4BAClC,YAAY,EAAE,uBAAuB;yBACtC,CAAC,GACC,EACL,sBACG,CAAC,CAAC,0CAA0C,EAAE;4BAC7C,YAAY,EACV,qEAAqE;yBACxE,CAAC,GACA,IACA,CACP,CAAC,CAAC,CAAC,IAAI,GAEV,GACE,CACP,CAAC;AACJ,CAAC","sourcesContent":["import {\n AgentChatSurface,\n appBasePath,\n appPath,\n markAgentChatHomeHandoff,\n useT,\n} from \"@agent-native/core/client\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ComponentProps,\n} from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\n\nimport { submitOverviewPrompt } from \"../../lib/overview-chat\";\n\nfunction chatThreadPath(threadId: string | null): string {\n return threadId ? `/chat/${encodeURIComponent(threadId)}` : \"/chat\";\n}\n\nfunction stripBasePath(pathname: string): string {\n const basePath = appBasePath();\n if (!basePath) return pathname;\n if (pathname === basePath) return \"/\";\n if (pathname.startsWith(`${basePath}/`)) {\n return pathname.slice(basePath.length) || \"/\";\n }\n return pathname;\n}\n\n// The chat surface renders for both `/chat` and the `/chat/:threadId` deep\n// link. The thread id is read from the pathname (not `useParams`) because the\n// param is owned by the nested deep-link route, not this leaf component.\nfunction threadIdFromPath(pathname: string): string | null {\n const match = stripBasePath(pathname).match(/^\\/chat\\/([^/]+)/);\n if (!match) return null;\n try {\n const value = decodeURIComponent(match[1]).trim();\n return value || null;\n } catch {\n return null;\n }\n}\n\n// Mirror the basename handling Dispatch's nav links use: pass a router-local\n// path when the live URL is already under the mount, otherwise prefix it.\nfunction dispatchNavTarget(path: string): string {\n if (typeof window === \"undefined\") return path;\n const basePath = appBasePath();\n if (!basePath) return path;\n const pathname = window.location.pathname;\n const routerHasBasename =\n pathname === basePath || pathname.startsWith(`${basePath}/`);\n return routerHasBasename ? path : appPath(path);\n}\n\ninterface DispatchThreadUrlSync {\n routeThreadId: string | null;\n getPath: (threadId: string | null) => string;\n navigate: (path: string, options?: { replace?: boolean }) => void;\n}\n\ntype DispatchAgentChatSurfaceProps = ComponentProps<typeof AgentChatSurface> & {\n threadUrlSync?: DispatchThreadUrlSync;\n};\n\nfunction DispatchAgentChatSurface(props: DispatchAgentChatSurfaceProps) {\n return <AgentChatSurface {...props} />;\n}\n\ninterface DispatchChatLocationState {\n dispatchPrompt?: {\n id?: string | number;\n message?: string;\n selectedModel?: string | null;\n };\n dispatchThread?: {\n id?: string | number;\n threadId?: string;\n };\n}\n\nexport function meta() {\n return [{ title: \"Chat — Dispatch\" }];\n}\n\nexport default function ChatRoute() {\n const t = useT();\n const location = useLocation();\n const navigate = useNavigate();\n const routeThreadId = threadIdFromPath(location.pathname);\n const handledStateIds = useRef(new Set<string>());\n\n const navigateThreadUrl = useCallback(\n (path: string, options?: { replace?: boolean }) =>\n navigate(dispatchNavTarget(path), options),\n [navigate],\n );\n const threadUrlSync = useMemo<DispatchThreadUrlSync>(\n () => ({\n routeThreadId: routeThreadId ?? null,\n getPath: chatThreadPath,\n navigate: navigateThreadUrl,\n }),\n [routeThreadId, navigateThreadUrl],\n );\n const state = location.state as DispatchChatLocationState | null;\n const prompt = state?.dispatchPrompt;\n const thread = state?.dispatchThread;\n\n useEffect(() => {\n const message = prompt?.message?.trim();\n const threadId = thread?.threadId?.trim();\n if (!message && !threadId) return;\n\n const stateId = String(\n prompt?.id ?? thread?.id ?? `${message ?? \"\"}:${threadId ?? \"\"}`,\n );\n if (handledStateIds.current.has(stateId)) return;\n handledStateIds.current.add(stateId);\n\n const timer = window.setTimeout(() => {\n if (threadId) {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:open-thread\", {\n detail: { threadId },\n }),\n );\n }\n if (message) {\n submitOverviewPrompt(message, prompt?.selectedModel, {\n openSidebar: false,\n });\n }\n navigate(`${location.pathname}${location.search}${location.hash}`, {\n replace: true,\n state: null,\n });\n }, 0);\n\n return () => window.clearTimeout(timer);\n }, [\n location.hash,\n location.pathname,\n location.search,\n navigate,\n prompt?.id,\n prompt?.message,\n prompt?.selectedModel,\n thread?.id,\n thread?.threadId,\n ]);\n\n useEffect(() => {\n function handleChatRunning(event: Event) {\n const detail = (event as CustomEvent).detail;\n if (detail?.isRunning === true) markAgentChatHomeHandoff(\"dispatch\");\n }\n\n window.addEventListener(\"agentNative.chatRunning\", handleChatRunning);\n return () =>\n window.removeEventListener(\"agentNative.chatRunning\", handleChatRunning);\n }, []);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col bg-background\">\n <DispatchAgentChatSurface\n mode=\"page\"\n chatViewTransition\n className=\"dispatch-chat-panel\"\n defaultMode=\"chat\"\n storageKey=\"dispatch\"\n threadUrlSync={threadUrlSync}\n showHeader={false}\n showTabBar={false}\n dynamicSuggestions={false}\n suggestions={[]}\n emptyStateText={t(\"dispatch.pages.chatAcrossAppsDescription\", {\n defaultValue:\n \"Route work, inspect status, or create something new from one place.\",\n })}\n emptyStateDisplay=\"hidden\"\n {...(!prompt?.message\n ? {\n centerComposerWhenEmpty: true,\n composerLayoutVariant: \"hero\" as const,\n }\n : {})}\n composerPlaceholder={t(\"dispatch.pages.chatPromptPlaceholder\", {\n defaultValue: \"Ask Dispatch...\",\n })}\n composerSlot={\n !prompt?.message ? (\n <div className=\"dispatch-chat-intro\">\n <h1>\n {t(\"dispatch.pages.chatAcrossApps\", {\n defaultValue: \"Chat across your apps\",\n })}\n </h1>\n <p>\n {t(\"dispatch.pages.chatAcrossAppsDescription\", {\n defaultValue:\n \"Route work, inspect status, or create something new from one place.\",\n })}\n </p>\n </div>\n ) : null\n }\n />\n </div>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destinations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/destinations.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"destinations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/destinations.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,IAAI;;IAEnB;AA4CD,MAAM,CAAC,OAAO,UAAU,iBAAiB,oDA+MxC"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useActionMutation, useActionQuery, useT, } from "@agent-native/core/client";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { toast } from "sonner";
|
|
5
|
+
import { ActionQueryError } from "../../components/action-query-error.js";
|
|
5
6
|
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
6
7
|
import { TaskQueueHealth } from "../../components/task-queue-health.js";
|
|
7
8
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "../../components/ui/alert-dialog.js";
|
|
@@ -33,7 +34,8 @@ function QuickSendRow({ destination, }) {
|
|
|
33
34
|
}
|
|
34
35
|
export default function DestinationsRoute() {
|
|
35
36
|
const t = useT();
|
|
36
|
-
const
|
|
37
|
+
const destinationsQuery = useActionQuery("list-destinations", {});
|
|
38
|
+
const { data } = destinationsQuery;
|
|
37
39
|
const [form, setForm] = useState({
|
|
38
40
|
name: "",
|
|
39
41
|
platform: "slack",
|
|
@@ -56,11 +58,11 @@ export default function DestinationsRoute() {
|
|
|
56
58
|
const remove = useActionMutation("delete-destination", {
|
|
57
59
|
onSuccess: () => toast.success(t("dispatch.pages.destinationRemoved")),
|
|
58
60
|
});
|
|
59
|
-
return (_jsx(DispatchShell, { title: t("dispatch.nav.destinations"), description: t("dispatch.pages.destinationsDescription"), children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(TaskQueueHealth, {}), _jsxs("div", { className: "grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]", children: [_jsxs("section", { className: "rounded-2xl border bg-card p-5", children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: t("dispatch.pages.savedDestinations") }), _jsxs("div", { className: "mt-4 space-y-3", children: [(data || []).map((destination) => (_jsxs("div", { className: "rounded-xl border bg-muted/30 p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: destination.name }), _jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [destination.platform, " \u00B7 ", destination.destination, destination.threadRef
|
|
61
|
+
return (_jsx(DispatchShell, { title: t("dispatch.nav.destinations"), description: t("dispatch.pages.destinationsDescription"), children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(TaskQueueHealth, {}), _jsxs("div", { className: "grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]", children: [_jsxs("section", { className: "rounded-2xl border bg-card p-5", children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: t("dispatch.pages.savedDestinations") }), destinationsQuery.isError ? (_jsx(ActionQueryError, { className: "mt-4", error: destinationsQuery.error, onRetry: () => void destinationsQuery.refetch() })) : (_jsxs("div", { className: "mt-4 space-y-3", children: [(data || []).map((destination) => (_jsxs("div", { className: "rounded-xl border bg-muted/30 p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: destination.name }), _jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [destination.platform, " \u00B7 ", destination.destination, destination.threadRef
|
|
60
62
|
? ` · thread ${destination.threadRef}`
|
|
61
63
|
: ""] }), destination.notes && (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: destination.notes }))] }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "sm", children: t("dispatch.pages.delete") }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("dispatch.pages.deleteDestinationTitle") }), _jsx(AlertDialogDescription, { children: t("dispatch.pages.deleteDestinationDescription", {
|
|
62
64
|
name: destination.name,
|
|
63
|
-
}) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: t("dispatch.pages.cancel") }), _jsx(AlertDialogAction, { onClick: () => remove.mutate({ id: destination.id }), children: t("dispatch.pages.delete") })] })] })] })] }), _jsx(QuickSendRow, { destination: destination })] }, destination.id))), (data?.length || 0) === 0 && (_jsx("div", { className: "rounded-xl border border-dashed px-4 py-8 text-sm text-muted-foreground", children: t("dispatch.pages.noDestinations") }))] })] }), _jsxs("section", { className: "rounded-2xl border bg-card p-5", children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: t("dispatch.pages.addDestination") }), _jsxs("div", { className: "mt-4 space-y-3", children: [_jsx(Input, { value: form.name, onChange: (event) => setForm((current) => ({
|
|
65
|
+
}) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: t("dispatch.pages.cancel") }), _jsx(AlertDialogAction, { onClick: () => remove.mutate({ id: destination.id }), children: t("dispatch.pages.delete") })] })] })] })] }), _jsx(QuickSendRow, { destination: destination })] }, destination.id))), (data?.length || 0) === 0 && (_jsx("div", { className: "rounded-xl border border-dashed px-4 py-8 text-sm text-muted-foreground", children: t("dispatch.pages.noDestinations") }))] }))] }), _jsxs("section", { className: "rounded-2xl border bg-card p-5", children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: t("dispatch.pages.addDestination") }), _jsxs("div", { className: "mt-4 space-y-3", children: [_jsx(Input, { value: form.name, onChange: (event) => setForm((current) => ({
|
|
64
66
|
...current,
|
|
65
67
|
name: event.target.value,
|
|
66
68
|
})), placeholder: t("dispatch.pages.dailyDigestChannel") }), _jsxs(Select, { value: form.platform, onValueChange: (value) => setForm((current) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destinations.js","sourceRoot":"","sources":["../../../src/routes/pages/destinations.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useActionMutation,\n useActionQuery,\n useT,\n} from \"@agent-native/core/client\";\nimport { useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { TaskQueueHealth } from \"../../components/task-queue-health\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"../../components/ui/alert-dialog\";\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 { Textarea } from \"../../components/ui/textarea\";\n\nexport function meta() {\n return [{ title: \"Destinations — Dispatch\" }];\n}\n\nfunction QuickSendRow({\n destination,\n}: {\n destination: { id: string; name: string };\n}) {\n const t = useT();\n const [text, setText] = useState(\"\");\n const send = useActionMutation(\"send-platform-message\", {\n onSuccess: () => {\n toast.success(t(\"dispatch.pages.messageSent\"));\n setText(\"\");\n },\n onError: (error) => {\n toast.error(\n error instanceof Error\n ? error.message\n : t(\"dispatch.pages.unableToSendMessage\"),\n );\n },\n });\n return (\n <div className=\"mt-3 flex gap-2\">\n <Input\n value={text}\n onChange={(event) => setText(event.target.value)}\n placeholder={t(\"dispatch.pages.quickTestMessage\")}\n />\n <Button\n onClick={() =>\n send.mutate({\n destinationId: destination.id,\n text: text || `Test message to ${destination.name}`,\n })\n }\n disabled={send.isPending}\n >\n {t(\"dispatch.pages.send\")}\n </Button>\n </div>\n );\n}\n\nexport default function DestinationsRoute() {\n const t = useT();\n const { data } = useActionQuery(\"list-destinations\", {});\n const [form, setForm] = useState({\n name: \"\",\n platform: \"slack\",\n destination: \"\",\n threadRef: \"\",\n notes: \"\",\n });\n\n const upsert = useActionMutation(\"upsert-destination\", {\n onSuccess: () => {\n toast.success(t(\"dispatch.pages.destinationSaved\"));\n setForm((current) => ({\n ...current,\n name: \"\",\n destination: \"\",\n threadRef: \"\",\n notes: \"\",\n }));\n },\n });\n const remove = useActionMutation(\"delete-destination\", {\n onSuccess: () => toast.success(t(\"dispatch.pages.destinationRemoved\")),\n });\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.destinations\")}\n description={t(\"dispatch.pages.destinationsDescription\")}\n >\n <div className=\"flex flex-col gap-4\">\n <TaskQueueHealth />\n <div className=\"grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]\">\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {t(\"dispatch.pages.savedDestinations\")}\n </h2>\n <div className=\"mt-4 space-y-3\">\n {(data || []).map((destination: any) => (\n <div\n key={destination.id}\n className=\"rounded-xl border bg-muted/30 p-4\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <div className=\"text-sm font-medium text-foreground\">\n {destination.name}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {destination.platform} · {destination.destination}\n {destination.threadRef\n ? ` · thread ${destination.threadRef}`\n : \"\"}\n </div>\n {destination.notes && (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {destination.notes}\n </p>\n )}\n </div>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n {t(\"dispatch.pages.delete\")}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t(\"dispatch.pages.deleteDestinationTitle\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\"dispatch.pages.deleteDestinationDescription\", {\n name: destination.name,\n })}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {t(\"dispatch.pages.cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={() =>\n remove.mutate({ id: destination.id })\n }\n >\n {t(\"dispatch.pages.delete\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n <QuickSendRow destination={destination} />\n </div>\n ))}\n {(data?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-8 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noDestinations\")}\n </div>\n )}\n </div>\n </section>\n\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {t(\"dispatch.pages.addDestination\")}\n </h2>\n <div className=\"mt-4 space-y-3\">\n <Input\n value={form.name}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n name: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.dailyDigestChannel\")}\n />\n <Select\n value={form.platform}\n onValueChange={(value) =>\n setForm((current) => ({\n ...current,\n platform: value,\n }))\n }\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"slack\">Slack</SelectItem>\n <SelectItem value=\"telegram\">Telegram</SelectItem>\n <SelectItem value=\"email\">Email</SelectItem>\n </SelectContent>\n </Select>\n <Input\n value={form.destination}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n destination: event.target.value,\n }))\n }\n placeholder={\n form.platform === \"slack\"\n ? \"C0123456789\"\n : form.platform === \"email\"\n ? \"teammate+qa@agent-native.test\"\n : \"123456789\"\n }\n />\n <Input\n value={form.threadRef}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n threadRef: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.optionalThreadOrTopicId\")}\n />\n <Textarea\n value={form.notes}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n notes: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.destinationNotes\")}\n />\n <Button\n className=\"w-full\"\n onClick={() =>\n upsert.mutate({\n name: form.name,\n platform: form.platform as \"slack\" | \"telegram\" | \"email\",\n destination: form.destination,\n threadRef: form.threadRef || undefined,\n notes: form.notes || undefined,\n })\n }\n disabled={!form.name || !form.destination}\n >\n {t(\"dispatch.pages.saveDestination\")}\n </Button>\n </div>\n </section>\n </div>\n </div>\n </DispatchShell>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"destinations.js","sourceRoot":"","sources":["../../../src/routes/pages/destinations.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useActionMutation,\n useActionQuery,\n useT,\n} from \"@agent-native/core/client\";\nimport { useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { TaskQueueHealth } from \"../../components/task-queue-health\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"../../components/ui/alert-dialog\";\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 { Textarea } from \"../../components/ui/textarea\";\n\nexport function meta() {\n return [{ title: \"Destinations — Dispatch\" }];\n}\n\nfunction QuickSendRow({\n destination,\n}: {\n destination: { id: string; name: string };\n}) {\n const t = useT();\n const [text, setText] = useState(\"\");\n const send = useActionMutation(\"send-platform-message\", {\n onSuccess: () => {\n toast.success(t(\"dispatch.pages.messageSent\"));\n setText(\"\");\n },\n onError: (error) => {\n toast.error(\n error instanceof Error\n ? error.message\n : t(\"dispatch.pages.unableToSendMessage\"),\n );\n },\n });\n return (\n <div className=\"mt-3 flex gap-2\">\n <Input\n value={text}\n onChange={(event) => setText(event.target.value)}\n placeholder={t(\"dispatch.pages.quickTestMessage\")}\n />\n <Button\n onClick={() =>\n send.mutate({\n destinationId: destination.id,\n text: text || `Test message to ${destination.name}`,\n })\n }\n disabled={send.isPending}\n >\n {t(\"dispatch.pages.send\")}\n </Button>\n </div>\n );\n}\n\nexport default function DestinationsRoute() {\n const t = useT();\n const destinationsQuery = useActionQuery(\"list-destinations\", {});\n const { data } = destinationsQuery;\n const [form, setForm] = useState({\n name: \"\",\n platform: \"slack\",\n destination: \"\",\n threadRef: \"\",\n notes: \"\",\n });\n\n const upsert = useActionMutation(\"upsert-destination\", {\n onSuccess: () => {\n toast.success(t(\"dispatch.pages.destinationSaved\"));\n setForm((current) => ({\n ...current,\n name: \"\",\n destination: \"\",\n threadRef: \"\",\n notes: \"\",\n }));\n },\n });\n const remove = useActionMutation(\"delete-destination\", {\n onSuccess: () => toast.success(t(\"dispatch.pages.destinationRemoved\")),\n });\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.destinations\")}\n description={t(\"dispatch.pages.destinationsDescription\")}\n >\n <div className=\"flex flex-col gap-4\">\n <TaskQueueHealth />\n <div className=\"grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]\">\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {t(\"dispatch.pages.savedDestinations\")}\n </h2>\n {destinationsQuery.isError ? (\n <ActionQueryError\n className=\"mt-4\"\n error={destinationsQuery.error}\n onRetry={() => void destinationsQuery.refetch()}\n />\n ) : (\n <div className=\"mt-4 space-y-3\">\n {(data || []).map((destination: any) => (\n <div\n key={destination.id}\n className=\"rounded-xl border bg-muted/30 p-4\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <div className=\"text-sm font-medium text-foreground\">\n {destination.name}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {destination.platform} · {destination.destination}\n {destination.threadRef\n ? ` · thread ${destination.threadRef}`\n : \"\"}\n </div>\n {destination.notes && (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {destination.notes}\n </p>\n )}\n </div>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n {t(\"dispatch.pages.delete\")}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t(\"dispatch.pages.deleteDestinationTitle\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\n \"dispatch.pages.deleteDestinationDescription\",\n {\n name: destination.name,\n },\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>\n {t(\"dispatch.pages.cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={() =>\n remove.mutate({ id: destination.id })\n }\n >\n {t(\"dispatch.pages.delete\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n <QuickSendRow destination={destination} />\n </div>\n ))}\n {(data?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-8 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noDestinations\")}\n </div>\n )}\n </div>\n )}\n </section>\n\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {t(\"dispatch.pages.addDestination\")}\n </h2>\n <div className=\"mt-4 space-y-3\">\n <Input\n value={form.name}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n name: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.dailyDigestChannel\")}\n />\n <Select\n value={form.platform}\n onValueChange={(value) =>\n setForm((current) => ({\n ...current,\n platform: value,\n }))\n }\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"slack\">Slack</SelectItem>\n <SelectItem value=\"telegram\">Telegram</SelectItem>\n <SelectItem value=\"email\">Email</SelectItem>\n </SelectContent>\n </Select>\n <Input\n value={form.destination}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n destination: event.target.value,\n }))\n }\n placeholder={\n form.platform === \"slack\"\n ? \"C0123456789\"\n : form.platform === \"email\"\n ? \"teammate+qa@agent-native.test\"\n : \"123456789\"\n }\n />\n <Input\n value={form.threadRef}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n threadRef: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.optionalThreadOrTopicId\")}\n />\n <Textarea\n value={form.notes}\n onChange={(event) =>\n setForm((current) => ({\n ...current,\n notes: event.target.value,\n }))\n }\n placeholder={t(\"dispatch.pages.destinationNotes\")}\n />\n <Button\n className=\"w-full\"\n onClick={() =>\n upsert.mutate({\n name: form.name,\n platform: form.platform as \"slack\" | \"telegram\" | \"email\",\n destination: form.destination,\n threadRef: form.threadRef || undefined,\n notes: form.notes || undefined,\n })\n }\n disabled={!form.name || !form.destination}\n >\n {t(\"dispatch.pages.saveDestination\")}\n </Button>\n </div>\n </section>\n </div>\n </div>\n </DispatchShell>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identities.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/identities.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identities.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/identities.tsx"],"names":[],"mappings":"AAOA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,oDA2FtC"}
|