@agent-native/dispatch 0.22.1 → 0.23.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 +1 -1
- package/dist/components/app-icon.d.ts +2 -1
- package/dist/components/app-icon.d.ts.map +1 -1
- package/dist/components/app-icon.js +51 -29
- package/dist/components/app-icon.js.map +1 -1
- package/dist/components/app-list-row.d.ts +1 -1
- package/dist/components/app-list-row.d.ts.map +1 -1
- package/dist/components/app-list-row.js +1 -1
- package/dist/components/app-list-row.js.map +1 -1
- package/dist/components/app-open-actions.d.ts +2 -1
- package/dist/components/app-open-actions.d.ts.map +1 -1
- package/dist/components/app-open-actions.js +2 -2
- package/dist/components/app-open-actions.js.map +1 -1
- package/dist/components/dispatch-control-plane.d.ts.map +1 -1
- package/dist/components/dispatch-control-plane.js +16 -17
- 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 +137 -66
- 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 +1 -1
- package/dist/components/layout/workspace-apps-rail.js.map +1 -1
- package/dist/components/other-apps-section.d.ts +3 -1
- package/dist/components/other-apps-section.d.ts.map +1 -1
- package/dist/components/other-apps-section.js +9 -6
- package/dist/components/other-apps-section.js.map +1 -1
- package/dist/components/workspace-app-card.d.ts.map +1 -1
- package/dist/components/workspace-app-card.js +7 -2
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/components/workspace-template-card.d.ts.map +1 -1
- package/dist/components/workspace-template-card.js +2 -5
- package/dist/components/workspace-template-card.js.map +1 -1
- package/dist/lib/overview-chat.d.ts.map +1 -1
- package/dist/lib/overview-chat.js +0 -8
- package/dist/lib/overview-chat.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/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 +71 -43
- package/src/components/app-list-row.tsx +1 -1
- package/src/components/app-open-actions.tsx +4 -2
- package/src/components/dispatch-control-plane.spec.tsx +45 -7
- package/src/components/dispatch-control-plane.tsx +56 -75
- package/src/components/layout/Layout.spec.tsx +53 -0
- package/src/components/layout/Layout.tsx +227 -99
- package/src/components/layout/workspace-apps-rail.tsx +1 -0
- package/src/components/other-apps-section.tsx +61 -40
- package/src/components/workspace-app-card.spec.tsx +63 -66
- package/src/components/workspace-app-card.tsx +10 -3
- package/src/components/workspace-template-card.spec.tsx +7 -8
- package/src/components/workspace-template-card.tsx +21 -11
- package/src/lib/overview-chat.spec.ts +0 -19
- package/src/lib/overview-chat.ts +0 -9
- package/src/routes/pages/chat.tsx +1 -1
- 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 +2 -2
|
@@ -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("
|
|
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
|
})
|
|
@@ -432,7 +435,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
|
|
|
432
435
|
}) })] }) })) : null, !chatFirstMode &&
|
|
433
436
|
chatsLoading &&
|
|
434
437
|
visibleThreads.length === 0 &&
|
|
435
|
-
Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, `chat-skeleton-${index}`))), chatFirstMode ? (_jsx(ChatFirstChatHistory, { items: chatItems, activeId: displayedActiveThreadId, loading: chatsLoading && visibleThreads.length === 0, loadingLabel: _jsx("div", { className: "space-y-1 px-2 py-1", children: [0, 1, 2].map((index) => (_jsxs("div", { className: "flex items-center gap-2 px-1 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, index))) }), label: t("dispatch.sidebar.chats", { defaultValue: "Chats" }), onSelect: (threadId) => openThread(threadId), renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
|
|
438
|
+
Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, `chat-skeleton-${index}`))), chatFirstMode && (chatsLoading || visibleThreads.length > 0) ? (_jsx(ChatFirstChatHistory, { items: chatItems, activeId: displayedActiveThreadId, loading: chatsLoading && visibleThreads.length === 0, loadingLabel: _jsx("div", { className: "space-y-1 px-2 py-1", children: [0, 1, 2].map((index) => (_jsxs("div", { className: "flex items-center gap-2 px-1 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, index))) }), label: t("dispatch.sidebar.chats", { defaultValue: "Chats" }), onSelect: (threadId) => openThread(threadId), renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
|
|
436
439
|
options: (item) => t("dispatch.sidebar.chatOptions", {
|
|
437
440
|
title: item.titleText ?? "",
|
|
438
441
|
}),
|
|
@@ -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", className: "size-
|
|
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();
|
|
@@ -584,26 +587,50 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
584
587
|
const localPathname = localDispatchPath(location.pathname);
|
|
585
588
|
const isChatRoute = localPathname === "/chat" || localPathname.startsWith("/chat/");
|
|
586
589
|
const chatFirstSurfaceScope = threadIdFromPath(localPathname) ?? "new";
|
|
587
|
-
const
|
|
590
|
+
const isWorkspaceAppRoute = localPathname.startsWith("/apps/");
|
|
591
|
+
const isWorkspaceAppHostRoute = isWorkspaceAppRoute &&
|
|
592
|
+
typeof window !== "undefined" &&
|
|
593
|
+
new URLSearchParams(window.location.search).get("embedded") === "1";
|
|
588
594
|
const [chatFirstPreference, setChatFirstPreference] = useState(() => readChatFirstMode());
|
|
589
595
|
const chatFirstEmbedded = typeof window !== "undefined" &&
|
|
590
596
|
new URLSearchParams(window.location.search).get("chatFirst") === "1";
|
|
591
597
|
const chatFirstMode = extensions?.chatFirst === true || chatFirstPreference || chatFirstEmbedded;
|
|
598
|
+
const chatFirstHasActiveChat = chatFirstSurfaceScope !== "new";
|
|
592
599
|
const [chatFirstAppLayout, setChatFirstAppLayout] = useState(() => readChatFirstAppLayout());
|
|
593
600
|
const chatFirstAppLayoutHydratedRef = useRef(false);
|
|
594
|
-
const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode
|
|
601
|
+
const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode });
|
|
602
|
+
const chatFirstGrantedAppsQuery = useActionQuery("list_apps", {}, { enabled: chatFirstMode });
|
|
595
603
|
const chatFirstWorkspaceApps = useMemo(() => mergeChatFirstWorkspaceApps(chatFirstAppsQuery.data), [chatFirstAppsQuery.data]);
|
|
596
|
-
const chatFirstAppRegistrations = useMemo(() =>
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
+
const chatFirstAppRegistrations = useMemo(() => {
|
|
605
|
+
const registrations = new Map();
|
|
606
|
+
for (const app of chatFirstWorkspaceApps) {
|
|
607
|
+
registrations.set(app.id.toLowerCase(), {
|
|
608
|
+
id: app.id,
|
|
609
|
+
name: app.name,
|
|
610
|
+
path: app.path,
|
|
611
|
+
url: app.url,
|
|
612
|
+
enabled: app.status !== "pending" && app.archived !== true,
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
for (const app of chatFirstGrantedAppsQuery.data?.apps ?? []) {
|
|
616
|
+
const id = app.id.trim();
|
|
617
|
+
if (!id || registrations.has(id.toLowerCase()))
|
|
618
|
+
continue;
|
|
619
|
+
registrations.set(id.toLowerCase(), {
|
|
620
|
+
id,
|
|
621
|
+
name: app.name,
|
|
622
|
+
url: app.url,
|
|
623
|
+
enabled: true,
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
return [...registrations.values()];
|
|
627
|
+
}, [chatFirstGrantedAppsQuery.data?.apps, chatFirstWorkspaceApps]);
|
|
628
|
+
const chatFirstAppItems = useMemo(() => chatFirstAppRegistrations
|
|
629
|
+
.filter((app) => app.enabled)
|
|
630
|
+
.map((app) => ({
|
|
604
631
|
id: app.id,
|
|
605
|
-
name: app.name,
|
|
606
|
-
})), [
|
|
632
|
+
name: app.name ?? app.id,
|
|
633
|
+
})), [chatFirstAppRegistrations]);
|
|
607
634
|
const chatFirstCopy = useMemo(() => createDispatchChatFirstCopy(t), [t]);
|
|
608
635
|
const createChatFirstEmbedSession = useActionMutation("create_embed_session", { skipActionQueryInvalidation: true });
|
|
609
636
|
const [chatFirstPane, setChatFirstPane] = useState(null);
|
|
@@ -627,10 +654,21 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
627
654
|
const previousChatFirstSurfaceScopeRef = useRef(chatFirstSurfaceScope);
|
|
628
655
|
const previousChatFirstSurfaceTabCountRef = useRef(null);
|
|
629
656
|
const activeChatFirstSurfaceTab = useMemo(() => chatFirstSurfaceTabs.tabs.find((tab) => tab.id === chatFirstSurfaceTabs.activeTabId) ?? null, [chatFirstSurfaceTabs]);
|
|
630
|
-
const
|
|
657
|
+
const chatFirstAppTakesMain = chatFirstMode &&
|
|
658
|
+
isChatRoute &&
|
|
659
|
+
activeChatFirstSurfaceTab?.kind === "app" &&
|
|
660
|
+
activeChatFirstSurfaceTab.placement === "main";
|
|
661
|
+
const activeChatFirstAppRegistration = useMemo(() => activeChatFirstSurfaceTab?.kind === "app" &&
|
|
631
662
|
activeChatFirstSurfaceTab.appId
|
|
632
|
-
? (
|
|
633
|
-
: null, [activeChatFirstSurfaceTab,
|
|
663
|
+
? (chatFirstAppRegistrations.find((app) => app.id === activeChatFirstSurfaceTab.appId) ?? null)
|
|
664
|
+
: null, [activeChatFirstSurfaceTab, chatFirstAppRegistrations]);
|
|
665
|
+
const activeChatFirstApp = useMemo(() => activeChatFirstAppRegistration
|
|
666
|
+
? {
|
|
667
|
+
id: activeChatFirstAppRegistration.id,
|
|
668
|
+
name: activeChatFirstAppRegistration.name ??
|
|
669
|
+
activeChatFirstAppRegistration.id,
|
|
670
|
+
}
|
|
671
|
+
: null, [activeChatFirstAppRegistration]);
|
|
634
672
|
const chatFirstAgentActivities = useMemo(() => (chatFirstAgentsQuery.data?.threads ?? []).map((thread) => ({
|
|
635
673
|
sessionId: thread.id,
|
|
636
674
|
title: thread.title || chatFirstCopy("agentsTitle", { name: thread.id }),
|
|
@@ -641,7 +679,8 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
641
679
|
const chatFirstEmbedPath = activeChatFirstSurfaceTab?.kind === "app"
|
|
642
680
|
? (activeChatFirstSurfaceTab.path ??
|
|
643
681
|
chatFirstPane?.path ??
|
|
644
|
-
|
|
682
|
+
activeChatFirstAppRegistration?.path ??
|
|
683
|
+
"/")
|
|
645
684
|
: null;
|
|
646
685
|
useEffect(() => {
|
|
647
686
|
if (!chatFirstMode || !isChatRoute || !activeChatFirstApp) {
|
|
@@ -688,25 +727,47 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
688
727
|
setChatFirstNotice("The app pane opened locally, but its focus could not be synced.");
|
|
689
728
|
});
|
|
690
729
|
}, []);
|
|
691
|
-
const openChatFirstPane = useCallback((pane) => {
|
|
730
|
+
const openChatFirstPane = useCallback((pane, placement = "side") => {
|
|
731
|
+
if (placement === "side" && !chatFirstHasActiveChat)
|
|
732
|
+
return;
|
|
692
733
|
setChatFirstNotice(null);
|
|
693
734
|
closeChatFirstSessionWatch();
|
|
735
|
+
if (!isChatRoute) {
|
|
736
|
+
navigateWithAgentChatViewTransition(navigate, dispatchNavLinkTarget("/chat"));
|
|
737
|
+
}
|
|
694
738
|
const app = chatFirstAppRegistrations.find((candidate) => candidate.id === pane.appId);
|
|
695
739
|
chatFirstSurfaceTabsStore.open({
|
|
696
740
|
id: chatFirstSurfaceTabId("app", `${pane.appId}:${pane.path ?? pane.view ?? "/"}`),
|
|
697
741
|
kind: "app",
|
|
698
742
|
title: app?.name ?? pane.appId,
|
|
699
743
|
appId: pane.appId,
|
|
744
|
+
placement,
|
|
700
745
|
...(pane.path ? { path: pane.path } : {}),
|
|
701
746
|
...(pane.view ? { view: pane.view } : {}),
|
|
702
747
|
});
|
|
703
|
-
|
|
748
|
+
setChatFirstSurfacePanelOpen(true);
|
|
749
|
+
persistChatFirstPane({ ...pane, placement });
|
|
704
750
|
}, [
|
|
705
751
|
chatFirstAppRegistrations,
|
|
706
752
|
chatFirstSurfaceTabsStore,
|
|
753
|
+
chatFirstHasActiveChat,
|
|
707
754
|
persistChatFirstPane,
|
|
755
|
+
isChatRoute,
|
|
756
|
+
navigate,
|
|
757
|
+
setChatFirstSurfacePanelOpen,
|
|
708
758
|
]);
|
|
709
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
|
+
}
|
|
710
771
|
if (kind !== "agents")
|
|
711
772
|
return;
|
|
712
773
|
persistChatFirstPane(null);
|
|
@@ -723,6 +784,20 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
723
784
|
setChatFirstNotice(chatFirstBrowserResolutionMessage(resolution.reason));
|
|
724
785
|
return;
|
|
725
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
|
+
}
|
|
726
801
|
persistChatFirstPane(null);
|
|
727
802
|
closeChatFirstSessionWatch();
|
|
728
803
|
setChatFirstNotice(null);
|
|
@@ -734,7 +809,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
734
809
|
});
|
|
735
810
|
}, [chatFirstSurfaceTabsStore, persistChatFirstPane]);
|
|
736
811
|
const resolveChatFirstOpenApp = useCallback((detail) => {
|
|
737
|
-
if (chatFirstAppsQuery.isLoading) {
|
|
812
|
+
if (chatFirstAppsQuery.isLoading || chatFirstGrantedAppsQuery.isLoading) {
|
|
738
813
|
pendingChatFirstOpenAppRef.current = detail;
|
|
739
814
|
return;
|
|
740
815
|
}
|
|
@@ -756,10 +831,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
756
831
|
chatFirstAppRegistrations,
|
|
757
832
|
chatFirstAppsQuery.isError,
|
|
758
833
|
chatFirstAppsQuery.isLoading,
|
|
834
|
+
chatFirstGrantedAppsQuery.isLoading,
|
|
759
835
|
openChatFirstPane,
|
|
760
836
|
]);
|
|
761
|
-
const sidebarBeforeAppRef = useRef(null);
|
|
762
|
-
const sidebarAutoCollapsedRef = useRef(false);
|
|
763
837
|
const chatHomeHandoffActive = useAgentChatHomeHandoff({
|
|
764
838
|
storageKey: "dispatch",
|
|
765
839
|
activePath: localPathname,
|
|
@@ -811,7 +885,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
811
885
|
});
|
|
812
886
|
}, []);
|
|
813
887
|
useEffect(() => {
|
|
814
|
-
if (!chatFirstMode
|
|
888
|
+
if (!chatFirstMode) {
|
|
815
889
|
setChatFirstPane(null);
|
|
816
890
|
closeChatFirstSessionWatch();
|
|
817
891
|
chatFirstSurfaceTabsStore.closeAll();
|
|
@@ -861,8 +935,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
861
935
|
? undefined
|
|
862
936
|
: window.location.origin,
|
|
863
937
|
});
|
|
864
|
-
if (resolution.status === "ready")
|
|
865
|
-
openChatFirstPane(resolution.target);
|
|
938
|
+
if (resolution.status === "ready") {
|
|
939
|
+
openChatFirstPane(resolution.target, persisted.placement);
|
|
940
|
+
}
|
|
866
941
|
})
|
|
867
942
|
.catch(() => {
|
|
868
943
|
if (active) {
|
|
@@ -904,7 +979,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
904
979
|
useEffect(() => {
|
|
905
980
|
const tabCount = chatFirstSurfaceTabs.tabs.length;
|
|
906
981
|
const previousTabCount = previousChatFirstSurfaceTabCountRef.current;
|
|
907
|
-
if (!chatFirstMode || !
|
|
982
|
+
if (!chatFirstMode || !chatFirstHasActiveChat) {
|
|
908
983
|
setChatFirstSurfacePanelOpen(false);
|
|
909
984
|
}
|
|
910
985
|
else if (tabCount > 0 &&
|
|
@@ -919,6 +994,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
919
994
|
previousChatFirstSurfaceTabCountRef.current = tabCount;
|
|
920
995
|
}, [
|
|
921
996
|
chatFirstMode,
|
|
997
|
+
chatFirstHasActiveChat,
|
|
922
998
|
setChatFirstSurfacePanelOpen,
|
|
923
999
|
chatFirstSurfaceTabs.tabs.length,
|
|
924
1000
|
isChatRoute,
|
|
@@ -933,13 +1009,17 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
933
1009
|
}, [activeChatFirstSurfaceTab, chatFirstSessionWatch.target]);
|
|
934
1010
|
useEffect(() => {
|
|
935
1011
|
const pending = pendingChatFirstOpenAppRef.current;
|
|
936
|
-
if (!pending ||
|
|
1012
|
+
if (!pending ||
|
|
1013
|
+
chatFirstAppsQuery.isLoading ||
|
|
1014
|
+
chatFirstGrantedAppsQuery.isLoading)
|
|
937
1015
|
return;
|
|
938
1016
|
resolveChatFirstOpenApp(pending);
|
|
939
1017
|
}, [
|
|
940
1018
|
chatFirstAppsQuery.data,
|
|
941
1019
|
chatFirstAppsQuery.isError,
|
|
942
1020
|
chatFirstAppsQuery.isLoading,
|
|
1021
|
+
chatFirstGrantedAppsQuery.data,
|
|
1022
|
+
chatFirstGrantedAppsQuery.isLoading,
|
|
943
1023
|
resolveChatFirstOpenApp,
|
|
944
1024
|
]);
|
|
945
1025
|
useEffect(() => {
|
|
@@ -959,26 +1039,6 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
959
1039
|
chatFirstSurfaceTabsStore,
|
|
960
1040
|
isChatRoute,
|
|
961
1041
|
]);
|
|
962
|
-
useEffect(() => {
|
|
963
|
-
if (isWorkspaceAppHostRoute) {
|
|
964
|
-
if (!sidebarAutoCollapsedRef.current) {
|
|
965
|
-
sidebarAutoCollapsedRef.current = true;
|
|
966
|
-
sidebarBeforeAppRef.current = sidebarCollapsed;
|
|
967
|
-
}
|
|
968
|
-
if (!sidebarCollapsed)
|
|
969
|
-
setSidebarCollapsed(true);
|
|
970
|
-
return;
|
|
971
|
-
}
|
|
972
|
-
if (!sidebarAutoCollapsedRef.current)
|
|
973
|
-
return;
|
|
974
|
-
sidebarAutoCollapsedRef.current = false;
|
|
975
|
-
const previousSidebarState = sidebarBeforeAppRef.current;
|
|
976
|
-
sidebarBeforeAppRef.current = null;
|
|
977
|
-
if (previousSidebarState !== null &&
|
|
978
|
-
previousSidebarState !== sidebarCollapsed) {
|
|
979
|
-
setSidebarCollapsed(previousSidebarState);
|
|
980
|
-
}
|
|
981
|
-
}, [isWorkspaceAppHostRoute, sidebarCollapsed]);
|
|
982
1042
|
useEffect(() => {
|
|
983
1043
|
if (typeof window === "undefined" || isWorkspaceAppHostRoute)
|
|
984
1044
|
return;
|
|
@@ -995,6 +1055,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
995
1055
|
closeChatFirstSessionWatch();
|
|
996
1056
|
persistChatFirstPane({
|
|
997
1057
|
appId: tab.appId,
|
|
1058
|
+
placement: tab.placement,
|
|
998
1059
|
...(tab.path ? { path: tab.path } : {}),
|
|
999
1060
|
...(tab.view ? { view: tab.view } : {}),
|
|
1000
1061
|
});
|
|
@@ -1042,8 +1103,14 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1042
1103
|
if (tab.kind === "app") {
|
|
1043
1104
|
if (tab.id !== chatFirstSurfaceTabs.activeTabId)
|
|
1044
1105
|
return null;
|
|
1045
|
-
const
|
|
1046
|
-
? (
|
|
1106
|
+
const registration = tab.appId
|
|
1107
|
+
? (chatFirstAppRegistrations.find((candidate) => candidate.id === tab.appId) ?? null)
|
|
1108
|
+
: null;
|
|
1109
|
+
const app = registration
|
|
1110
|
+
? {
|
|
1111
|
+
id: registration.id,
|
|
1112
|
+
name: registration.name ?? registration.id,
|
|
1113
|
+
}
|
|
1047
1114
|
: null;
|
|
1048
1115
|
return (_jsx(ChatFirstAppPane, { app: app, status: chatFirstEmbedError
|
|
1049
1116
|
? "error"
|
|
@@ -1087,7 +1154,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1087
1154
|
chatFirstEmbedUrl,
|
|
1088
1155
|
chatFirstSessionWatch.target,
|
|
1089
1156
|
chatFirstSurfaceTabs.activeTabId,
|
|
1090
|
-
|
|
1157
|
+
chatFirstAppRegistrations,
|
|
1091
1158
|
closeChatFirstSurfaceTab,
|
|
1092
1159
|
renderChatFirstWatchChat,
|
|
1093
1160
|
]);
|
|
@@ -1107,27 +1174,31 @@ export function Layout({ children, extensions, agentPageHref, }) {
|
|
|
1107
1174
|
t("dispatch.sidebar.suggestionRouteSlack"),
|
|
1108
1175
|
t("dispatch.sidebar.suggestionGrantKey"),
|
|
1109
1176
|
];
|
|
1110
|
-
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 ||
|
|
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
|
|
1111
1178
|
? "min-h-0 overflow-hidden"
|
|
1112
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) })] }));
|
|
1113
|
-
const
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1180
|
+
const chatFirstSurfaceTabsBar = activeChatFirstSurfaceTab?.kind === "app" ? null : (_jsx(ChatFirstSurfaceTabs, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, onActivate: activateChatFirstSurfaceTab, onClose: closeChatFirstSurfaceTab, onCloseOthers: (tab) => {
|
|
1181
|
+
activateChatFirstSurfaceTab(tab);
|
|
1182
|
+
chatFirstSurfaceTabsStore.closeOthers(tab.id);
|
|
1183
|
+
}, onCloseToRight: (tab) => {
|
|
1184
|
+
const targetIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === tab.id);
|
|
1185
|
+
const activeIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === chatFirstSurfaceTabs.activeTabId);
|
|
1186
|
+
if (activeIndex > targetIndex)
|
|
1187
|
+
activateChatFirstSurfaceTab(tab);
|
|
1188
|
+
chatFirstSurfaceTabsStore.closeToRight(tab.id);
|
|
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 }));
|
|
1190
|
+
const chatFirstSurfaceContent = chatFirstSurfaceTabs.tabs.length > 0 ? (_jsx(ChatFirstSurfaceContent, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, renderTab: renderChatFirstSurfaceTab })) : null;
|
|
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 }));
|
|
1123
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
|
|
1124
1195
|
? chatFirstCopy("appsLoadError")
|
|
1125
1196
|
: null, chatFirstActiveAppId: activeChatFirstSurfaceTab?.kind === "app"
|
|
1126
1197
|
? activeChatFirstSurfaceTab.appId
|
|
1127
|
-
: 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
|
|
1128
1199
|
? chatFirstCopy("appsLoadError")
|
|
1129
1200
|
: null, chatFirstActiveAppId: activeChatFirstSurfaceTab?.kind === "app"
|
|
1130
1201
|
? activeChatFirstSurfaceTab.appId
|
|
1131
|
-
: 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] }) }) }));
|
|
1132
1203
|
}
|
|
1133
1204
|
//# sourceMappingURL=Layout.js.map
|