@agent-native/dispatch 0.23.0 → 0.23.2
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 +4 -4
- package/dist/components/app-icon.d.ts.map +1 -1
- package/dist/components/app-icon.js +50 -30
- package/dist/components/app-icon.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +60 -17
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/routes/pages/chat.js +1 -1
- package/dist/routes/pages/chat.js.map +1 -1
- package/dist/server/lib/dispatch-integrations.js +2 -2
- package/dist/server/lib/dispatch-integrations.js.map +1 -1
- package/dist/server/lib/mcp-gateway.d.ts.map +1 -1
- package/dist/server/lib/mcp-gateway.js +14 -1
- package/dist/server/lib/mcp-gateway.js.map +1 -1
- package/package.json +3 -3
- package/src/components/app-icon.tsx +68 -44
- package/src/components/dispatch-control-plane.spec.tsx +2 -0
- package/src/components/layout/Layout.spec.tsx +8 -1
- package/src/components/layout/Layout.tsx +82 -19
- package/src/routes/pages/chat.tsx +1 -1
- package/src/server/lib/dispatch-integrations.ts +2 -2
- package/src/server/lib/mcp-gateway.spec.ts +64 -2
- package/src/server/lib/mcp-gateway.ts +19 -1
- package/src/styles/dispatch-css.spec.ts +11 -0
- package/src/styles/dispatch.css +1 -1
|
@@ -48,8 +48,8 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
50
|
id?: undefined;
|
|
51
|
-
provider?: undefined;
|
|
52
51
|
deleted?: undefined;
|
|
52
|
+
provider?: undefined;
|
|
53
53
|
providers: {
|
|
54
54
|
id: string;
|
|
55
55
|
label: string;
|
|
@@ -65,9 +65,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
65
65
|
label?: undefined;
|
|
66
66
|
message?: undefined;
|
|
67
67
|
} | {
|
|
68
|
-
count?: undefined;
|
|
69
68
|
id?: undefined;
|
|
70
69
|
deleted?: undefined;
|
|
70
|
+
count?: undefined;
|
|
71
71
|
providers?: undefined;
|
|
72
72
|
found: boolean;
|
|
73
73
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
@@ -75,9 +75,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
75
75
|
label?: undefined;
|
|
76
76
|
message?: undefined;
|
|
77
77
|
} | {
|
|
78
|
+
deleted?: undefined;
|
|
78
79
|
count?: undefined;
|
|
79
80
|
provider?: undefined;
|
|
80
|
-
deleted?: undefined;
|
|
81
81
|
providers?: undefined;
|
|
82
82
|
found: boolean;
|
|
83
83
|
id: string;
|
|
@@ -95,9 +95,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
95
95
|
label?: undefined;
|
|
96
96
|
message?: undefined;
|
|
97
97
|
} | {
|
|
98
|
+
deleted?: undefined;
|
|
98
99
|
count?: undefined;
|
|
99
100
|
provider?: undefined;
|
|
100
|
-
deleted?: undefined;
|
|
101
101
|
providers?: undefined;
|
|
102
102
|
found?: undefined;
|
|
103
103
|
registered: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-icon.d.ts","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-icon.d.ts","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"AA+GA,wBAAgB,OAAO,CAAC,EACtB,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,SAAS,EACT,IAAW,EACX,UAAkB,GACnB,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;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,mDAqCA"}
|
|
@@ -1,37 +1,57 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { IconBrain, IconBrandChrome, IconBrandJira, IconCalendar, IconChartBar, IconCode, IconFileText, IconFolder, IconLayoutBoard, IconListCheck, IconMail, IconMessageCircle, IconPhoto, IconPresentation, IconRoute, IconSettings, IconStack2, IconUsers, } from "@tabler/icons-react";
|
|
3
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
4
|
const ICONS_BY_KEY = {
|
|
17
5
|
barchart2: IconChartBar,
|
|
6
|
+
brandjira: IconBrandJira,
|
|
18
7
|
brain: IconBrain,
|
|
19
|
-
brush: IconBrush,
|
|
20
8
|
calendardays: IconCalendar,
|
|
9
|
+
calendarmonth: IconCalendar,
|
|
21
10
|
chartbar: IconChartBar,
|
|
22
|
-
|
|
11
|
+
code: IconCode,
|
|
23
12
|
filetext: IconFileText,
|
|
13
|
+
folder: IconFolder,
|
|
24
14
|
galleryhorizontal: IconPresentation,
|
|
15
|
+
globe: IconBrandChrome,
|
|
16
|
+
layoutboard: IconLayoutBoard,
|
|
17
|
+
listcheck: IconListCheck,
|
|
25
18
|
mail: IconMail,
|
|
19
|
+
messagecircle: IconMessageCircle,
|
|
26
20
|
photo: IconPhoto,
|
|
27
21
|
presentation: IconPresentation,
|
|
28
|
-
|
|
22
|
+
route: IconRoute,
|
|
23
|
+
settings: IconSettings,
|
|
24
|
+
stack2: IconStack2,
|
|
25
|
+
users: IconUsers,
|
|
26
|
+
};
|
|
27
|
+
/** Keep the Dispatch rail visually identical to the desktop app for first-party apps. */
|
|
28
|
+
const APP_VISUALS_BY_ID = {
|
|
29
|
+
analytics: { icon: IconChartBar, colorRgb: "245 158 11" },
|
|
30
|
+
assets: { icon: IconPhoto, colorRgb: "15 118 110" },
|
|
31
|
+
brain: { icon: IconBrain, colorRgb: "139 92 246" },
|
|
32
|
+
calendar: { icon: IconCalendar, colorRgb: "0 181 255" },
|
|
33
|
+
chat: { icon: IconMessageCircle, colorRgb: "24 24 27" },
|
|
34
|
+
clips: { icon: IconStack2, colorRgb: "14 165 233" },
|
|
35
|
+
content: { icon: IconFileText, colorRgb: "16 185 129" },
|
|
36
|
+
crm: { icon: IconUsers, colorRgb: "37 99 235" },
|
|
37
|
+
design: { icon: IconStack2, colorRgb: "244 114 182" },
|
|
38
|
+
dispatch: { icon: IconRoute, colorRgb: "20 184 166" },
|
|
39
|
+
factory: { icon: IconUsers, colorRgb: "124 58 237" },
|
|
40
|
+
forms: { icon: IconStack2, colorRgb: "6 182 212" },
|
|
41
|
+
macros: { icon: IconCode, colorRgb: "113 113 122" },
|
|
42
|
+
mail: { icon: IconMail, colorRgb: "59 130 246" },
|
|
43
|
+
plan: { icon: IconLayoutBoard, colorRgb: "82 82 91" },
|
|
44
|
+
slides: { icon: IconPresentation, colorRgb: "236 72 153" },
|
|
45
|
+
tasks: { icon: IconListCheck, colorRgb: "99 102 241" },
|
|
29
46
|
};
|
|
30
47
|
function appIconComponent(id, name, iconKey) {
|
|
31
48
|
const normalizedIconKey = iconKey?.trim().toLowerCase();
|
|
32
49
|
if (normalizedIconKey && ICONS_BY_KEY[normalizedIconKey]) {
|
|
33
50
|
return ICONS_BY_KEY[normalizedIconKey];
|
|
34
51
|
}
|
|
52
|
+
const standardVisuals = APP_VISUALS_BY_ID[id.trim().toLowerCase()];
|
|
53
|
+
if (standardVisuals)
|
|
54
|
+
return standardVisuals.icon;
|
|
35
55
|
const haystack = `${id} ${name}`.toLowerCase();
|
|
36
56
|
if (haystack.includes("mail") || haystack.includes("email")) {
|
|
37
57
|
return IconMail;
|
|
@@ -45,11 +65,7 @@ function appIconComponent(id, name, iconKey) {
|
|
|
45
65
|
if (haystack.includes("coach") || haystack.includes("agent")) {
|
|
46
66
|
return IconBrain;
|
|
47
67
|
}
|
|
48
|
-
|
|
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;
|
|
68
|
+
return IconStack2;
|
|
53
69
|
}
|
|
54
70
|
function safeHexColor(color) {
|
|
55
71
|
const normalized = color?.trim();
|
|
@@ -58,21 +74,25 @@ function safeHexColor(color) {
|
|
|
58
74
|
export function AppIcon({ id, name, icon, color, className, size = "md", monochrome = false, }) {
|
|
59
75
|
const Icon = appIconComponent(id, name, icon);
|
|
60
76
|
const customColor = safeHexColor(color);
|
|
61
|
-
const
|
|
77
|
+
const standardColorRgb = APP_VISUALS_BY_ID[id.trim().toLowerCase()]?.colorRgb;
|
|
62
78
|
const style = customColor
|
|
63
79
|
? {
|
|
64
80
|
"--dispatch-app-icon-color": customColor,
|
|
65
81
|
backgroundColor: "color-mix(in srgb, var(--dispatch-app-icon-color) 14%, transparent)",
|
|
66
82
|
color: "var(--dispatch-app-icon-color)",
|
|
67
83
|
}
|
|
68
|
-
:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
: standardColorRgb
|
|
85
|
+
? {
|
|
86
|
+
"--dispatch-app-icon-color-rgb": standardColorRgb,
|
|
87
|
+
backgroundColor: "rgb(var(--dispatch-app-icon-color-rgb) / 0.14)",
|
|
88
|
+
color: "rgb(var(--dispatch-app-icon-color-rgb))",
|
|
89
|
+
}
|
|
90
|
+
: {
|
|
91
|
+
"--dispatch-app-icon-hue": `${appHue(id, name)} 72% 44%`,
|
|
92
|
+
backgroundColor: "hsl(var(--dispatch-app-icon-hue) / 0.14)",
|
|
93
|
+
color: "hsl(var(--dispatch-app-icon-hue))",
|
|
94
|
+
};
|
|
95
|
+
return (_jsx("span", { "aria-hidden": "true", className: cn("flex shrink-0 items-center justify-center rounded-lg", size === "sm" ? "size-7" : "size-10", monochrome && "bg-transparent text-sidebar-foreground/70", className), style: monochrome ? undefined : style, children: _jsx(Icon, { size: size === "sm" ? 15 : 19, strokeWidth: 1.8 }) }));
|
|
76
96
|
}
|
|
77
97
|
function hashForApp(id, name) {
|
|
78
98
|
let hash = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-icon.js","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"app-icon.js","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconBrain,\n IconBrandChrome,\n IconBrandJira,\n IconCalendar,\n IconChartBar,\n IconCode,\n IconFileText,\n IconFolder,\n IconLayoutBoard,\n IconListCheck,\n IconMail,\n IconMessageCircle,\n IconPhoto,\n IconPresentation,\n IconRoute,\n IconSettings,\n IconStack2,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport type { CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\ntype AppIconComponent = typeof IconStack2;\n\nconst ICONS_BY_KEY: Record<string, AppIconComponent> = {\n barchart2: IconChartBar,\n brandjira: IconBrandJira,\n brain: IconBrain,\n calendardays: IconCalendar,\n calendarmonth: IconCalendar,\n chartbar: IconChartBar,\n code: IconCode,\n filetext: IconFileText,\n folder: IconFolder,\n galleryhorizontal: IconPresentation,\n globe: IconBrandChrome,\n layoutboard: IconLayoutBoard,\n listcheck: IconListCheck,\n mail: IconMail,\n messagecircle: IconMessageCircle,\n photo: IconPhoto,\n presentation: IconPresentation,\n route: IconRoute,\n settings: IconSettings,\n stack2: IconStack2,\n users: IconUsers,\n};\n\n/** Keep the Dispatch rail visually identical to the desktop app for first-party apps. */\nconst APP_VISUALS_BY_ID: Record<\n string,\n { icon: AppIconComponent; colorRgb: string }\n> = {\n analytics: { icon: IconChartBar, colorRgb: \"245 158 11\" },\n assets: { icon: IconPhoto, colorRgb: \"15 118 110\" },\n brain: { icon: IconBrain, colorRgb: \"139 92 246\" },\n calendar: { icon: IconCalendar, colorRgb: \"0 181 255\" },\n chat: { icon: IconMessageCircle, colorRgb: \"24 24 27\" },\n clips: { icon: IconStack2, colorRgb: \"14 165 233\" },\n content: { icon: IconFileText, colorRgb: \"16 185 129\" },\n crm: { icon: IconUsers, colorRgb: \"37 99 235\" },\n design: { icon: IconStack2, colorRgb: \"244 114 182\" },\n dispatch: { icon: IconRoute, colorRgb: \"20 184 166\" },\n factory: { icon: IconUsers, colorRgb: \"124 58 237\" },\n forms: { icon: IconStack2, colorRgb: \"6 182 212\" },\n macros: { icon: IconCode, colorRgb: \"113 113 122\" },\n mail: { icon: IconMail, colorRgb: \"59 130 246\" },\n plan: { icon: IconLayoutBoard, colorRgb: \"82 82 91\" },\n slides: { icon: IconPresentation, colorRgb: \"236 72 153\" },\n tasks: { icon: IconListCheck, colorRgb: \"99 102 241\" },\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 standardVisuals = APP_VISUALS_BY_ID[id.trim().toLowerCase()];\n if (standardVisuals) return standardVisuals.icon;\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 return IconStack2;\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 monochrome = false,\n}: {\n id: string;\n name: string;\n icon?: string;\n color?: string;\n className?: string;\n size?: \"sm\" | \"md\";\n monochrome?: boolean;\n}) {\n const Icon = appIconComponent(id, name, icon);\n const customColor = safeHexColor(color);\n const standardColorRgb = APP_VISUALS_BY_ID[id.trim().toLowerCase()]?.colorRgb;\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 : standardColorRgb\n ? ({\n \"--dispatch-app-icon-color-rgb\": standardColorRgb,\n backgroundColor: \"rgb(var(--dispatch-app-icon-color-rgb) / 0.14)\",\n color: \"rgb(var(--dispatch-app-icon-color-rgb))\",\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-lg\",\n size === \"sm\" ? \"size-7\" : \"size-10\",\n monochrome && \"bg-transparent text-sidebar-foreground/70\",\n className,\n )}\n style={monochrome ? undefined : style}\n >\n <Icon size={size === \"sm\" ? 15 : 19} strokeWidth={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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAuBL,KAAK,4BAA4B,
|
|
1
|
+
{"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAuBL,KAAK,4BAA4B,EAYlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAaL,KAAK,gBAAgB,EAGtB,MAAM,sCAAsC,CAAC;AAgC9C,OAAO,EAQL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAuBf,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AA4DD,UAAU,0BAA0B;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;CACnB;AAYD,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,0BAA0B,CAE5B;AAkBD,wBAAgB,qBAAqB,IAAI,uBAAuB,GAAG,SAAS,CAE3E;AAuOD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,UAWlE;AA6YD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,UAAU,EACV,aAAqB,EACrB,iBAAyB,EACzB,SAAiB,EACjB,WAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,aAAkB,EAClB,oBAA4B,EAC5B,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,GACrB,EAAE;IACD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,4BAA4B,CAAC;IAClD,0BAA0B,CAAC,EAAE,CAAC,MAAM,EAAE,4BAA4B,KAAK,IAAI,CAAC;IAC5E,aAAa,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC5C,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrD,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,mDAwVA;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,mDAikCA"}
|
|
@@ -269,6 +269,9 @@ function persistedChatFirstPane(value) {
|
|
|
269
269
|
return null;
|
|
270
270
|
return {
|
|
271
271
|
appId: record.appId,
|
|
272
|
+
...(record.placement === "main" || record.placement === "side"
|
|
273
|
+
? { placement: record.placement }
|
|
274
|
+
: {}),
|
|
272
275
|
...(typeof record.path === "string" ? { path: record.path } : {}),
|
|
273
276
|
...(typeof record.view === "string" ? { view: record.view } : {}),
|
|
274
277
|
};
|
|
@@ -417,7 +420,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
|
|
|
417
420
|
if (threadId)
|
|
418
421
|
openThread(threadId, { isNew: true });
|
|
419
422
|
}
|
|
420
|
-
return (_jsxs("div", { className: cn("min-w-0 space-y-0.5", showNewChat && "dispatch-chat-first-chats"), children: [showNewChat && chatFirstNavigation ? (_jsx("nav", { className: "space-y-0.5 px-
|
|
423
|
+
return (_jsxs("div", { className: cn("min-w-0 space-y-0.5", showNewChat && "dispatch-chat-first-chats"), children: [showNewChat && chatFirstNavigation ? (_jsx("nav", { className: "space-y-0.5 px-0 py-2", children: _jsx(ChatFirstPrimaryNavigation, { copy: chatFirstCopy, onNewChat: () => void handleNewChat(), onOpenIntegrations: chatFirstNavigation.onOpenIntegrations, onOpenScheduled: chatFirstNavigation.onOpenScheduled, onSearch: openCommandMenu }) })) : null, prelude, !chatFirstMode ? (_jsx("div", { className: "flex justify-end px-2 pt-0.5", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-dispatch-chat-source-toggle": true, "aria-pressed": includeExternal, "aria-label": includeExternal
|
|
421
424
|
? t("dispatch.sidebar.showLocalChats", {
|
|
422
425
|
defaultValue: "Show local chats",
|
|
423
426
|
})
|
|
@@ -515,7 +518,7 @@ export function NavContent({ onNavigate, extensions, chatFirstMode = false, chat
|
|
|
515
518
|
}, onOpenAllApps: () => {
|
|
516
519
|
navigate(dispatchNavLinkTarget("/apps"));
|
|
517
520
|
onNavigate?.();
|
|
518
|
-
}, createAppTrigger: chatFirstCreateAppTrigger, renderIcon: (app) => (_jsx(AppIcon, { id: app.id, name: app.name, size: "sm",
|
|
521
|
+
}, createAppTrigger: chatFirstCreateAppTrigger, renderIcon: (app) => (_jsx(AppIcon, { id: app.id, name: app.name, size: "sm", className: "size-7 rounded-lg" })), copy: chatFirstCopy }));
|
|
519
522
|
const renderNavItem = (item) => {
|
|
520
523
|
const Icon = item.icon;
|
|
521
524
|
const itemMatchesLocalPath = navItemMatchesPath(item, localPathname);
|
|
@@ -564,7 +567,7 @@ export function NavContent({ onNavigate, extensions, chatFirstMode = false, chat
|
|
|
564
567
|
navigate(dispatchNavLinkTarget("/admin/automations"));
|
|
565
568
|
onNavigate?.();
|
|
566
569
|
},
|
|
567
|
-
}, prelude: chatFirstAppsRail })) : (chatFirstAppsRail) })) : null, _jsxs("div", { className: cn("flex min-h-0 flex-1 flex-col overflow-y-auto", chatFirstMode && "hidden"), children: [_jsx("nav", { className: cn("py-2", collapsed ? "px-1.5" : "px-2"), children: _jsx("ul", { className: cn(collapsed ? "flex flex-col items-center gap-1" : "space-y-0.5"), children: primaryNavItems.map(renderNavItem) }) }), _jsxs("div", { className: "mt-auto shrink-0", children: [bottomNavigation, organizationPicker] }), sidebarFooterActions] }), chatFirstMode ? (_jsxs("div", { className: "mt-auto shrink-0", children: [bottomNavigation, organizationPicker,
|
|
570
|
+
}, prelude: chatFirstAppsRail })) : (chatFirstAppsRail) })) : null, _jsxs("div", { className: cn("flex min-h-0 flex-1 flex-col overflow-y-auto", chatFirstMode && "hidden"), children: [_jsx("nav", { className: cn("py-2", collapsed ? "px-1.5" : "px-2"), children: _jsx("ul", { className: cn(collapsed ? "flex flex-col items-center gap-1" : "space-y-0.5"), children: primaryNavItems.map(renderNavItem) }) }), _jsxs("div", { className: "mt-auto shrink-0", children: [bottomNavigation, organizationPicker] }), sidebarFooterActions] }), chatFirstMode ? (_jsxs("div", { className: "mt-auto shrink-0", children: [bottomNavigation, organizationPicker, sidebarFooterActions] })) : null] }));
|
|
568
571
|
}
|
|
569
572
|
export function Layout({ children, extensions, agentPageHref, }) {
|
|
570
573
|
const t = useT();
|
|
@@ -592,6 +595,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
592
595
|
const chatFirstEmbedded = typeof window !== "undefined" &&
|
|
593
596
|
new URLSearchParams(window.location.search).get("chatFirst") === "1";
|
|
594
597
|
const chatFirstMode = extensions?.chatFirst === true || chatFirstPreference || chatFirstEmbedded;
|
|
598
|
+
const chatFirstHasActiveChat = chatFirstSurfaceScope !== "new";
|
|
595
599
|
const [chatFirstAppLayout, setChatFirstAppLayout] = useState(() => readChatFirstAppLayout());
|
|
596
600
|
const chatFirstAppLayoutHydratedRef = useRef(false);
|
|
597
601
|
const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode });
|
|
@@ -621,10 +625,12 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
621
625
|
}
|
|
622
626
|
return [...registrations.values()];
|
|
623
627
|
}, [chatFirstGrantedAppsQuery.data?.apps, chatFirstWorkspaceApps]);
|
|
624
|
-
const chatFirstAppItems = useMemo(() =>
|
|
628
|
+
const chatFirstAppItems = useMemo(() => chatFirstAppRegistrations
|
|
629
|
+
.filter((app) => app.enabled)
|
|
630
|
+
.map((app) => ({
|
|
625
631
|
id: app.id,
|
|
626
|
-
name: app.name,
|
|
627
|
-
})), [
|
|
632
|
+
name: app.name ?? app.id,
|
|
633
|
+
})), [chatFirstAppRegistrations]);
|
|
628
634
|
const chatFirstCopy = useMemo(() => createDispatchChatFirstCopy(t), [t]);
|
|
629
635
|
const createChatFirstEmbedSession = useActionMutation("create_embed_session", { skipActionQueryInvalidation: true });
|
|
630
636
|
const [chatFirstPane, setChatFirstPane] = useState(null);
|
|
@@ -648,7 +654,10 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
648
654
|
const previousChatFirstSurfaceScopeRef = useRef(chatFirstSurfaceScope);
|
|
649
655
|
const previousChatFirstSurfaceTabCountRef = useRef(null);
|
|
650
656
|
const activeChatFirstSurfaceTab = useMemo(() => chatFirstSurfaceTabs.tabs.find((tab) => tab.id === chatFirstSurfaceTabs.activeTabId) ?? null, [chatFirstSurfaceTabs]);
|
|
651
|
-
const chatFirstAppTakesMain = chatFirstMode &&
|
|
657
|
+
const chatFirstAppTakesMain = chatFirstMode &&
|
|
658
|
+
isChatRoute &&
|
|
659
|
+
activeChatFirstSurfaceTab?.kind === "app" &&
|
|
660
|
+
activeChatFirstSurfaceTab.placement === "main";
|
|
652
661
|
const activeChatFirstAppRegistration = useMemo(() => activeChatFirstSurfaceTab?.kind === "app" &&
|
|
653
662
|
activeChatFirstSurfaceTab.appId
|
|
654
663
|
? (chatFirstAppRegistrations.find((app) => app.id === activeChatFirstSurfaceTab.appId) ?? null)
|
|
@@ -718,7 +727,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
718
727
|
setChatFirstNotice("The app pane opened locally, but its focus could not be synced.");
|
|
719
728
|
});
|
|
720
729
|
}, []);
|
|
721
|
-
const openChatFirstPane = useCallback((pane) => {
|
|
730
|
+
const openChatFirstPane = useCallback((pane, placement = "side") => {
|
|
731
|
+
if (placement === "side" && !chatFirstHasActiveChat)
|
|
732
|
+
return;
|
|
722
733
|
setChatFirstNotice(null);
|
|
723
734
|
closeChatFirstSessionWatch();
|
|
724
735
|
if (!isChatRoute) {
|
|
@@ -730,20 +741,33 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
730
741
|
kind: "app",
|
|
731
742
|
title: app?.name ?? pane.appId,
|
|
732
743
|
appId: pane.appId,
|
|
744
|
+
placement,
|
|
733
745
|
...(pane.path ? { path: pane.path } : {}),
|
|
734
746
|
...(pane.view ? { view: pane.view } : {}),
|
|
735
747
|
});
|
|
736
748
|
setChatFirstSurfacePanelOpen(true);
|
|
737
|
-
persistChatFirstPane(pane);
|
|
749
|
+
persistChatFirstPane({ ...pane, placement });
|
|
738
750
|
}, [
|
|
739
751
|
chatFirstAppRegistrations,
|
|
740
752
|
chatFirstSurfaceTabsStore,
|
|
753
|
+
chatFirstHasActiveChat,
|
|
741
754
|
persistChatFirstPane,
|
|
742
755
|
isChatRoute,
|
|
743
756
|
navigate,
|
|
744
757
|
setChatFirstSurfacePanelOpen,
|
|
745
758
|
]);
|
|
746
759
|
const openChatFirstSurface = useCallback((kind) => {
|
|
760
|
+
if (kind === "browser") {
|
|
761
|
+
persistChatFirstPane(null);
|
|
762
|
+
closeChatFirstSessionWatch();
|
|
763
|
+
chatFirstSurfaceTabsStore.open({
|
|
764
|
+
id: chatFirstSurfaceTabId("browser", "homepage"),
|
|
765
|
+
kind: "browser",
|
|
766
|
+
title: "Browser",
|
|
767
|
+
url: "https://www.google.com/",
|
|
768
|
+
});
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
747
771
|
if (kind !== "agents")
|
|
748
772
|
return;
|
|
749
773
|
persistChatFirstPane(null);
|
|
@@ -760,6 +784,20 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
760
784
|
setChatFirstNotice(chatFirstBrowserResolutionMessage(resolution.reason));
|
|
761
785
|
return;
|
|
762
786
|
}
|
|
787
|
+
if (resolution.target.openExternally && typeof window !== "undefined") {
|
|
788
|
+
try {
|
|
789
|
+
// Builder's Visual Editor rejects iframe ancestors with CSP/X-Frame-
|
|
790
|
+
// Options. Prefer the real browser tab; the browser pane below is a
|
|
791
|
+
// visible fallback when popup policy blocks this non-click event.
|
|
792
|
+
if (window.open(resolution.target.url, "_blank", "noopener,noreferrer")) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
console.warn("[chat-first] external browser open failed; keeping link fallback", error);
|
|
798
|
+
// Fall through to the non-iframe browser pane below.
|
|
799
|
+
}
|
|
800
|
+
}
|
|
763
801
|
persistChatFirstPane(null);
|
|
764
802
|
closeChatFirstSessionWatch();
|
|
765
803
|
setChatFirstNotice(null);
|
|
@@ -897,8 +935,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
897
935
|
? undefined
|
|
898
936
|
: window.location.origin,
|
|
899
937
|
});
|
|
900
|
-
if (resolution.status === "ready")
|
|
901
|
-
openChatFirstPane(resolution.target);
|
|
938
|
+
if (resolution.status === "ready") {
|
|
939
|
+
openChatFirstPane(resolution.target, persisted.placement);
|
|
940
|
+
}
|
|
902
941
|
})
|
|
903
942
|
.catch(() => {
|
|
904
943
|
if (active) {
|
|
@@ -940,7 +979,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
940
979
|
useEffect(() => {
|
|
941
980
|
const tabCount = chatFirstSurfaceTabs.tabs.length;
|
|
942
981
|
const previousTabCount = previousChatFirstSurfaceTabCountRef.current;
|
|
943
|
-
if (!chatFirstMode) {
|
|
982
|
+
if (!chatFirstMode || !chatFirstHasActiveChat) {
|
|
944
983
|
setChatFirstSurfacePanelOpen(false);
|
|
945
984
|
}
|
|
946
985
|
else if (tabCount > 0 &&
|
|
@@ -955,6 +994,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
955
994
|
previousChatFirstSurfaceTabCountRef.current = tabCount;
|
|
956
995
|
}, [
|
|
957
996
|
chatFirstMode,
|
|
997
|
+
chatFirstHasActiveChat,
|
|
958
998
|
setChatFirstSurfacePanelOpen,
|
|
959
999
|
chatFirstSurfaceTabs.tabs.length,
|
|
960
1000
|
isChatRoute,
|
|
@@ -1015,6 +1055,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1015
1055
|
closeChatFirstSessionWatch();
|
|
1016
1056
|
persistChatFirstPane({
|
|
1017
1057
|
appId: tab.appId,
|
|
1058
|
+
placement: tab.placement,
|
|
1018
1059
|
...(tab.path ? { path: tab.path } : {}),
|
|
1019
1060
|
...(tab.view ? { view: tab.view } : {}),
|
|
1020
1061
|
});
|
|
@@ -1133,7 +1174,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1133
1174
|
t("dispatch.sidebar.suggestionRouteSlack"),
|
|
1134
1175
|
t("dispatch.sidebar.suggestionGrantKey"),
|
|
1135
1176
|
];
|
|
1136
|
-
const appContent = (_jsxs("div", { className: "relative flex h-full min-w-0 flex-1 flex-col overflow-hidden", children: [showHeader ? _jsx(Header, { onOpenMobile: () => setMobileOpen(true) }) : null, _jsx(InvitationBanner, {}), isChatRoute && chatFirstMode ? (_jsx(ChatFirstSurfacePanelToggle, { open: chatFirstSurfacePanel.open, onToggle: chatFirstSurfacePanel.toggle, className: "absolute right-3 top-2 z-[4]" })) : null, isChatRoute && chatFirstMode && chatFirstNotice ? (_jsxs("div", { className: "dispatch-chat-first-notice", role: "status", "aria-live": "polite", children: [_jsx("span", { children: chatFirstNotice }), _jsx("button", { type: "button", onClick: () => setChatFirstNotice(null), "aria-label": "Dismiss app notice", children: "Dismiss" })] })) : null, _jsx("main", { className: cn("flex-1", isChatRoute || isWorkspaceAppRoute
|
|
1177
|
+
const appContent = (_jsxs("div", { className: "relative flex h-full min-w-0 flex-1 flex-col overflow-hidden", children: [showHeader ? _jsx(Header, { onOpenMobile: () => setMobileOpen(true) }) : null, _jsx(InvitationBanner, {}), isChatRoute && chatFirstMode && chatFirstHasActiveChat ? (_jsx(ChatFirstSurfacePanelToggle, { open: chatFirstSurfacePanel.open, onToggle: chatFirstSurfacePanel.toggle, className: "absolute right-3 top-2 z-[4]" })) : null, isChatRoute && chatFirstMode && chatFirstNotice ? (_jsxs("div", { className: "dispatch-chat-first-notice", role: "status", "aria-live": "polite", children: [_jsx("span", { children: chatFirstNotice }), _jsx("button", { type: "button", onClick: () => setChatFirstNotice(null), "aria-label": "Dismiss app notice", children: "Dismiss" })] })) : null, _jsx("main", { className: cn("flex-1", isChatRoute || isWorkspaceAppRoute
|
|
1137
1178
|
? "min-h-0 overflow-hidden"
|
|
1138
1179
|
: "overflow-y-auto"), children: showHeader ? (_jsx("div", { className: "mx-auto max-w-7xl space-y-10 px-4 py-6 sm:px-6", children: children })) : (children) })] }));
|
|
1139
1180
|
const chatFirstSurfaceTabsBar = activeChatFirstSurfaceTab?.kind === "app" ? null : (_jsx(ChatFirstSurfaceTabs, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, onActivate: activateChatFirstSurfaceTab, onClose: closeChatFirstSurfaceTab, onCloseOthers: (tab) => {
|
|
@@ -1145,17 +1186,19 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1145
1186
|
if (activeIndex > targetIndex)
|
|
1146
1187
|
activateChatFirstSurfaceTab(tab);
|
|
1147
1188
|
chatFirstSurfaceTabsStore.closeToRight(tab.id);
|
|
1148
|
-
}, onCloseAll: closeAllChatFirstSurfaceTabs, onOpenSurface: openChatFirstSurface, copy: chatFirstCopy }));
|
|
1189
|
+
}, onCloseAll: closeAllChatFirstSurfaceTabs, onOpenSurface: openChatFirstSurface, apps: chatFirstAppItems, onOpenApp: (app) => openChatFirstPane({ appId: app.id }, "side"), renderAppIcon: (app) => (_jsx(AppIcon, { id: app.id, name: app.name, size: "sm", className: "size-7 rounded-lg" })), copy: chatFirstCopy }));
|
|
1149
1190
|
const chatFirstSurfaceContent = chatFirstSurfaceTabs.tabs.length > 0 ? (_jsx(ChatFirstSurfaceContent, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, renderTab: renderChatFirstSurfaceTab })) : null;
|
|
1150
|
-
const content = isChatRoute ? (_jsx("div", { className: cn("agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden", chatFirstMode && "dispatch-chat-first-surface"), children: chatFirstAppTakesMain ? (_jsx("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", "data-dispatch-chat-first-main-app": true, children: chatFirstSurfaceContent })) : (_jsxs(_Fragment, { children: [appContent, chatFirstMode &&
|
|
1191
|
+
const content = isChatRoute ? (_jsx("div", { className: cn("agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden", chatFirstMode && "dispatch-chat-first-surface"), children: chatFirstAppTakesMain ? (_jsx("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", "data-dispatch-chat-first-main-app": true, children: chatFirstSurfaceContent })) : (_jsxs(_Fragment, { children: [appContent, chatFirstMode &&
|
|
1192
|
+
chatFirstHasActiveChat &&
|
|
1193
|
+
chatFirstSurfacePanel.open ? (_jsxs(ChatFirstSurfacePanel, { width: chatFirstSurfaceResize.width, onResizePointerDown: chatFirstSurfaceResize.onPointerDown, copy: chatFirstCopy, children: [chatFirstSurfaceTabsBar, chatFirstSurfaceContent] })) : null] })) })) : isWorkspaceAppRoute ? (appContent) : (_jsx(AgentSidebar, { position: "right", defaultOpen: false, agentPageHref: agentPageHref, chatViewTransition: true, storageKey: "dispatch", openOnChatRunning: chatHomeHandoffActive, onFullscreenRequest: openAskAgentFullscreen, emptyStateText: t("dispatch.sidebar.emptyAgentText"), suggestions: sidebarSuggestions, children: appContent }));
|
|
1151
1194
|
return (_jsx(DispatchExtensionsContext.Provider, { value: extensions, children: _jsx(HeaderActionsProvider, { children: _jsxs("div", { className: "agent-layout-shell flex h-screen w-full overflow-hidden bg-background", children: [_jsx("aside", { "data-collapsed": sidebarCollapsed ? "true" : "false", className: cn("agent-layout-left-drawer hidden shrink-0 flex-col border-e !border-e-sidebar-border bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out lg:flex", sidebarCollapsed ? "w-14" : "w-56"), children: _jsx(NavContent, { extensions: extensions, chatFirstMode: chatFirstMode, chatFirstEmbedded: chatFirstEmbedded, collapsed: sidebarCollapsed, chatFirstAppLayout: chatFirstAppLayout, onChatFirstAppLayoutChange: persistChatFirstAppLayout, chatFirstApps: chatFirstAppItems, chatFirstAppsLoading: chatFirstAppsQuery.isLoading, chatFirstAppsError: chatFirstAppsQuery.isError
|
|
1152
1195
|
? chatFirstCopy("appsLoadError")
|
|
1153
1196
|
: null, chatFirstActiveAppId: activeChatFirstSurfaceTab?.kind === "app"
|
|
1154
1197
|
? activeChatFirstSurfaceTab.appId
|
|
1155
|
-
: undefined, onChatFirstAppOpen: (app) => openChatFirstPane({ appId: app.id }), onChatFirstAppsRetry: () => void chatFirstAppsQuery.refetch(), collapsible: true, onCollapsedChange: setSidebarCollapsed }) }), _jsx(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: _jsxs(SheetContent, { side: "left", className: "w-72 p-0
|
|
1198
|
+
: undefined, onChatFirstAppOpen: (app) => openChatFirstPane({ appId: app.id }, "main"), onChatFirstAppsRetry: () => void chatFirstAppsQuery.refetch(), collapsible: true, onCollapsedChange: setSidebarCollapsed }) }), _jsx(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: _jsxs(SheetContent, { side: "left", className: "w-72 bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden", children: [_jsx(SheetTitle, { className: "sr-only", children: t("dispatch.nav.navigation") }), _jsx(SheetDescription, { className: "sr-only", children: t("dispatch.nav.navigationDescription") }), _jsx("div", { className: "flex h-full w-full flex-col", children: _jsx(NavContent, { extensions: extensions, chatFirstMode: chatFirstMode, chatFirstEmbedded: chatFirstEmbedded, collapsed: false, chatFirstAppLayout: chatFirstAppLayout, onChatFirstAppLayoutChange: persistChatFirstAppLayout, chatFirstApps: chatFirstAppItems, chatFirstAppsLoading: chatFirstAppsQuery.isLoading, chatFirstAppsError: chatFirstAppsQuery.isError
|
|
1156
1199
|
? chatFirstCopy("appsLoadError")
|
|
1157
1200
|
: null, chatFirstActiveAppId: activeChatFirstSurfaceTab?.kind === "app"
|
|
1158
1201
|
? activeChatFirstSurfaceTab.appId
|
|
1159
|
-
: undefined, onChatFirstAppOpen: (app) => openChatFirstPane({ appId: app.id }), onChatFirstAppsRetry: () => void chatFirstAppsQuery.refetch(), onNavigate: () => setMobileOpen(false) }) })] }) }), content] }) }) }));
|
|
1202
|
+
: undefined, onChatFirstAppOpen: (app) => openChatFirstPane({ appId: app.id }, "main"), onChatFirstAppsRetry: () => void chatFirstAppsQuery.refetch(), onNavigate: () => setMobileOpen(false) }) })] }) }), content] }) }) }));
|
|
1160
1203
|
}
|
|
1161
1204
|
//# sourceMappingURL=Layout.js.map
|