@agent-native/dispatch 0.22.1 → 0.23.0
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/components/app-icon.d.ts +2 -1
- package/dist/components/app-icon.d.ts.map +1 -1
- package/dist/components/app-icon.js +4 -2
- 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 +84 -56
- 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/package.json +3 -3
- package/src/components/app-icon.tsx +6 -2
- 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 +43 -7
- package/src/components/dispatch-control-plane.tsx +56 -75
- package/src/components/layout/Layout.spec.tsx +46 -0
- package/src/components/layout/Layout.tsx +149 -84
- 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/styles/dispatch.css +2 -2
|
@@ -214,6 +214,16 @@ interface ChatFirstEmbedSessionInput {
|
|
|
214
214
|
chrome: "minimal";
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
interface ChatFirstGrantedAppSummary {
|
|
218
|
+
id: string;
|
|
219
|
+
name: string;
|
|
220
|
+
url?: string | null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
interface ChatFirstGrantedAppsResult {
|
|
224
|
+
apps: ChatFirstGrantedAppSummary[];
|
|
225
|
+
}
|
|
226
|
+
|
|
217
227
|
export function buildChatFirstEmbedSessionInput(
|
|
218
228
|
appId: string,
|
|
219
229
|
path: string,
|
|
@@ -663,7 +673,7 @@ function DispatchChatsSection({
|
|
|
663
673
|
return (
|
|
664
674
|
<div
|
|
665
675
|
className={cn(
|
|
666
|
-
"
|
|
676
|
+
"min-w-0 space-y-0.5",
|
|
667
677
|
showNewChat && "dispatch-chat-first-chats",
|
|
668
678
|
)}
|
|
669
679
|
>
|
|
@@ -730,7 +740,7 @@ function DispatchChatsSection({
|
|
|
730
740
|
<Skeleton className="h-3 w-3/4 rounded" />
|
|
731
741
|
</div>
|
|
732
742
|
))}
|
|
733
|
-
{chatFirstMode ? (
|
|
743
|
+
{chatFirstMode && (chatsLoading || visibleThreads.length > 0) ? (
|
|
734
744
|
<ChatFirstChatHistory
|
|
735
745
|
items={chatItems}
|
|
736
746
|
activeId={displayedActiveThreadId}
|
|
@@ -1015,6 +1025,7 @@ export function NavContent({
|
|
|
1015
1025
|
id={app.id}
|
|
1016
1026
|
name={app.name}
|
|
1017
1027
|
size="sm"
|
|
1028
|
+
monochrome
|
|
1018
1029
|
className="size-5 rounded-md"
|
|
1019
1030
|
/>
|
|
1020
1031
|
)}
|
|
@@ -1278,7 +1289,11 @@ export function Layout({
|
|
|
1278
1289
|
const isChatRoute =
|
|
1279
1290
|
localPathname === "/chat" || localPathname.startsWith("/chat/");
|
|
1280
1291
|
const chatFirstSurfaceScope = threadIdFromPath(localPathname) ?? "new";
|
|
1281
|
-
const
|
|
1292
|
+
const isWorkspaceAppRoute = localPathname.startsWith("/apps/");
|
|
1293
|
+
const isWorkspaceAppHostRoute =
|
|
1294
|
+
isWorkspaceAppRoute &&
|
|
1295
|
+
typeof window !== "undefined" &&
|
|
1296
|
+
new URLSearchParams(window.location.search).get("embedded") === "1";
|
|
1282
1297
|
const [chatFirstPreference, setChatFirstPreference] = useState(() =>
|
|
1283
1298
|
readChatFirstMode(),
|
|
1284
1299
|
);
|
|
@@ -1293,23 +1308,40 @@ export function Layout({
|
|
|
1293
1308
|
const chatFirstAppsQuery = useActionQuery<WorkspaceAppSummary[]>(
|
|
1294
1309
|
"list-workspace-apps",
|
|
1295
1310
|
{ includeAgentCards: false },
|
|
1296
|
-
{ enabled: chatFirstMode
|
|
1311
|
+
{ enabled: chatFirstMode },
|
|
1312
|
+
);
|
|
1313
|
+
const chatFirstGrantedAppsQuery = useActionQuery<ChatFirstGrantedAppsResult>(
|
|
1314
|
+
"list_apps",
|
|
1315
|
+
{},
|
|
1316
|
+
{ enabled: chatFirstMode },
|
|
1297
1317
|
);
|
|
1298
1318
|
const chatFirstWorkspaceApps = useMemo(
|
|
1299
1319
|
() => mergeChatFirstWorkspaceApps(chatFirstAppsQuery.data),
|
|
1300
1320
|
[chatFirstAppsQuery.data],
|
|
1301
1321
|
);
|
|
1302
|
-
const chatFirstAppRegistrations = useMemo<ChatFirstAppRegistration[]>(
|
|
1303
|
-
()
|
|
1304
|
-
|
|
1322
|
+
const chatFirstAppRegistrations = useMemo<ChatFirstAppRegistration[]>(() => {
|
|
1323
|
+
const registrations = new Map<string, ChatFirstAppRegistration>();
|
|
1324
|
+
for (const app of chatFirstWorkspaceApps) {
|
|
1325
|
+
registrations.set(app.id.toLowerCase(), {
|
|
1305
1326
|
id: app.id,
|
|
1306
1327
|
name: app.name,
|
|
1307
1328
|
path: app.path,
|
|
1308
1329
|
url: app.url,
|
|
1309
1330
|
enabled: app.status !== "pending" && app.archived !== true,
|
|
1310
|
-
})
|
|
1311
|
-
|
|
1312
|
-
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
for (const app of chatFirstGrantedAppsQuery.data?.apps ?? []) {
|
|
1334
|
+
const id = app.id.trim();
|
|
1335
|
+
if (!id || registrations.has(id.toLowerCase())) continue;
|
|
1336
|
+
registrations.set(id.toLowerCase(), {
|
|
1337
|
+
id,
|
|
1338
|
+
name: app.name,
|
|
1339
|
+
url: app.url,
|
|
1340
|
+
enabled: true,
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
return [...registrations.values()];
|
|
1344
|
+
}, [chatFirstGrantedAppsQuery.data?.apps, chatFirstWorkspaceApps]);
|
|
1313
1345
|
const chatFirstAppItems = useMemo<ChatFirstAppItem[]>(
|
|
1314
1346
|
() =>
|
|
1315
1347
|
chatFirstWorkspaceApps.map((app) => ({
|
|
@@ -1366,15 +1398,29 @@ export function Layout({
|
|
|
1366
1398
|
) ?? null,
|
|
1367
1399
|
[chatFirstSurfaceTabs],
|
|
1368
1400
|
);
|
|
1369
|
-
const
|
|
1401
|
+
const chatFirstAppTakesMain =
|
|
1402
|
+
chatFirstMode && isChatRoute && activeChatFirstSurfaceTab?.kind === "app";
|
|
1403
|
+
const activeChatFirstAppRegistration = useMemo(
|
|
1370
1404
|
() =>
|
|
1371
1405
|
activeChatFirstSurfaceTab?.kind === "app" &&
|
|
1372
1406
|
activeChatFirstSurfaceTab.appId
|
|
1373
|
-
? (
|
|
1407
|
+
? (chatFirstAppRegistrations.find(
|
|
1374
1408
|
(app) => app.id === activeChatFirstSurfaceTab.appId,
|
|
1375
1409
|
) ?? null)
|
|
1376
1410
|
: null,
|
|
1377
|
-
[activeChatFirstSurfaceTab,
|
|
1411
|
+
[activeChatFirstSurfaceTab, chatFirstAppRegistrations],
|
|
1412
|
+
);
|
|
1413
|
+
const activeChatFirstApp = useMemo(
|
|
1414
|
+
() =>
|
|
1415
|
+
activeChatFirstAppRegistration
|
|
1416
|
+
? {
|
|
1417
|
+
id: activeChatFirstAppRegistration.id,
|
|
1418
|
+
name:
|
|
1419
|
+
activeChatFirstAppRegistration.name ??
|
|
1420
|
+
activeChatFirstAppRegistration.id,
|
|
1421
|
+
}
|
|
1422
|
+
: null,
|
|
1423
|
+
[activeChatFirstAppRegistration],
|
|
1378
1424
|
);
|
|
1379
1425
|
const chatFirstAgentActivities = useMemo<ChatFirstAgentActivity[]>(
|
|
1380
1426
|
() =>
|
|
@@ -1392,7 +1438,8 @@ export function Layout({
|
|
|
1392
1438
|
activeChatFirstSurfaceTab?.kind === "app"
|
|
1393
1439
|
? (activeChatFirstSurfaceTab.path ??
|
|
1394
1440
|
chatFirstPane?.path ??
|
|
1395
|
-
|
|
1441
|
+
activeChatFirstAppRegistration?.path ??
|
|
1442
|
+
"/")
|
|
1396
1443
|
: null;
|
|
1397
1444
|
useEffect(() => {
|
|
1398
1445
|
if (!chatFirstMode || !isChatRoute || !activeChatFirstApp) {
|
|
@@ -1454,6 +1501,12 @@ export function Layout({
|
|
|
1454
1501
|
(pane: DispatchChatFirstPane) => {
|
|
1455
1502
|
setChatFirstNotice(null);
|
|
1456
1503
|
closeChatFirstSessionWatch();
|
|
1504
|
+
if (!isChatRoute) {
|
|
1505
|
+
navigateWithAgentChatViewTransition(
|
|
1506
|
+
navigate,
|
|
1507
|
+
dispatchNavLinkTarget("/chat"),
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1457
1510
|
const app = chatFirstAppRegistrations.find(
|
|
1458
1511
|
(candidate) => candidate.id === pane.appId,
|
|
1459
1512
|
);
|
|
@@ -1468,12 +1521,16 @@ export function Layout({
|
|
|
1468
1521
|
...(pane.path ? { path: pane.path } : {}),
|
|
1469
1522
|
...(pane.view ? { view: pane.view } : {}),
|
|
1470
1523
|
});
|
|
1524
|
+
setChatFirstSurfacePanelOpen(true);
|
|
1471
1525
|
persistChatFirstPane(pane);
|
|
1472
1526
|
},
|
|
1473
1527
|
[
|
|
1474
1528
|
chatFirstAppRegistrations,
|
|
1475
1529
|
chatFirstSurfaceTabsStore,
|
|
1476
1530
|
persistChatFirstPane,
|
|
1531
|
+
isChatRoute,
|
|
1532
|
+
navigate,
|
|
1533
|
+
setChatFirstSurfacePanelOpen,
|
|
1477
1534
|
],
|
|
1478
1535
|
);
|
|
1479
1536
|
const openChatFirstSurface = useCallback(
|
|
@@ -1512,7 +1569,7 @@ export function Layout({
|
|
|
1512
1569
|
);
|
|
1513
1570
|
const resolveChatFirstOpenApp = useCallback(
|
|
1514
1571
|
(detail: ChatFirstOpenAppDetail) => {
|
|
1515
|
-
if (chatFirstAppsQuery.isLoading) {
|
|
1572
|
+
if (chatFirstAppsQuery.isLoading || chatFirstGrantedAppsQuery.isLoading) {
|
|
1516
1573
|
pendingChatFirstOpenAppRef.current = detail;
|
|
1517
1574
|
return;
|
|
1518
1575
|
}
|
|
@@ -1543,11 +1600,10 @@ export function Layout({
|
|
|
1543
1600
|
chatFirstAppRegistrations,
|
|
1544
1601
|
chatFirstAppsQuery.isError,
|
|
1545
1602
|
chatFirstAppsQuery.isLoading,
|
|
1603
|
+
chatFirstGrantedAppsQuery.isLoading,
|
|
1546
1604
|
openChatFirstPane,
|
|
1547
1605
|
],
|
|
1548
1606
|
);
|
|
1549
|
-
const sidebarBeforeAppRef = useRef<boolean | null>(null);
|
|
1550
|
-
const sidebarAutoCollapsedRef = useRef(false);
|
|
1551
1607
|
const chatHomeHandoffActive = useAgentChatHomeHandoff({
|
|
1552
1608
|
storageKey: "dispatch",
|
|
1553
1609
|
activePath: localPathname,
|
|
@@ -1618,7 +1674,7 @@ export function Layout({
|
|
|
1618
1674
|
);
|
|
1619
1675
|
|
|
1620
1676
|
useEffect(() => {
|
|
1621
|
-
if (!chatFirstMode
|
|
1677
|
+
if (!chatFirstMode) {
|
|
1622
1678
|
setChatFirstPane(null);
|
|
1623
1679
|
closeChatFirstSessionWatch();
|
|
1624
1680
|
chatFirstSurfaceTabsStore.closeAll();
|
|
@@ -1721,7 +1777,7 @@ export function Layout({
|
|
|
1721
1777
|
useEffect(() => {
|
|
1722
1778
|
const tabCount = chatFirstSurfaceTabs.tabs.length;
|
|
1723
1779
|
const previousTabCount = previousChatFirstSurfaceTabCountRef.current;
|
|
1724
|
-
if (!chatFirstMode
|
|
1780
|
+
if (!chatFirstMode) {
|
|
1725
1781
|
setChatFirstSurfacePanelOpen(false);
|
|
1726
1782
|
} else if (
|
|
1727
1783
|
tabCount > 0 &&
|
|
@@ -1756,12 +1812,19 @@ export function Layout({
|
|
|
1756
1812
|
|
|
1757
1813
|
useEffect(() => {
|
|
1758
1814
|
const pending = pendingChatFirstOpenAppRef.current;
|
|
1759
|
-
if (
|
|
1815
|
+
if (
|
|
1816
|
+
!pending ||
|
|
1817
|
+
chatFirstAppsQuery.isLoading ||
|
|
1818
|
+
chatFirstGrantedAppsQuery.isLoading
|
|
1819
|
+
)
|
|
1820
|
+
return;
|
|
1760
1821
|
resolveChatFirstOpenApp(pending);
|
|
1761
1822
|
}, [
|
|
1762
1823
|
chatFirstAppsQuery.data,
|
|
1763
1824
|
chatFirstAppsQuery.isError,
|
|
1764
1825
|
chatFirstAppsQuery.isLoading,
|
|
1826
|
+
chatFirstGrantedAppsQuery.data,
|
|
1827
|
+
chatFirstGrantedAppsQuery.isLoading,
|
|
1765
1828
|
resolveChatFirstOpenApp,
|
|
1766
1829
|
]);
|
|
1767
1830
|
|
|
@@ -1782,28 +1845,6 @@ export function Layout({
|
|
|
1782
1845
|
isChatRoute,
|
|
1783
1846
|
]);
|
|
1784
1847
|
|
|
1785
|
-
useEffect(() => {
|
|
1786
|
-
if (isWorkspaceAppHostRoute) {
|
|
1787
|
-
if (!sidebarAutoCollapsedRef.current) {
|
|
1788
|
-
sidebarAutoCollapsedRef.current = true;
|
|
1789
|
-
sidebarBeforeAppRef.current = sidebarCollapsed;
|
|
1790
|
-
}
|
|
1791
|
-
if (!sidebarCollapsed) setSidebarCollapsed(true);
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
if (!sidebarAutoCollapsedRef.current) return;
|
|
1796
|
-
sidebarAutoCollapsedRef.current = false;
|
|
1797
|
-
const previousSidebarState = sidebarBeforeAppRef.current;
|
|
1798
|
-
sidebarBeforeAppRef.current = null;
|
|
1799
|
-
if (
|
|
1800
|
-
previousSidebarState !== null &&
|
|
1801
|
-
previousSidebarState !== sidebarCollapsed
|
|
1802
|
-
) {
|
|
1803
|
-
setSidebarCollapsed(previousSidebarState);
|
|
1804
|
-
}
|
|
1805
|
-
}, [isWorkspaceAppHostRoute, sidebarCollapsed]);
|
|
1806
|
-
|
|
1807
1848
|
useEffect(() => {
|
|
1808
1849
|
if (typeof window === "undefined" || isWorkspaceAppHostRoute) return;
|
|
1809
1850
|
try {
|
|
@@ -1900,11 +1941,17 @@ export function Layout({
|
|
|
1900
1941
|
(tab: ChatFirstSurfaceTab) => {
|
|
1901
1942
|
if (tab.kind === "app") {
|
|
1902
1943
|
if (tab.id !== chatFirstSurfaceTabs.activeTabId) return null;
|
|
1903
|
-
const
|
|
1904
|
-
? (
|
|
1944
|
+
const registration = tab.appId
|
|
1945
|
+
? (chatFirstAppRegistrations.find(
|
|
1905
1946
|
(candidate) => candidate.id === tab.appId,
|
|
1906
1947
|
) ?? null)
|
|
1907
1948
|
: null;
|
|
1949
|
+
const app = registration
|
|
1950
|
+
? {
|
|
1951
|
+
id: registration.id,
|
|
1952
|
+
name: registration.name ?? registration.id,
|
|
1953
|
+
}
|
|
1954
|
+
: null;
|
|
1908
1955
|
return (
|
|
1909
1956
|
<ChatFirstAppPane
|
|
1910
1957
|
app={app}
|
|
@@ -2007,7 +2054,7 @@ export function Layout({
|
|
|
2007
2054
|
chatFirstEmbedUrl,
|
|
2008
2055
|
chatFirstSessionWatch.target,
|
|
2009
2056
|
chatFirstSurfaceTabs.activeTabId,
|
|
2010
|
-
|
|
2057
|
+
chatFirstAppRegistrations,
|
|
2011
2058
|
closeChatFirstSurfaceTab,
|
|
2012
2059
|
renderChatFirstWatchChat,
|
|
2013
2060
|
],
|
|
@@ -2075,7 +2122,7 @@ export function Layout({
|
|
|
2075
2122
|
<main
|
|
2076
2123
|
className={cn(
|
|
2077
2124
|
"flex-1",
|
|
2078
|
-
isChatRoute ||
|
|
2125
|
+
isChatRoute || isWorkspaceAppRoute
|
|
2079
2126
|
? "min-h-0 overflow-hidden"
|
|
2080
2127
|
: "overflow-y-auto",
|
|
2081
2128
|
)}
|
|
@@ -2090,6 +2137,40 @@ export function Layout({
|
|
|
2090
2137
|
</main>
|
|
2091
2138
|
</div>
|
|
2092
2139
|
);
|
|
2140
|
+
const chatFirstSurfaceTabsBar =
|
|
2141
|
+
activeChatFirstSurfaceTab?.kind === "app" ? null : (
|
|
2142
|
+
<ChatFirstSurfaceTabs
|
|
2143
|
+
tabs={chatFirstSurfaceTabs.tabs}
|
|
2144
|
+
activeTabId={chatFirstSurfaceTabs.activeTabId}
|
|
2145
|
+
onActivate={activateChatFirstSurfaceTab}
|
|
2146
|
+
onClose={closeChatFirstSurfaceTab}
|
|
2147
|
+
onCloseOthers={(tab) => {
|
|
2148
|
+
activateChatFirstSurfaceTab(tab);
|
|
2149
|
+
chatFirstSurfaceTabsStore.closeOthers(tab.id);
|
|
2150
|
+
}}
|
|
2151
|
+
onCloseToRight={(tab) => {
|
|
2152
|
+
const targetIndex = chatFirstSurfaceTabs.tabs.findIndex(
|
|
2153
|
+
(candidate) => candidate.id === tab.id,
|
|
2154
|
+
);
|
|
2155
|
+
const activeIndex = chatFirstSurfaceTabs.tabs.findIndex(
|
|
2156
|
+
(candidate) => candidate.id === chatFirstSurfaceTabs.activeTabId,
|
|
2157
|
+
);
|
|
2158
|
+
if (activeIndex > targetIndex) activateChatFirstSurfaceTab(tab);
|
|
2159
|
+
chatFirstSurfaceTabsStore.closeToRight(tab.id);
|
|
2160
|
+
}}
|
|
2161
|
+
onCloseAll={closeAllChatFirstSurfaceTabs}
|
|
2162
|
+
onOpenSurface={openChatFirstSurface}
|
|
2163
|
+
copy={chatFirstCopy}
|
|
2164
|
+
/>
|
|
2165
|
+
);
|
|
2166
|
+
const chatFirstSurfaceContent =
|
|
2167
|
+
chatFirstSurfaceTabs.tabs.length > 0 ? (
|
|
2168
|
+
<ChatFirstSurfaceContent
|
|
2169
|
+
tabs={chatFirstSurfaceTabs.tabs}
|
|
2170
|
+
activeTabId={chatFirstSurfaceTabs.activeTabId}
|
|
2171
|
+
renderTab={renderChatFirstSurfaceTab}
|
|
2172
|
+
/>
|
|
2173
|
+
) : null;
|
|
2093
2174
|
const content = isChatRoute ? (
|
|
2094
2175
|
<div
|
|
2095
2176
|
className={cn(
|
|
@@ -2097,47 +2178,31 @@ export function Layout({
|
|
|
2097
2178
|
chatFirstMode && "dispatch-chat-first-surface",
|
|
2098
2179
|
)}
|
|
2099
2180
|
>
|
|
2100
|
-
{
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
onResizePointerDown={chatFirstSurfaceResize.onPointerDown}
|
|
2105
|
-
copy={chatFirstCopy}
|
|
2181
|
+
{chatFirstAppTakesMain ? (
|
|
2182
|
+
<div
|
|
2183
|
+
className="flex min-w-0 flex-1 flex-col overflow-hidden"
|
|
2184
|
+
data-dispatch-chat-first-main-app
|
|
2106
2185
|
>
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
(candidate) =>
|
|
2122
|
-
candidate.id === chatFirstSurfaceTabs.activeTabId,
|
|
2123
|
-
);
|
|
2124
|
-
if (activeIndex > targetIndex) activateChatFirstSurfaceTab(tab);
|
|
2125
|
-
chatFirstSurfaceTabsStore.closeToRight(tab.id);
|
|
2126
|
-
}}
|
|
2127
|
-
onCloseAll={closeAllChatFirstSurfaceTabs}
|
|
2128
|
-
onOpenSurface={openChatFirstSurface}
|
|
2129
|
-
copy={chatFirstCopy}
|
|
2130
|
-
/>
|
|
2131
|
-
{chatFirstSurfaceTabs.tabs.length > 0 ? (
|
|
2132
|
-
<ChatFirstSurfaceContent
|
|
2133
|
-
tabs={chatFirstSurfaceTabs.tabs}
|
|
2134
|
-
activeTabId={chatFirstSurfaceTabs.activeTabId}
|
|
2135
|
-
renderTab={renderChatFirstSurfaceTab}
|
|
2136
|
-
/>
|
|
2186
|
+
{chatFirstSurfaceContent}
|
|
2187
|
+
</div>
|
|
2188
|
+
) : (
|
|
2189
|
+
<>
|
|
2190
|
+
{appContent}
|
|
2191
|
+
{chatFirstMode && chatFirstSurfacePanel.open ? (
|
|
2192
|
+
<ChatFirstSurfacePanel
|
|
2193
|
+
width={chatFirstSurfaceResize.width}
|
|
2194
|
+
onResizePointerDown={chatFirstSurfaceResize.onPointerDown}
|
|
2195
|
+
copy={chatFirstCopy}
|
|
2196
|
+
>
|
|
2197
|
+
{chatFirstSurfaceTabsBar}
|
|
2198
|
+
{chatFirstSurfaceContent}
|
|
2199
|
+
</ChatFirstSurfacePanel>
|
|
2137
2200
|
) : null}
|
|
2138
|
-
|
|
2139
|
-
)
|
|
2201
|
+
</>
|
|
2202
|
+
)}
|
|
2140
2203
|
</div>
|
|
2204
|
+
) : isWorkspaceAppRoute ? (
|
|
2205
|
+
appContent
|
|
2141
2206
|
) : (
|
|
2142
2207
|
<AgentSidebar
|
|
2143
2208
|
position="right"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
-
import { IconStack2 } from "@tabler/icons-react";
|
|
3
2
|
|
|
4
3
|
import { filterOtherApps, type ConnectedAppSummary } from "../lib/other-apps";
|
|
5
4
|
import type { WorkspaceAppId } from "../lib/other-apps";
|
|
@@ -80,6 +79,8 @@ export function OtherAppsSection({
|
|
|
80
79
|
onRetryConnectedApps,
|
|
81
80
|
templateLabels,
|
|
82
81
|
onRemixSuccess,
|
|
82
|
+
heading = "Other apps",
|
|
83
|
+
embeddedInList = false,
|
|
83
84
|
className,
|
|
84
85
|
}: {
|
|
85
86
|
templates?: CuratedWorkspaceTemplatesResult;
|
|
@@ -96,6 +97,8 @@ export function OtherAppsSection({
|
|
|
96
97
|
result: unknown,
|
|
97
98
|
template: CuratedWorkspaceTemplate,
|
|
98
99
|
) => void;
|
|
100
|
+
heading?: string | null;
|
|
101
|
+
embeddedInList?: boolean;
|
|
99
102
|
className?: string;
|
|
100
103
|
}) {
|
|
101
104
|
const t = useT();
|
|
@@ -109,26 +112,15 @@ export function OtherAppsSection({
|
|
|
109
112
|
|
|
110
113
|
if (!isLoading && !hasError && entries.length === 0) return null;
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
size={16}
|
|
117
|
-
className="mt-0.5 shrink-0 text-muted-foreground"
|
|
118
|
-
/>
|
|
119
|
-
<div className="min-w-0">
|
|
115
|
+
const content = (
|
|
116
|
+
<>
|
|
117
|
+
{heading ? (
|
|
118
|
+
<div className="flex min-w-0 items-center">
|
|
120
119
|
<h2 className="truncate text-sm font-semibold text-foreground">
|
|
121
|
-
{t("dispatch.pages.otherApps", { defaultValue:
|
|
120
|
+
{t("dispatch.pages.otherApps", { defaultValue: heading })}
|
|
122
121
|
</h2>
|
|
123
|
-
{entries.length > 0 ? (
|
|
124
|
-
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
125
|
-
{t("dispatch.pages.availableCount", {
|
|
126
|
-
count: entries.length,
|
|
127
|
-
})}
|
|
128
|
-
</p>
|
|
129
|
-
) : null}
|
|
130
122
|
</div>
|
|
131
|
-
|
|
123
|
+
) : null}
|
|
132
124
|
|
|
133
125
|
{templatesError ? (
|
|
134
126
|
<ActionQueryError
|
|
@@ -144,31 +136,37 @@ export function OtherAppsSection({
|
|
|
144
136
|
) : null}
|
|
145
137
|
|
|
146
138
|
{isLoading && entries.length === 0 ? (
|
|
147
|
-
|
|
139
|
+
embeddedInList ? (
|
|
140
|
+
<OtherAppsSkeletonRows />
|
|
141
|
+
) : (
|
|
142
|
+
<OtherAppsSkeletonList />
|
|
143
|
+
)
|
|
148
144
|
) : entries.length > 0 ? (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)}
|
|
168
|
-
</AppList>
|
|
145
|
+
entries.map((entry) =>
|
|
146
|
+
entry.kind === "template" ? (
|
|
147
|
+
<WorkspaceTemplateCard
|
|
148
|
+
key={`template:${templateKey(entry.template)}`}
|
|
149
|
+
template={entry.template}
|
|
150
|
+
labels={templateLabels}
|
|
151
|
+
catalog
|
|
152
|
+
className={APP_LIST_GRID_ROW_CLASS}
|
|
153
|
+
onRemixSuccess={onRemixSuccess}
|
|
154
|
+
/>
|
|
155
|
+
) : (
|
|
156
|
+
<ConnectedAppCard
|
|
157
|
+
key={`connected:${entry.app.id}`}
|
|
158
|
+
app={entry.app}
|
|
159
|
+
className={APP_LIST_GRID_ROW_CLASS}
|
|
160
|
+
/>
|
|
161
|
+
),
|
|
162
|
+
)
|
|
169
163
|
) : null}
|
|
170
|
-
|
|
164
|
+
</>
|
|
171
165
|
);
|
|
166
|
+
|
|
167
|
+
if (embeddedInList) return content;
|
|
168
|
+
|
|
169
|
+
return <section className={cn("space-y-3", className)}>{content}</section>;
|
|
172
170
|
}
|
|
173
171
|
|
|
174
172
|
function OtherAppsSkeletonList() {
|
|
@@ -193,3 +191,26 @@ function OtherAppsSkeletonList() {
|
|
|
193
191
|
</AppList>
|
|
194
192
|
);
|
|
195
193
|
}
|
|
194
|
+
|
|
195
|
+
function OtherAppsSkeletonRows() {
|
|
196
|
+
return (
|
|
197
|
+
<>
|
|
198
|
+
{Array.from({ length: 4 }).map((_, index) => (
|
|
199
|
+
<div
|
|
200
|
+
key={index}
|
|
201
|
+
className={cn(
|
|
202
|
+
"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0",
|
|
203
|
+
APP_LIST_GRID_ROW_CLASS,
|
|
204
|
+
)}
|
|
205
|
+
>
|
|
206
|
+
<Skeleton className="size-8 shrink-0 rounded-xl" />
|
|
207
|
+
<div className="min-w-0 flex-1 space-y-2">
|
|
208
|
+
<Skeleton className="h-4 w-32" />
|
|
209
|
+
<Skeleton className="h-3 w-2/3" />
|
|
210
|
+
</div>
|
|
211
|
+
<Skeleton className="h-9 w-24 shrink-0 rounded-md" />
|
|
212
|
+
</div>
|
|
213
|
+
))}
|
|
214
|
+
</>
|
|
215
|
+
);
|
|
216
|
+
}
|