@agent-native/dispatch 0.19.2 → 0.20.1
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/dist/actions/provider-api-register.d.ts +5 -5
- package/dist/actions/start-workspace-app-creation.js +1 -1
- package/dist/actions/start-workspace-app-creation.js.map +1 -1
- package/dist/components/admin-navigation.d.ts +2 -1
- package/dist/components/admin-navigation.d.ts.map +1 -1
- package/dist/components/admin-navigation.js +10 -7
- package/dist/components/admin-navigation.js.map +1 -1
- package/dist/components/app-icon.d.ts +9 -0
- package/dist/components/app-icon.d.ts.map +1 -0
- package/dist/components/app-icon.js +85 -0
- package/dist/components/app-icon.js.map +1 -0
- package/dist/components/app-list-row.d.ts +12 -0
- package/dist/components/app-list-row.d.ts.map +1 -0
- package/dist/components/app-list-row.js +11 -0
- package/dist/components/app-list-row.js.map +1 -0
- package/dist/components/app-open-actions.d.ts +17 -0
- package/dist/components/app-open-actions.d.ts.map +1 -0
- package/dist/components/app-open-actions.js +20 -0
- package/dist/components/app-open-actions.js.map +1 -0
- package/dist/components/connected-app-card.d.ts +2 -1
- package/dist/components/connected-app-card.d.ts.map +1 -1
- package/dist/components/connected-app-card.js +8 -8
- package/dist/components/connected-app-card.js.map +1 -1
- package/dist/components/dispatch-control-plane.d.ts.map +1 -1
- package/dist/components/dispatch-control-plane.js +21 -14
- package/dist/components/dispatch-control-plane.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +40 -19
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
- package/dist/components/layout/workspace-apps-rail.js +10 -10
- package/dist/components/layout/workspace-apps-rail.js.map +1 -1
- package/dist/components/other-apps-section.d.ts +31 -0
- package/dist/components/other-apps-section.d.ts.map +1 -0
- package/dist/components/other-apps-section.js +59 -0
- package/dist/components/other-apps-section.js.map +1 -0
- package/dist/components/workspace-app-card.d.ts.map +1 -1
- package/dist/components/workspace-app-card.js +38 -28
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/components/workspace-template-card.d.ts +8 -2
- package/dist/components/workspace-template-card.d.ts.map +1 -1
- package/dist/components/workspace-template-card.js +17 -13
- package/dist/components/workspace-template-card.js.map +1 -1
- package/dist/lib/other-apps.d.ts.map +1 -1
- package/dist/lib/other-apps.js +5 -1
- package/dist/lib/other-apps.js.map +1 -1
- package/dist/lib/workspace-apps.d.ts +1 -0
- package/dist/lib/workspace-apps.d.ts.map +1 -1
- package/dist/lib/workspace-apps.js +3 -0
- package/dist/lib/workspace-apps.js.map +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +0 -2
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/pages/admin._index.d.ts.map +1 -1
- package/dist/routes/pages/admin._index.js +32 -7
- package/dist/routes/pages/admin._index.js.map +1 -1
- package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
- package/dist/routes/pages/apps.$appId.js +62 -13
- package/dist/routes/pages/apps.$appId.js.map +1 -1
- package/dist/routes/pages/apps.d.ts +1 -1
- package/dist/routes/pages/apps.d.ts.map +1 -1
- package/dist/routes/pages/apps.js +21 -30
- package/dist/routes/pages/apps.js.map +1 -1
- package/dist/server/plugins/agent-chat.js +6 -1
- package/dist/server/plugins/agent-chat.js.map +1 -1
- package/package.json +2 -2
- package/src/actions/start-workspace-app-creation.ts +1 -1
- package/src/components/admin-navigation.tsx +21 -16
- package/src/components/app-icon.tsx +149 -0
- package/src/components/app-list-row.tsx +40 -0
- package/src/components/app-open-actions.tsx +111 -0
- package/src/components/connected-app-card.tsx +30 -34
- package/src/components/dispatch-control-plane.spec.tsx +28 -1
- package/src/components/dispatch-control-plane.tsx +122 -48
- package/src/components/layout/Layout.spec.tsx +4 -4
- package/src/components/layout/Layout.tsx +86 -55
- package/src/components/layout/workspace-apps-rail.tsx +20 -21
- package/src/components/other-apps-section.tsx +195 -0
- package/src/components/workspace-app-card.spec.tsx +58 -32
- package/src/components/workspace-app-card.tsx +222 -158
- package/src/components/workspace-template-card.spec.tsx +45 -7
- package/src/components/workspace-template-card.tsx +74 -81
- package/src/lib/other-apps.spec.ts +31 -0
- package/src/lib/other-apps.ts +9 -1
- package/src/lib/workspace-apps.ts +4 -0
- package/src/routes/index.spec.ts +2 -1
- package/src/routes/index.ts +0 -2
- package/src/routes/pages/admin._index.tsx +85 -17
- package/src/routes/pages/apps.$appId.tsx +144 -57
- package/src/routes/pages/apps.tsx +76 -147
- package/src/server/plugins/agent-chat.spec.ts +5 -0
- package/src/server/plugins/agent-chat.ts +6 -1
|
@@ -47,8 +47,8 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
47
47
|
notes?: string | undefined;
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
|
+
id?: undefined;
|
|
50
51
|
deleted?: undefined;
|
|
51
|
-
found?: undefined;
|
|
52
52
|
providers: {
|
|
53
53
|
id: string;
|
|
54
54
|
label: string;
|
|
@@ -60,18 +60,18 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
60
60
|
}[];
|
|
61
61
|
count: number;
|
|
62
62
|
provider?: undefined;
|
|
63
|
+
found?: undefined;
|
|
63
64
|
registered?: undefined;
|
|
64
|
-
id?: undefined;
|
|
65
65
|
label?: undefined;
|
|
66
66
|
message?: undefined;
|
|
67
67
|
} | {
|
|
68
|
+
id?: undefined;
|
|
68
69
|
deleted?: undefined;
|
|
69
70
|
providers?: undefined;
|
|
70
71
|
count?: undefined;
|
|
71
72
|
found: boolean;
|
|
72
73
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
73
74
|
registered?: undefined;
|
|
74
|
-
id?: undefined;
|
|
75
75
|
label?: undefined;
|
|
76
76
|
message?: undefined;
|
|
77
77
|
} | {
|
|
@@ -85,10 +85,10 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
85
85
|
label?: undefined;
|
|
86
86
|
message?: undefined;
|
|
87
87
|
} | {
|
|
88
|
-
found?: undefined;
|
|
89
88
|
providers?: undefined;
|
|
90
89
|
count?: undefined;
|
|
91
90
|
provider?: undefined;
|
|
91
|
+
found?: undefined;
|
|
92
92
|
deleted: boolean;
|
|
93
93
|
id: string;
|
|
94
94
|
registered?: undefined;
|
|
@@ -96,10 +96,10 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
96
96
|
message?: undefined;
|
|
97
97
|
} | {
|
|
98
98
|
deleted?: undefined;
|
|
99
|
-
found?: undefined;
|
|
100
99
|
providers?: undefined;
|
|
101
100
|
count?: undefined;
|
|
102
101
|
provider?: undefined;
|
|
102
|
+
found?: undefined;
|
|
103
103
|
registered: boolean;
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
@@ -3,7 +3,7 @@ import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { startWorkspaceAppCreation } from "../server/lib/app-creation-store.js";
|
|
5
5
|
export default defineAction({
|
|
6
|
-
description: 'Start creating a new workspace app from Dispatch when the request truly needs its own app. Callers should include a concise generated description by default; Dispatch generates one from the prompt when omitted. In local dev this returns a code-agent prompt; in production it creates a Builder branch only when a Builder branch project is configured. If the result mode is "coming-soon", the work still requires a code change but no Builder Cloud Agent can run here; tell the user to edit locally or use Builder.io to edit this code in the cloud and continue customizing the app any way they like, and do not send them to Builder org/beta settings. The result must be a separate workspace app under apps/<app-id>, not a new route or file in apps/chat. If chat is used as the source template, the finished app must be branded as the requested app and must not leave visible "Chat", "Starter", "Blank app", or "New app" UI behind. If the request needs Mail, Calendar, Analytics, Brain, Assets, or another first-party app, use the existing hosted/connected app via links or A2A; do not wrap or nest those apps inside the new app unless the user explicitly asks for a customized app from that template.',
|
|
6
|
+
description: 'Start creating a new workspace app from Dispatch when the request truly needs its own app. For Claude Web, ChatGPT Web, or either host\'s web Project, this action is the Builder handoff: call it after forming a bounded source brief and do not scaffold or edit files in the host sandbox. Callers should include a concise generated description by default; Dispatch generates one from the prompt when omitted. In local dev this returns a code-agent prompt; in production it creates a Builder branch only when a Builder branch project is configured. If the result mode is "coming-soon", the work still requires a code change but no Builder Cloud Agent can run here; tell the user to edit locally or use Builder.io to edit this code in the cloud and continue customizing the app any way they like, and do not send them to Builder org/beta settings. The result must be a separate workspace app under apps/<app-id>, not a new route or file in apps/chat. If chat is used as the source template, the finished app must be branded as the requested app and must not leave visible "Chat", "Starter", "Blank app", or "New app" UI behind. If the request needs Mail, Calendar, Analytics, Brain, Assets, or another first-party app, use the existing hosted/connected app via links or A2A; do not wrap or nest those apps inside the new app unless the user explicitly asks for a customized app from that template.',
|
|
7
7
|
schema: z.object({
|
|
8
8
|
prompt: z.string().min(1).describe("The user's app creation request"),
|
|
9
9
|
appId: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-workspace-app-creation.js","sourceRoot":"","sources":["../../src/actions/start-workspace-app-creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT
|
|
1
|
+
{"version":3,"file":"start-workspace-app-creation.js","sourceRoot":"","sources":["../../src/actions/start-workspace-app-creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,m3CAAm3C;IACr3C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACrE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE;YAC3D,OAAO,EACL,yEAAyE;SAC5E,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,+BAA+B,CAAC;QAC5C,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,wBAAwB,CAAC;QACrC,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,6HAA6H,CAC9H;QACH,SAAS,EAAE,CAAC;aACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,+CAA+C,CAAC;QAC5D,WAAW,EAAE,CAAC;aACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wEAAwE,CACzE;KACJ,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;CACrD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { startWorkspaceAppCreation } from \"../server/lib/app-creation-store.js\";\n\nexport default defineAction({\n description:\n 'Start creating a new workspace app from Dispatch when the request truly needs its own app. For Claude Web, ChatGPT Web, or either host\\'s web Project, this action is the Builder handoff: call it after forming a bounded source brief and do not scaffold or edit files in the host sandbox. Callers should include a concise generated description by default; Dispatch generates one from the prompt when omitted. In local dev this returns a code-agent prompt; in production it creates a Builder branch only when a Builder branch project is configured. If the result mode is \"coming-soon\", the work still requires a code change but no Builder Cloud Agent can run here; tell the user to edit locally or use Builder.io to edit this code in the cloud and continue customizing the app any way they like, and do not send them to Builder org/beta settings. The result must be a separate workspace app under apps/<app-id>, not a new route or file in apps/chat. If chat is used as the source template, the finished app must be branded as the requested app and must not leave visible \"Chat\", \"Starter\", \"Blank app\", or \"New app\" UI behind. If the request needs Mail, Calendar, Analytics, Brain, Assets, or another first-party app, use the existing hosted/connected app via links or A2A; do not wrap or nest those apps inside the new app unless the user explicitly asks for a customized app from that template.',\n schema: z.object({\n prompt: z.string().min(1).describe(\"The user's app creation request\"),\n appId: z\n .string()\n .max(64)\n .refine((appId) => !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .optional()\n .nullable()\n .describe(\"Desired workspace app id/path\"),\n template: z\n .string()\n .optional()\n .nullable()\n .describe(\"Template to start from\"),\n description: z\n .string()\n .max(500)\n .optional()\n .nullable()\n .describe(\n \"Concise AI-generated description of the app based on the user's prompt. Dispatch saves this while the app is being created.\",\n ),\n secretIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\"Dispatch vault secret IDs to grant to the app\"),\n resourceIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\n \"Dispatch workspace resource IDs or knowledge packs to grant to the app\",\n ),\n }),\n run: async (args) => startWorkspaceAppCreation(args),\n});\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type DispatchNavItem } from "./layout/Layout.js";
|
|
3
|
-
interface AdminNavGroup {
|
|
3
|
+
export interface AdminNavGroup {
|
|
4
4
|
id: string;
|
|
5
5
|
label: string;
|
|
6
6
|
labelKey: string;
|
|
@@ -12,4 +12,5 @@ export declare function AdminShell({ children, onNavigate, }: {
|
|
|
12
12
|
onNavigate?: () => void;
|
|
13
13
|
}): import("node_modules/@types/react").JSX.Element;
|
|
14
14
|
export { BUILT_IN_ADMIN_NAV_GROUPS };
|
|
15
|
+
export declare function useAdminNavGroups(): readonly AdminNavGroup[];
|
|
15
16
|
//# sourceMappingURL=admin-navigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-navigation.d.ts","sourceRoot":"","sources":["../../src/components/admin-navigation.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE9E,
|
|
1
|
+
{"version":3,"file":"admin-navigation.d.ts","sourceRoot":"","sources":["../../src/components/admin-navigation.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CACnC;AAED,QAAA,MAAM,yBAAyB,EAAE,SAAS,aAAa,EAoItD,CAAC;AAwCF,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,mDAmDA;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC,wBAAgB,iBAAiB,IAAI,SAAS,aAAa,EAAE,CAiB5D"}
|
|
@@ -151,9 +151,18 @@ function AdminNavLink({ item, onNavigate, }) {
|
|
|
151
151
|
}
|
|
152
152
|
export function AdminShell({ children, onNavigate, }) {
|
|
153
153
|
const t = useT();
|
|
154
|
+
const groups = useAdminNavGroups();
|
|
155
|
+
return (_jsxs("div", { className: "grid min-w-0 gap-6 lg:grid-cols-[13rem_minmax(0,1fr)]", "data-dispatch-admin-shell": true, children: [_jsxs("aside", { className: "min-w-0 border-b pb-5 lg:sticky lg:top-2 lg:self-start lg:border-b-0 lg:border-e lg:pe-6", children: [_jsxs("div", { className: "px-2", children: [_jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: t("dispatch.nav.admin", { defaultValue: "Admin" }) }), _jsx("p", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: t("dispatch.pages.adminDescription", {
|
|
156
|
+
defaultValue: "Workspace controls and operations",
|
|
157
|
+
}) })] }), _jsx("nav", { "aria-label": t("dispatch.pages.adminNavigation", {
|
|
158
|
+
defaultValue: "Admin navigation",
|
|
159
|
+
}), className: "mt-5 space-y-5", children: groups.map((group) => (_jsxs("section", { children: [_jsx("h2", { className: "px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground/70", children: t(group.labelKey, { defaultValue: group.label }) }), _jsx("ul", { className: "mt-1 space-y-0.5", children: group.items.map((item) => (_jsx(AdminNavLink, { item: item, onNavigate: onNavigate }, item.id))) })] }, group.id))) })] }), _jsx("section", { className: "min-w-0", "data-dispatch-admin-content": true, children: children })] }));
|
|
160
|
+
}
|
|
161
|
+
export { BUILT_IN_ADMIN_NAV_GROUPS };
|
|
162
|
+
export function useAdminNavGroups() {
|
|
154
163
|
const extensions = useDispatchExtensions();
|
|
155
164
|
const extensionItems = (extensions?.navItems ?? []).filter((item) => item.section === "operations");
|
|
156
|
-
|
|
165
|
+
return extensionItems.length
|
|
157
166
|
? [
|
|
158
167
|
...BUILT_IN_ADMIN_NAV_GROUPS,
|
|
159
168
|
{
|
|
@@ -164,11 +173,5 @@ export function AdminShell({ children, onNavigate, }) {
|
|
|
164
173
|
},
|
|
165
174
|
]
|
|
166
175
|
: BUILT_IN_ADMIN_NAV_GROUPS;
|
|
167
|
-
return (_jsxs("div", { className: "grid min-w-0 gap-6 lg:grid-cols-[13rem_minmax(0,1fr)]", "data-dispatch-admin-shell": true, children: [_jsxs("aside", { className: "min-w-0 border-b pb-5 lg:sticky lg:top-2 lg:self-start lg:border-b-0 lg:border-e lg:pe-6", children: [_jsxs("div", { className: "px-2", children: [_jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: t("dispatch.nav.admin", { defaultValue: "Admin" }) }), _jsx("p", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: t("dispatch.pages.adminDescription", {
|
|
168
|
-
defaultValue: "Workspace controls and operations",
|
|
169
|
-
}) })] }), _jsx("nav", { "aria-label": t("dispatch.pages.adminNavigation", {
|
|
170
|
-
defaultValue: "Admin navigation",
|
|
171
|
-
}), className: "mt-5 space-y-5", children: groups.map((group) => (_jsxs("section", { children: [_jsx("h2", { className: "px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground/70", children: t(group.labelKey, { defaultValue: group.label }) }), _jsx("ul", { className: "mt-1 space-y-0.5", children: group.items.map((item) => (_jsx(AdminNavLink, { item: item, onNavigate: onNavigate }, item.id))) })] }, group.id))) })] }), _jsx("section", { className: "min-w-0", "data-dispatch-admin-content": true, children: children })] }));
|
|
172
176
|
}
|
|
173
|
-
export { BUILT_IN_ADMIN_NAV_GROUPS };
|
|
174
177
|
//# sourceMappingURL=admin-navigation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-navigation.js","sourceRoot":"","sources":["../../src/components/admin-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconActivity,\n IconArrowUpRight,\n IconBrain,\n IconBrandTelegram,\n IconChartBar,\n IconFingerprint,\n IconHistory,\n IconKey,\n IconLayersSubtract,\n IconMail,\n IconMessages,\n IconPlugConnected,\n IconPuzzle,\n IconSettingsAutomation,\n IconShield,\n IconShieldCheck,\n} from \"@tabler/icons-react\";\nimport { type ReactNode } from \"react\";\nimport { NavLink } from \"react-router\";\n\nimport { cn } from \"../lib/utils\";\nimport { useDispatchExtensions, type DispatchNavItem } from \"./layout/Layout\";\n\ninterface AdminNavGroup {\n id: string;\n label: string;\n labelKey: string;\n items: readonly DispatchNavItem[];\n}\n\nconst BUILT_IN_ADMIN_NAV_GROUPS: readonly AdminNavGroup[] = [\n {\n id: \"workspace\",\n label: \"Workspace\",\n labelKey: \"dispatch.pages.adminWorkspace\",\n items: [\n {\n id: \"admin-overview\",\n to: \"/admin\",\n label: \"Overview\",\n icon: IconShield,\n },\n {\n id: \"admin-resources\",\n to: \"/admin/workspace\",\n label: \"Resources\",\n icon: IconLayersSubtract,\n },\n ],\n },\n {\n id: \"operations\",\n label: \"Operations\",\n labelKey: \"dispatch.pages.adminOperations\",\n items: [\n {\n id: \"operations\",\n to: \"/admin/operations\",\n label: \"Operations\",\n icon: IconActivity,\n },\n {\n id: \"metrics\",\n to: \"/admin/metrics\",\n label: \"Metrics\",\n icon: IconChartBar,\n },\n {\n id: \"audit\",\n to: \"/admin/audit\",\n label: \"Audit\",\n icon: IconHistory,\n },\n {\n id: \"thread-debug\",\n to: \"/admin/thread-debug\",\n label: \"Thread Debug\",\n icon: IconMessages,\n },\n ],\n },\n {\n id: \"automation\",\n label: \"Automation & delivery\",\n labelKey: \"dispatch.pages.adminAutomation\",\n items: [\n {\n id: \"automations\",\n to: \"/admin/automations\",\n label: \"Automations\",\n icon: IconSettingsAutomation,\n },\n {\n id: \"approvals\",\n to: \"/admin/approvals\",\n label: \"Approvals\",\n icon: IconShieldCheck,\n },\n {\n id: \"destinations\",\n to: \"/admin/destinations\",\n label: \"Destinations\",\n icon: IconArrowUpRight,\n },\n {\n id: \"transactional-email\",\n to: \"/admin/transactional-email\",\n label: \"Transactional email\",\n icon: IconMail,\n },\n ],\n },\n {\n id: \"connections\",\n label: \"Connections\",\n labelKey: \"dispatch.pages.adminConnections\",\n items: [\n {\n id: \"integrations\",\n to: \"/admin/integrations\",\n label: \"Integrations\",\n icon: IconPuzzle,\n },\n {\n id: \"vault\",\n to: \"/admin/vault\",\n label: \"Vault\",\n icon: IconKey,\n },\n {\n id: \"messaging\",\n to: \"/admin/messaging\",\n label: \"Messaging\",\n icon: IconBrandTelegram,\n },\n {\n id: \"identities\",\n to: \"/admin/identities\",\n label: \"Identities\",\n icon: IconFingerprint,\n },\n ],\n },\n {\n id: \"agent-platform\",\n label: \"Agent platform\",\n labelKey: \"dispatch.pages.adminAgentPlatform\",\n items: [\n {\n id: \"agents\",\n to: \"/admin/agents\",\n label: \"Agents\",\n icon: IconPlugConnected,\n },\n {\n id: \"dreams\",\n to: \"/admin/dreams\",\n label: \"Dreams\",\n icon: IconBrain,\n },\n ],\n },\n];\n\nfunction itemLabel(t: ReturnType<typeof useT>, item: DispatchNavItem) {\n return t(`dispatch.nav.${item.id}`, { defaultValue: item.label });\n}\n\nfunction AdminNavLink({\n item,\n onNavigate,\n}: {\n item: DispatchNavItem;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const to = item.adminTo ?? item.to;\n const label = itemLabel(t, item);\n const Icon = item.icon;\n\n return (\n <li>\n <NavLink\n to={to}\n end={item.id === \"admin-overview\"}\n onClick={onNavigate}\n className={({ isActive }) =>\n cn(\n \"flex min-h-8 items-center gap-2 rounded-md px-2 text-sm transition-colors\",\n isActive\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-muted-foreground hover:bg-accent/60 hover:text-foreground\",\n )\n }\n >\n {Icon ? <Icon size={15} className=\"shrink-0\" /> : null}\n <span className=\"truncate\">{label}</span>\n </NavLink>\n </li>\n );\n}\n\nexport function AdminShell({\n children,\n onNavigate,\n}: {\n children: ReactNode;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const extensions = useDispatchExtensions();\n const extensionItems = (extensions?.navItems ?? []).filter(\n (item) => item.section === \"operations\",\n );\n const groups = extensionItems.length\n ? [\n ...BUILT_IN_ADMIN_NAV_GROUPS,\n {\n id: \"workspace-extensions\",\n label: \"Workspace extensions\",\n labelKey: \"dispatch.pages.adminWorkspaceExtensions\",\n items: extensionItems,\n },\n ]\n : BUILT_IN_ADMIN_NAV_GROUPS;\n\n return (\n <div\n className=\"grid min-w-0 gap-6 lg:grid-cols-[13rem_minmax(0,1fr)]\"\n data-dispatch-admin-shell\n >\n <aside className=\"min-w-0 border-b pb-5 lg:sticky lg:top-2 lg:self-start lg:border-b-0 lg:border-e lg:pe-6\">\n <div className=\"px-2\">\n <div className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n {t(\"dispatch.nav.admin\", { defaultValue: \"Admin\" })}\n </div>\n <p className=\"mt-1 text-xs leading-5 text-muted-foreground\">\n {t(\"dispatch.pages.adminDescription\", {\n defaultValue: \"Workspace controls and operations\",\n })}\n </p>\n </div>\n\n <nav\n aria-label={t(\"dispatch.pages.adminNavigation\", {\n defaultValue: \"Admin navigation\",\n })}\n className=\"mt-5 space-y-5\"\n >\n {groups.map((group) => (\n <section key={group.id}>\n <h2 className=\"px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground/70\">\n {t(group.labelKey, { defaultValue: group.label })}\n </h2>\n <ul className=\"mt-1 space-y-0.5\">\n {group.items.map((item) => (\n <AdminNavLink\n key={item.id}\n item={item}\n onNavigate={onNavigate}\n />\n ))}\n </ul>\n </section>\n ))}\n </nav>\n </aside>\n\n <section className=\"min-w-0\" data-dispatch-admin-content>\n {children}\n </section>\n </div>\n );\n}\n\nexport { BUILT_IN_ADMIN_NAV_GROUPS };\n"]}
|
|
1
|
+
{"version":3,"file":"admin-navigation.js","sourceRoot":"","sources":["../../src/components/admin-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconActivity,\n IconArrowUpRight,\n IconBrain,\n IconBrandTelegram,\n IconChartBar,\n IconFingerprint,\n IconHistory,\n IconKey,\n IconLayersSubtract,\n IconMail,\n IconMessages,\n IconPlugConnected,\n IconPuzzle,\n IconSettingsAutomation,\n IconShield,\n IconShieldCheck,\n} from \"@tabler/icons-react\";\nimport { type ReactNode } from \"react\";\nimport { NavLink } from \"react-router\";\n\nimport { cn } from \"../lib/utils\";\nimport { useDispatchExtensions, type DispatchNavItem } from \"./layout/Layout\";\n\nexport interface AdminNavGroup {\n id: string;\n label: string;\n labelKey: string;\n items: readonly DispatchNavItem[];\n}\n\nconst BUILT_IN_ADMIN_NAV_GROUPS: readonly AdminNavGroup[] = [\n {\n id: \"workspace\",\n label: \"Workspace\",\n labelKey: \"dispatch.pages.adminWorkspace\",\n items: [\n {\n id: \"admin-overview\",\n to: \"/admin\",\n label: \"Overview\",\n icon: IconShield,\n },\n {\n id: \"admin-resources\",\n to: \"/admin/workspace\",\n label: \"Resources\",\n icon: IconLayersSubtract,\n },\n ],\n },\n {\n id: \"operations\",\n label: \"Operations\",\n labelKey: \"dispatch.pages.adminOperations\",\n items: [\n {\n id: \"operations\",\n to: \"/admin/operations\",\n label: \"Operations\",\n icon: IconActivity,\n },\n {\n id: \"metrics\",\n to: \"/admin/metrics\",\n label: \"Metrics\",\n icon: IconChartBar,\n },\n {\n id: \"audit\",\n to: \"/admin/audit\",\n label: \"Audit\",\n icon: IconHistory,\n },\n {\n id: \"thread-debug\",\n to: \"/admin/thread-debug\",\n label: \"Thread Debug\",\n icon: IconMessages,\n },\n ],\n },\n {\n id: \"automation\",\n label: \"Automation & delivery\",\n labelKey: \"dispatch.pages.adminAutomation\",\n items: [\n {\n id: \"automations\",\n to: \"/admin/automations\",\n label: \"Automations\",\n icon: IconSettingsAutomation,\n },\n {\n id: \"approvals\",\n to: \"/admin/approvals\",\n label: \"Approvals\",\n icon: IconShieldCheck,\n },\n {\n id: \"destinations\",\n to: \"/admin/destinations\",\n label: \"Destinations\",\n icon: IconArrowUpRight,\n },\n {\n id: \"transactional-email\",\n to: \"/admin/transactional-email\",\n label: \"Transactional email\",\n icon: IconMail,\n },\n ],\n },\n {\n id: \"connections\",\n label: \"Connections\",\n labelKey: \"dispatch.pages.adminConnections\",\n items: [\n {\n id: \"integrations\",\n to: \"/admin/integrations\",\n label: \"Integrations\",\n icon: IconPuzzle,\n },\n {\n id: \"vault\",\n to: \"/admin/vault\",\n label: \"Vault\",\n icon: IconKey,\n },\n {\n id: \"messaging\",\n to: \"/admin/messaging\",\n label: \"Messaging\",\n icon: IconBrandTelegram,\n },\n {\n id: \"identities\",\n to: \"/admin/identities\",\n label: \"Identities\",\n icon: IconFingerprint,\n },\n ],\n },\n {\n id: \"agent-platform\",\n label: \"Agent platform\",\n labelKey: \"dispatch.pages.adminAgentPlatform\",\n items: [\n {\n id: \"agents\",\n to: \"/admin/agents\",\n label: \"Agents\",\n icon: IconPlugConnected,\n },\n {\n id: \"dreams\",\n to: \"/admin/dreams\",\n label: \"Dreams\",\n icon: IconBrain,\n },\n ],\n },\n];\n\nfunction itemLabel(t: ReturnType<typeof useT>, item: DispatchNavItem) {\n return t(`dispatch.nav.${item.id}`, { defaultValue: item.label });\n}\n\nfunction AdminNavLink({\n item,\n onNavigate,\n}: {\n item: DispatchNavItem;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const to = item.adminTo ?? item.to;\n const label = itemLabel(t, item);\n const Icon = item.icon;\n\n return (\n <li>\n <NavLink\n to={to}\n end={item.id === \"admin-overview\"}\n onClick={onNavigate}\n className={({ isActive }) =>\n cn(\n \"flex min-h-8 items-center gap-2 rounded-md px-2 text-sm transition-colors\",\n isActive\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-muted-foreground hover:bg-accent/60 hover:text-foreground\",\n )\n }\n >\n {Icon ? <Icon size={15} className=\"shrink-0\" /> : null}\n <span className=\"truncate\">{label}</span>\n </NavLink>\n </li>\n );\n}\n\nexport function AdminShell({\n children,\n onNavigate,\n}: {\n children: ReactNode;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const groups = useAdminNavGroups();\n\n return (\n <div\n className=\"grid min-w-0 gap-6 lg:grid-cols-[13rem_minmax(0,1fr)]\"\n data-dispatch-admin-shell\n >\n <aside className=\"min-w-0 border-b pb-5 lg:sticky lg:top-2 lg:self-start lg:border-b-0 lg:border-e lg:pe-6\">\n <div className=\"px-2\">\n <div className=\"text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n {t(\"dispatch.nav.admin\", { defaultValue: \"Admin\" })}\n </div>\n <p className=\"mt-1 text-xs leading-5 text-muted-foreground\">\n {t(\"dispatch.pages.adminDescription\", {\n defaultValue: \"Workspace controls and operations\",\n })}\n </p>\n </div>\n\n <nav\n aria-label={t(\"dispatch.pages.adminNavigation\", {\n defaultValue: \"Admin navigation\",\n })}\n className=\"mt-5 space-y-5\"\n >\n {groups.map((group) => (\n <section key={group.id}>\n <h2 className=\"px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground/70\">\n {t(group.labelKey, { defaultValue: group.label })}\n </h2>\n <ul className=\"mt-1 space-y-0.5\">\n {group.items.map((item) => (\n <AdminNavLink\n key={item.id}\n item={item}\n onNavigate={onNavigate}\n />\n ))}\n </ul>\n </section>\n ))}\n </nav>\n </aside>\n\n <section className=\"min-w-0\" data-dispatch-admin-content>\n {children}\n </section>\n </div>\n );\n}\n\nexport { BUILT_IN_ADMIN_NAV_GROUPS };\n\nexport function useAdminNavGroups(): readonly AdminNavGroup[] {\n const extensions = useDispatchExtensions();\n const extensionItems = (extensions?.navItems ?? []).filter(\n (item) => item.section === \"operations\",\n );\n\n return extensionItems.length\n ? [\n ...BUILT_IN_ADMIN_NAV_GROUPS,\n {\n id: \"workspace-extensions\",\n label: \"Workspace extensions\",\n labelKey: \"dispatch.pages.adminWorkspaceExtensions\",\n items: extensionItems,\n },\n ]\n : BUILT_IN_ADMIN_NAV_GROUPS;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function AppIcon({ id, name, icon, color, className, size, }: {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
color?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
size?: "sm" | "md";
|
|
8
|
+
}): import("node_modules/@types/react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=app-icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-icon.d.ts","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"AA0FA,wBAAgB,OAAO,CAAC,EACtB,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,SAAS,EACT,IAAW,GACZ,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB,mDAgCA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { IconActivity, IconApps, IconBrain, IconBrush, IconCalendar, IconChartBar, IconClipboardList, IconFileText, IconMail, IconPhoto, IconPlugConnected, IconPresentation, IconPuzzle, IconScreenShare, } from "@tabler/icons-react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
const FALLBACK_ICONS = [
|
|
5
|
+
IconApps,
|
|
6
|
+
IconPuzzle,
|
|
7
|
+
IconActivity,
|
|
8
|
+
IconPlugConnected,
|
|
9
|
+
];
|
|
10
|
+
const APP_ICON_TONES = [
|
|
11
|
+
"bg-primary/10 text-primary",
|
|
12
|
+
"bg-secondary text-secondary-foreground",
|
|
13
|
+
"bg-accent text-accent-foreground",
|
|
14
|
+
"bg-muted text-foreground",
|
|
15
|
+
];
|
|
16
|
+
const ICONS_BY_KEY = {
|
|
17
|
+
barchart2: IconChartBar,
|
|
18
|
+
brain: IconBrain,
|
|
19
|
+
brush: IconBrush,
|
|
20
|
+
calendardays: IconCalendar,
|
|
21
|
+
chartbar: IconChartBar,
|
|
22
|
+
clipboardlist: IconClipboardList,
|
|
23
|
+
filetext: IconFileText,
|
|
24
|
+
galleryhorizontal: IconPresentation,
|
|
25
|
+
mail: IconMail,
|
|
26
|
+
photo: IconPhoto,
|
|
27
|
+
presentation: IconPresentation,
|
|
28
|
+
screenshare: IconScreenShare,
|
|
29
|
+
};
|
|
30
|
+
function appIconComponent(id, name, iconKey) {
|
|
31
|
+
const normalizedIconKey = iconKey?.trim().toLowerCase();
|
|
32
|
+
if (normalizedIconKey && ICONS_BY_KEY[normalizedIconKey]) {
|
|
33
|
+
return ICONS_BY_KEY[normalizedIconKey];
|
|
34
|
+
}
|
|
35
|
+
const haystack = `${id} ${name}`.toLowerCase();
|
|
36
|
+
if (haystack.includes("mail") || haystack.includes("email")) {
|
|
37
|
+
return IconMail;
|
|
38
|
+
}
|
|
39
|
+
if (haystack.includes("analytics") ||
|
|
40
|
+
haystack.includes("metric") ||
|
|
41
|
+
haystack.includes("indicator") ||
|
|
42
|
+
haystack.includes("gtm")) {
|
|
43
|
+
return IconChartBar;
|
|
44
|
+
}
|
|
45
|
+
if (haystack.includes("coach") || haystack.includes("agent")) {
|
|
46
|
+
return IconBrain;
|
|
47
|
+
}
|
|
48
|
+
let hash = 0;
|
|
49
|
+
for (const character of `${id}:${name}`) {
|
|
50
|
+
hash = (hash * 31 + character.charCodeAt(0)) | 0;
|
|
51
|
+
}
|
|
52
|
+
return FALLBACK_ICONS[Math.abs(hash) % FALLBACK_ICONS.length] ?? IconApps;
|
|
53
|
+
}
|
|
54
|
+
function safeHexColor(color) {
|
|
55
|
+
const normalized = color?.trim();
|
|
56
|
+
return normalized && /^#[0-9a-f]{6}$/i.test(normalized) ? normalized : null;
|
|
57
|
+
}
|
|
58
|
+
export function AppIcon({ id, name, icon, color, className, size = "md", }) {
|
|
59
|
+
const Icon = appIconComponent(id, name, icon);
|
|
60
|
+
const customColor = safeHexColor(color);
|
|
61
|
+
const tone = APP_ICON_TONES[Math.abs(hashForApp(id, name)) % APP_ICON_TONES.length];
|
|
62
|
+
const style = customColor
|
|
63
|
+
? {
|
|
64
|
+
"--dispatch-app-icon-color": customColor,
|
|
65
|
+
backgroundColor: "color-mix(in srgb, var(--dispatch-app-icon-color) 14%, transparent)",
|
|
66
|
+
color: "var(--dispatch-app-icon-color)",
|
|
67
|
+
}
|
|
68
|
+
: {
|
|
69
|
+
"--dispatch-app-icon-hue": `${appHue(id, name)} 72% 44%`,
|
|
70
|
+
backgroundColor: "hsl(var(--dispatch-app-icon-hue) / 0.14)",
|
|
71
|
+
color: "hsl(var(--dispatch-app-icon-hue))",
|
|
72
|
+
};
|
|
73
|
+
return (_jsx("span", { "aria-hidden": "true", className: cn("flex shrink-0 items-center justify-center rounded-xl", size === "sm" ? "size-8" : "size-10", !customColor && tone, className), style: style, children: _jsx(Icon, { size: size === "sm" ? 16 : 19, stroke: 1.8 }) }));
|
|
74
|
+
}
|
|
75
|
+
function hashForApp(id, name) {
|
|
76
|
+
let hash = 0;
|
|
77
|
+
for (const character of `${id}:${name}`) {
|
|
78
|
+
hash = (hash * 31 + character.charCodeAt(0)) | 0;
|
|
79
|
+
}
|
|
80
|
+
return hash;
|
|
81
|
+
}
|
|
82
|
+
function appHue(id, name) {
|
|
83
|
+
return 20 + (Math.abs(hashForApp(id, name)) % 320);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=app-icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-icon.js","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconActivity,\n IconApps,\n IconBrain,\n IconBrush,\n IconCalendar,\n IconChartBar,\n IconClipboardList,\n IconFileText,\n IconMail,\n IconPhoto,\n IconPlugConnected,\n IconPresentation,\n IconPuzzle,\n IconScreenShare,\n} from \"@tabler/icons-react\";\nimport type { CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\ntype AppIconComponent = typeof IconApps;\n\nconst FALLBACK_ICONS: AppIconComponent[] = [\n IconApps,\n IconPuzzle,\n IconActivity,\n IconPlugConnected,\n];\n\nconst APP_ICON_TONES = [\n \"bg-primary/10 text-primary\",\n \"bg-secondary text-secondary-foreground\",\n \"bg-accent text-accent-foreground\",\n \"bg-muted text-foreground\",\n] as const;\n\nconst ICONS_BY_KEY: Record<string, AppIconComponent> = {\n barchart2: IconChartBar,\n brain: IconBrain,\n brush: IconBrush,\n calendardays: IconCalendar,\n chartbar: IconChartBar,\n clipboardlist: IconClipboardList,\n filetext: IconFileText,\n galleryhorizontal: IconPresentation,\n mail: IconMail,\n photo: IconPhoto,\n presentation: IconPresentation,\n screenshare: IconScreenShare,\n};\n\nfunction appIconComponent(\n id: string,\n name: string,\n iconKey?: string,\n): AppIconComponent {\n const normalizedIconKey = iconKey?.trim().toLowerCase();\n if (normalizedIconKey && ICONS_BY_KEY[normalizedIconKey]) {\n return ICONS_BY_KEY[normalizedIconKey];\n }\n\n const haystack = `${id} ${name}`.toLowerCase();\n\n if (haystack.includes(\"mail\") || haystack.includes(\"email\")) {\n return IconMail;\n }\n if (\n haystack.includes(\"analytics\") ||\n haystack.includes(\"metric\") ||\n haystack.includes(\"indicator\") ||\n haystack.includes(\"gtm\")\n ) {\n return IconChartBar;\n }\n if (haystack.includes(\"coach\") || haystack.includes(\"agent\")) {\n return IconBrain;\n }\n\n let hash = 0;\n for (const character of `${id}:${name}`) {\n hash = (hash * 31 + character.charCodeAt(0)) | 0;\n }\n return FALLBACK_ICONS[Math.abs(hash) % FALLBACK_ICONS.length] ?? IconApps;\n}\n\nfunction safeHexColor(color: string | undefined): string | null {\n const normalized = color?.trim();\n return normalized && /^#[0-9a-f]{6}$/i.test(normalized) ? normalized : null;\n}\n\nexport function AppIcon({\n id,\n name,\n icon,\n color,\n className,\n size = \"md\",\n}: {\n id: string;\n name: string;\n icon?: string;\n color?: string;\n className?: string;\n size?: \"sm\" | \"md\";\n}) {\n const Icon = appIconComponent(id, name, icon);\n const customColor = safeHexColor(color);\n const tone =\n APP_ICON_TONES[Math.abs(hashForApp(id, name)) % APP_ICON_TONES.length];\n const style = customColor\n ? ({\n \"--dispatch-app-icon-color\": customColor,\n backgroundColor:\n \"color-mix(in srgb, var(--dispatch-app-icon-color) 14%, transparent)\",\n color: \"var(--dispatch-app-icon-color)\",\n } as CSSProperties)\n : ({\n \"--dispatch-app-icon-hue\": `${appHue(id, name)} 72% 44%`,\n backgroundColor: \"hsl(var(--dispatch-app-icon-hue) / 0.14)\",\n color: \"hsl(var(--dispatch-app-icon-hue))\",\n } as CSSProperties);\n\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"flex shrink-0 items-center justify-center rounded-xl\",\n size === \"sm\" ? \"size-8\" : \"size-10\",\n !customColor && tone,\n className,\n )}\n style={style}\n >\n <Icon size={size === \"sm\" ? 16 : 19} stroke={1.8} />\n </span>\n );\n}\n\nfunction hashForApp(id: string, name: string): number {\n let hash = 0;\n for (const character of `${id}:${name}`) {\n hash = (hash * 31 + character.charCodeAt(0)) | 0;\n }\n return hash;\n}\n\nfunction appHue(id: string, name: string): number {\n return 20 + (Math.abs(hashForApp(id, name)) % 320);\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export declare const APP_LIST_GRID_CLASS = "xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent";
|
|
3
|
+
export declare const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border-0 xl:bg-card";
|
|
4
|
+
export declare function AppList({ children, className, }: {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
}): import("node_modules/@types/react").JSX.Element;
|
|
8
|
+
export declare function AppListRow({ children, className, }: {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
}): import("node_modules/@types/react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=app-list-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-list-row.d.ts","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,mBAAmB,0FACyD,CAAC;AAC1F,eAAO,MAAM,uBAAuB,0CAA0C,CAAC;AAE/E,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAMA;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAWA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
export const APP_LIST_GRID_CLASS = "xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent";
|
|
4
|
+
export const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border-0 xl:bg-card";
|
|
5
|
+
export function AppList({ children, className, }) {
|
|
6
|
+
return (_jsx("div", { className: cn("overflow-hidden rounded-2xl bg-card", className), children: children }));
|
|
7
|
+
}
|
|
8
|
+
export function AppListRow({ children, className, }) {
|
|
9
|
+
return (_jsx("div", { className: cn("group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color] hover:bg-muted/30 focus-within:bg-muted/30", className), children: children }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=app-list-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-list-row.js","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAC9B,uFAAuF,CAAC;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG,uCAAuC,CAAC;AAE/E,MAAM,UAAU,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YACjE,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,qJAAqJ,EACrJ,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nexport const APP_LIST_GRID_CLASS =\n \"xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent\";\nexport const APP_LIST_GRID_ROW_CLASS = \"xl:rounded-2xl xl:border-0 xl:bg-card\";\n\nexport function AppList({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"overflow-hidden rounded-2xl bg-card\", className)}>\n {children}\n </div>\n );\n}\n\nexport function AppListRow({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n \"group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color] hover:bg-muted/30 focus-within:bg-muted/30\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface AppOpenActionLabels {
|
|
2
|
+
addApp: string;
|
|
3
|
+
openApp: string;
|
|
4
|
+
openInline: string;
|
|
5
|
+
openInNewTab: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function AppOpenActions({ name, href, target, rel, labels: labelOverrides, onAddApp, showInlineOption, showNewTabOption, }: {
|
|
8
|
+
name: string;
|
|
9
|
+
href: string | null;
|
|
10
|
+
target?: "_blank";
|
|
11
|
+
rel?: string;
|
|
12
|
+
labels?: Partial<AppOpenActionLabels>;
|
|
13
|
+
onAddApp?: () => void;
|
|
14
|
+
showInlineOption?: boolean;
|
|
15
|
+
showNewTabOption?: boolean;
|
|
16
|
+
}): import("node_modules/@types/react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=app-open-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-open-actions.d.ts","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AASD,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,GAAG,EACH,MAAM,EAAE,cAAc,EACtB,QAAQ,EACR,gBAAwB,EACxB,gBAAwB,GACzB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,mDAoEA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconChevronDown, IconPlus } from "@tabler/icons-react";
|
|
3
|
+
import { Button } from "./ui/button.js";
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "./ui/dropdown-menu.js";
|
|
5
|
+
const DEFAULT_LABELS = {
|
|
6
|
+
addApp: "Add app",
|
|
7
|
+
openApp: "Open app",
|
|
8
|
+
openInline: "Open inline",
|
|
9
|
+
openInNewTab: "Open in new tab",
|
|
10
|
+
};
|
|
11
|
+
export function AppOpenActions({ name, href, target, rel, labels: labelOverrides, onAddApp, showInlineOption = false, showNewTabOption = false, }) {
|
|
12
|
+
const labels = { ...DEFAULT_LABELS, ...labelOverrides };
|
|
13
|
+
const hasMenu = Boolean(onAddApp) ||
|
|
14
|
+
(Boolean(href) && (showInlineOption || showNewTabOption));
|
|
15
|
+
if (!href && !hasMenu) {
|
|
16
|
+
return (_jsx(Button, { size: "sm", variant: "outline", disabled: true, children: labels.openApp }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsxs("div", { className: "flex shrink-0 overflow-hidden rounded-md border border-border focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2", children: [_jsx(Button, { asChild: Boolean(href), size: "sm", variant: "outline", className: "rounded-none border-0 border-e border-border", disabled: !href, children: href ? (_jsx("a", { href: href, target: target, rel: rel, children: labels.openApp })) : (_jsx("span", { children: labels.openApp })) }), hasMenu ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "size-9 rounded-none border-0 p-0", "aria-label": `Open options for ${name}`, children: _jsx(IconChevronDown, { size: 15 }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-40", children: [onAddApp ? (_jsxs(DropdownMenuItem, { onSelect: onAddApp, children: [_jsx(IconPlus, { size: 14, className: "mr-2" }), labels.addApp] })) : null, showInlineOption && href ? (_jsx(DropdownMenuItem, { asChild: true, children: _jsx("a", { href: href, children: labels.openInline }) })) : null, showNewTabOption && href ? (_jsx(DropdownMenuItem, { asChild: true, children: _jsx("a", { href: href, target: "_blank", rel: "noreferrer", children: labels.openInNewTab }) })) : null] })] })) : null] }));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=app-open-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-open-actions.js","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconChevronDown, IconPlus } from \"@tabler/icons-react\";\n\nimport { Button } from \"./ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\n\nexport interface AppOpenActionLabels {\n addApp: string;\n openApp: string;\n openInline: string;\n openInNewTab: string;\n}\n\nconst DEFAULT_LABELS: AppOpenActionLabels = {\n addApp: \"Add app\",\n openApp: \"Open app\",\n openInline: \"Open inline\",\n openInNewTab: \"Open in new tab\",\n};\n\nexport function AppOpenActions({\n name,\n href,\n target,\n rel,\n labels: labelOverrides,\n onAddApp,\n showInlineOption = false,\n showNewTabOption = false,\n}: {\n name: string;\n href: string | null;\n target?: \"_blank\";\n rel?: string;\n labels?: Partial<AppOpenActionLabels>;\n onAddApp?: () => void;\n showInlineOption?: boolean;\n showNewTabOption?: boolean;\n}) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides };\n const hasMenu =\n Boolean(onAddApp) ||\n (Boolean(href) && (showInlineOption || showNewTabOption));\n\n if (!href && !hasMenu) {\n return (\n <Button size=\"sm\" variant=\"outline\" disabled>\n {labels.openApp}\n </Button>\n );\n }\n\n return (\n <div className=\"flex shrink-0 overflow-hidden rounded-md border border-border focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2\">\n <Button\n asChild={Boolean(href)}\n size=\"sm\"\n variant=\"outline\"\n className=\"rounded-none border-0 border-e border-border\"\n disabled={!href}\n >\n {href ? (\n <a href={href} target={target} rel={rel}>\n {labels.openApp}\n </a>\n ) : (\n <span>{labels.openApp}</span>\n )}\n </Button>\n {hasMenu ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"size-9 rounded-none border-0 p-0\"\n aria-label={`Open options for ${name}`}\n >\n <IconChevronDown size={15} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-40\">\n {onAddApp ? (\n <DropdownMenuItem onSelect={onAddApp}>\n <IconPlus size={14} className=\"mr-2\" />\n {labels.addApp}\n </DropdownMenuItem>\n ) : null}\n {showInlineOption && href ? (\n <DropdownMenuItem asChild>\n <a href={href}>{labels.openInline}</a>\n </DropdownMenuItem>\n ) : null}\n {showNewTabOption && href ? (\n <DropdownMenuItem asChild>\n <a href={href} target=\"_blank\" rel=\"noreferrer\">\n {labels.openInNewTab}\n </a>\n </DropdownMenuItem>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ConnectedAppSummary } from "../lib/other-apps.js";
|
|
2
|
-
export declare function ConnectedAppCard({ app }: {
|
|
2
|
+
export declare function ConnectedAppCard({ app, className, }: {
|
|
3
3
|
app: ConnectedAppSummary;
|
|
4
|
+
className?: string;
|
|
4
5
|
}): import("node_modules/@types/react").JSX.Element;
|
|
5
6
|
//# sourceMappingURL=connected-app-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAK7D,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAwBA"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useT } from "@agent-native/core/client/i18n";
|
|
3
2
|
import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import { AppIcon } from "./app-icon.js";
|
|
4
|
+
import { AppListRow } from "./app-list-row.js";
|
|
5
|
+
import { AppOpenActions } from "./app-open-actions.js";
|
|
6
|
+
export function ConnectedAppCard({ app, className, }) {
|
|
7
|
+
return (_jsxs(AppListRow, { className: className, children: [_jsx(AppIcon, { id: app.id, name: app.name, color: app.color, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), _jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || app.url })] }), _jsx(AppOpenActions, { name: app.name, href: withBuilderUtmTrackingParams(app.url, {
|
|
8
|
+
campaign: "product",
|
|
9
|
+
content: "dispatch_app",
|
|
10
|
+
}), target: "_blank", rel: "noopener noreferrer", showNewTabOption: true })] }));
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=connected-app-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAG/F,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GAIV;IACC,OAAO,CACL,MAAC,UAAU,IAAC,SAAS,EAAE,SAAS,aAC9B,KAAC,OAAO,IAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,GAAG,EACnE,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,gDAAgD,YAC5D,GAAG,CAAC,IAAI,GACL,EACN,cAAK,SAAS,EAAC,+CAA+C,YAC3D,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,GACvB,IACF,EACN,KAAC,cAAc,IACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,IAAI,EAAE,4BAA4B,CAAC,GAAG,CAAC,GAAG,EAAE;oBAC1C,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,cAAc;iBACxB,CAAC,EACF,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,gBAAgB,SAChB,IACS,CACd,CAAC;AACJ,CAAC","sourcesContent":["import { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppListRow } from \"./app-list-row\";\nimport { AppOpenActions } from \"./app-open-actions\";\n\nexport function ConnectedAppCard({\n app,\n className,\n}: {\n app: ConnectedAppSummary;\n className?: string;\n}) {\n return (\n <AppListRow className={className}>\n <AppIcon id={app.id} name={app.name} color={app.color} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {app.description || app.url}\n </div>\n </div>\n <AppOpenActions\n name={app.name}\n href={withBuilderUtmTrackingParams(app.url, {\n campaign: \"product\",\n content: \"dispatch_app\",\n })}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n showNewTabOption\n />\n </AppListRow>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-control-plane.d.ts","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-control-plane.d.ts","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":"AA4UA,wBAAgB,oBAAoB,oDAwCnC"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { navigateWithAgentChatViewTransition, useChatModels, } from "@agent-native/core/client/agent-chat";
|
|
3
3
|
import { PromptComposer } from "@agent-native/core/client/composer";
|
|
4
4
|
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
5
5
|
import { isInBuilderFrame } from "@agent-native/core/client/host";
|
|
6
6
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
-
import { IconArrowUpRight, IconChevronDown, IconClockHour4, } from "@tabler/icons-react";
|
|
7
|
+
import { IconArrowUpRight, IconChevronDown, IconClockHour4, IconApps, } from "@tabler/icons-react";
|
|
8
8
|
import { useState } from "react";
|
|
9
9
|
import { Link, useNavigate } from "react-router";
|
|
10
|
-
import { filterOtherApps } from "../lib/other-apps.js";
|
|
11
10
|
import { submitOverviewPrompt } from "../lib/overview-chat.js";
|
|
11
|
+
import { cn } from "../lib/utils.js";
|
|
12
12
|
import { ActionQueryError } from "./action-query-error.js";
|
|
13
|
-
import {
|
|
13
|
+
import { APP_LIST_GRID_CLASS, AppList, APP_LIST_GRID_ROW_CLASS, } from "./app-list-row.js";
|
|
14
14
|
import { CreateAppPopover } from "./create-app-popover.js";
|
|
15
15
|
import { useSetPageTitle } from "./layout/HeaderActions.js";
|
|
16
|
+
import { OtherAppsSection } from "./other-apps-section.js";
|
|
16
17
|
import { Button } from "./ui/button.js";
|
|
17
18
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "./ui/collapsible.js";
|
|
18
19
|
import { Skeleton } from "./ui/skeleton.js";
|
|
@@ -20,6 +21,9 @@ import { WorkspaceAppCard } from "./workspace-app-card.js";
|
|
|
20
21
|
function SectionHeader({ title, action, }) {
|
|
21
22
|
return (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3", children: [_jsx("h2", { className: "truncate text-sm font-semibold text-foreground", children: title }), action ? _jsx("div", { className: "shrink-0", children: action }) : null] }));
|
|
22
23
|
}
|
|
24
|
+
function AppGroupHeader({ title, description, }) {
|
|
25
|
+
return (_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [_jsx(IconApps, { size: 16, className: "mt-0.5 shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: title }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description })] })] }));
|
|
26
|
+
}
|
|
23
27
|
function CommandPanel() {
|
|
24
28
|
const t = useT();
|
|
25
29
|
const { availableModels, isLoading: modelListLoading, onEffortChange, onModelChange, selectedEffort, selectedEngine, selectedModel, } = useChatModels({ storageKey: "dispatch" });
|
|
@@ -63,29 +67,32 @@ function CommandPanel() {
|
|
|
63
67
|
defaultValue: "Ask Dispatch anything...",
|
|
64
68
|
}), selectedEffort: selectedEffort, selectedEngine: selectedEngine, selectedModel: selectedModel, onEffortChange: onEffortChange, onModelChange: onModelChange, onSubmit: (text) => send(text) }), _jsx("div", { className: "mt-3 flex flex-wrap justify-center gap-2", children: promptSuggestions.map((suggestion) => (_jsx("button", { type: "button", onClick: () => send(suggestion), className: "cursor-pointer rounded-md border border-transparent bg-muted/60 px-2.5 py-1.5 text-xs text-muted-foreground transition-[background-color,color] hover:bg-muted hover:text-foreground", children: suggestion }, suggestion))) })] }) }));
|
|
65
69
|
}
|
|
66
|
-
function AppsPanel({ apps, isLoading,
|
|
70
|
+
function AppsPanel({ apps, isLoading, connectedApps, connectedAppsError, connectedAppsLoading, onRetryConnectedApps, curatedTemplates, curatedTemplatesError, curatedTemplatesLoading, onRetryCuratedTemplates, }) {
|
|
67
71
|
const t = useT();
|
|
68
72
|
const [showPending, setShowPending] = useState(false);
|
|
69
73
|
const visibleApps = apps.filter((app) => !app.isDispatch && !app.archived);
|
|
70
74
|
const activeApps = visibleApps.filter((app) => app.status !== "pending");
|
|
71
75
|
const pendingApps = visibleApps.filter((app) => app.status === "pending");
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
const showSkeletons = isLoading && activeApps.length === 0 && pendingApps.length === 0;
|
|
77
|
+
return (_jsxs("section", { className: "flex flex-col gap-3", children: [_jsx(SectionHeader, { title: "Apps", action: _jsx(Button, { variant: "outline", size: "sm", asChild: true, children: _jsxs(Link, { to: "/apps", children: ["View all", _jsx(IconArrowUpRight, { size: 14 })] }) }) }), showSkeletons ? (_jsx(OverviewAppsSkeleton, {})) : (_jsxs(_Fragment, { children: [activeApps.length > 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx(AppGroupHeader, { title: t("dispatch.pages.yourApps", {
|
|
78
|
+
defaultValue: "Your apps",
|
|
79
|
+
}), description: t("dispatch.pages.activeCount", {
|
|
80
|
+
count: activeApps.length,
|
|
81
|
+
}) }), _jsx(AppList, { className: APP_LIST_GRID_CLASS, children: activeApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: APP_LIST_GRID_ROW_CLASS }, app.id))) })] })) : (_jsx(CreateAppPopover, {})), _jsx(OtherAppsSection, { templates: curatedTemplates, connectedApps: connectedApps, workspaceApps: apps, templatesLoading: curatedTemplatesLoading, connectedAppsLoading: connectedAppsLoading, templatesError: curatedTemplatesError, connectedAppsError: connectedAppsError, onRetryTemplates: onRetryCuratedTemplates, onRetryConnectedApps: onRetryConnectedApps })] })), pendingApps.length > 0 ? (_jsx(Collapsible, { open: showPending, onOpenChange: setShowPending, children: _jsxs("div", { className: "space-y-3 border-t pt-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconClockHour4, { size: 15, className: "shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "text-xs font-semibold text-foreground", children: t("dispatch.pages.pendingApps") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.pendingAppsDescription", {
|
|
78
82
|
count: pendingApps.length,
|
|
79
83
|
}) })] })] }), _jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 gap-1.5 px-2 text-xs", children: [showPending
|
|
80
84
|
? t("dispatch.pages.hidePendingApps")
|
|
81
|
-
: t("dispatch.pages.showPendingApps"), _jsx(IconChevronDown, { size: 13, className: showPending ? "rotate-180" : undefined })] }) })] }), _jsx(CollapsibleContent, { children: _jsx(
|
|
85
|
+
: t("dispatch.pages.showPendingApps"), _jsx(IconChevronDown, { size: 13, className: showPending ? "rotate-180" : undefined })] }) })] }), _jsx(CollapsibleContent, { children: _jsx(AppList, { className: APP_LIST_GRID_CLASS, children: pendingApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: APP_LIST_GRID_ROW_CLASS }, app.id))) }) })] }) })) : null] }));
|
|
86
|
+
}
|
|
87
|
+
function OverviewAppsSkeleton() {
|
|
88
|
+
return (_jsx(AppList, { className: APP_LIST_GRID_CLASS, children: Array.from({ length: 4 }).map((_, index) => (_jsxs("div", { className: cn("flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0", APP_LIST_GRID_ROW_CLASS), children: [_jsx(Skeleton, { className: "size-8 shrink-0 rounded-xl" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-32" }), _jsx(Skeleton, { className: "h-3 w-2/3" })] }), _jsx(Skeleton, { className: "h-9 w-24 shrink-0 rounded-md" })] }, index))) }));
|
|
82
89
|
}
|
|
83
90
|
export function DispatchControlPlane() {
|
|
84
91
|
useSetPageTitle(_jsx("span", { "aria-hidden": true }));
|
|
85
92
|
const appsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false, includeArchived: true });
|
|
86
93
|
const connectedAppsQuery = useActionQuery("list-connected-agents", {});
|
|
94
|
+
const curatedTemplatesQuery = useActionQuery("list-curated-workspace-templates", {});
|
|
87
95
|
const { data: workspaceApps = [], isLoading: appsLoading } = appsQuery;
|
|
88
|
-
|
|
89
|
-
return (_jsxs("div", { className: "flex flex-col gap-8", children: [_jsx(CommandPanel, {}), appsQuery.isError ? (_jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() })) : (_jsx(AppsPanel, { apps: workspaceApps ?? [], isLoading: appsLoading, otherApps: otherApps, otherAppsError: connectedAppsQuery.error, otherAppsLoading: connectedAppsQuery.isLoading, onRetryOtherApps: () => void connectedAppsQuery.refetch() }))] }));
|
|
96
|
+
return (_jsxs("div", { className: "flex flex-col gap-8", children: [_jsx(CommandPanel, {}), appsQuery.isError ? (_jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() })) : (_jsx(AppsPanel, { apps: workspaceApps ?? [], isLoading: appsLoading, connectedApps: connectedAppsQuery.data ?? [], connectedAppsError: connectedAppsQuery.error, connectedAppsLoading: connectedAppsQuery.isLoading, onRetryConnectedApps: () => void connectedAppsQuery.refetch(), curatedTemplates: curatedTemplatesQuery.data, curatedTemplatesError: curatedTemplatesQuery.error, curatedTemplatesLoading: curatedTemplatesQuery.isLoading, onRetryCuratedTemplates: () => void curatedTemplatesQuery.refetch() }))] }));
|
|
90
97
|
}
|
|
91
98
|
//# sourceMappingURL=dispatch-control-plane.js.map
|