@agent-native/dispatch 0.31.17 → 0.31.18-nightly-20260825123905
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/dispatch-control-plane.d.ts.map +1 -1
- package/dist/components/dispatch-control-plane.js +17 -7
- package/dist/components/dispatch-control-plane.js.map +1 -1
- package/dist/routes/pages/apps.js +14 -10
- package/dist/routes/pages/apps.js.map +1 -1
- package/package.json +3 -3
- package/src/components/dispatch-control-plane.spec.tsx +68 -0
- package/src/components/dispatch-control-plane.tsx +40 -24
- package/src/routes/pages/apps.tsx +22 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-control-plane.d.ts","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-control-plane.d.ts","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":"AAwYA,wBAAgB,oBAAoB,oDAwCnC"}
|
|
@@ -13,7 +13,7 @@ import { ActionQueryError } from "./action-query-error.js";
|
|
|
13
13
|
import { APP_LIST_GRID_CLASS, AppList, APP_LIST_GRID_ROW_CLASS, } from "./app-list-row.js";
|
|
14
14
|
import { CreateAppPopover } from "./create-app-popover.js";
|
|
15
15
|
import { useSetPageTitle } from "./layout/HeaderActions.js";
|
|
16
|
-
import { mergeOtherAppEntries, OtherAppsSection } from "./other-apps-section.js";
|
|
16
|
+
import { filterOtherAppEntries, mergeOtherAppEntries, OtherAppsSection, } from "./other-apps-section.js";
|
|
17
17
|
import { Button } from "./ui/button.js";
|
|
18
18
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "./ui/collapsible.js";
|
|
19
19
|
import { Skeleton } from "./ui/skeleton.js";
|
|
@@ -70,20 +70,30 @@ function AppsPanel({ apps, isLoading, connectedApps, connectedAppsError, connect
|
|
|
70
70
|
const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);
|
|
71
71
|
const filteredActiveApps = orderedActiveApps.filter((app) => workspaceAppMatchesQuery(app, searchQuery));
|
|
72
72
|
const filteredPendingApps = orderedPendingApps.filter((app) => workspaceAppMatchesQuery(app, searchQuery));
|
|
73
|
-
const
|
|
74
|
-
const otherAppEntries = mergeOtherAppEntries({
|
|
73
|
+
const otherAppEntries = filterOtherAppEntries(mergeOtherAppEntries({
|
|
75
74
|
templates: curatedTemplates,
|
|
76
75
|
connectedApps,
|
|
77
76
|
workspaceApps: apps,
|
|
78
|
-
});
|
|
77
|
+
}), searchQuery);
|
|
78
|
+
const hasSearchResults = filteredActiveApps.length > 0 ||
|
|
79
|
+
filteredPendingApps.length > 0 ||
|
|
80
|
+
otherAppEntries.length > 0;
|
|
81
|
+
const otherAppsLoading = curatedTemplatesLoading || connectedAppsLoading;
|
|
82
|
+
const otherAppsError = curatedTemplatesError || connectedAppsError;
|
|
79
83
|
const showSkeletons = isLoading && activeApps.length === 0 && pendingApps.length === 0;
|
|
80
|
-
return (_jsxs("section", { className: "mx-auto flex w-full max-w-[1000px] flex-col gap-3", children: [_jsx(SectionHeader, { title: "Apps", action: _jsxs("div", { className: "flex min-w-0 flex-wrap items-center justify-end gap-1.5", children: [_jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: _jsx(Link, { to: "/apps", className: "text-muted-foreground", children: "View all" }) }), !showSkeletons &&
|
|
84
|
+
return (_jsxs("section", { className: "mx-auto flex w-full max-w-[1000px] flex-col gap-3", children: [_jsx(SectionHeader, { title: "Apps", action: _jsxs("div", { className: "flex min-w-0 flex-wrap items-center justify-end gap-1.5", children: [_jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: _jsx(Link, { to: "/apps", className: "text-muted-foreground", children: "View all" }) }), !showSkeletons &&
|
|
85
|
+
(visibleApps.length > 0 ||
|
|
86
|
+
otherAppEntries.length > 0 ||
|
|
87
|
+
Boolean(searchQuery.trim())) ? (_jsx(WorkspaceAppSearch, { className: "w-[220px]", query: searchQuery, onQueryChange: setSearchQuery })) : null, _jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { variant: "default", size: "sm", className: "gap-1.5", children: [_jsx(IconPlus, { size: 14 }), t("dispatch.pages.newApp", { defaultValue: "New" })] }) })] }) }), !showSkeletons && visibleApps.length > 0 && persistenceError ? (_jsx("p", { className: "text-xs text-muted-foreground", role: "status", children: persistenceError === "both"
|
|
81
88
|
? t("dispatch.pages.appPinSaveFailed", {
|
|
82
89
|
defaultValue: "App pins could not be saved.",
|
|
83
90
|
})
|
|
84
91
|
: t("dispatch.pages.appPinSavedLocally", {
|
|
85
92
|
defaultValue: "App pins are saved on this device only.",
|
|
86
|
-
}) })) : null, showSkeletons ? (_jsx(OverviewAppsSkeleton, {})) : searchQuery.trim() &&
|
|
93
|
+
}) })) : null, showSkeletons ? (_jsx(OverviewAppsSkeleton, {})) : searchQuery.trim() &&
|
|
94
|
+
!hasSearchResults &&
|
|
95
|
+
!otherAppsLoading &&
|
|
96
|
+
!otherAppsError ? (_jsx(WorkspaceAppSearchEmpty, { query: searchQuery, onClear: () => setSearchQuery("") })) : (_jsx(_Fragment, { children: _jsxs(AppList, { className: APP_LIST_GRID_CLASS, children: [filteredActiveApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: APP_LIST_GRID_ROW_CLASS, isPinned: layout.pinnedIds.includes(app.id), onTogglePinned: () => togglePinned(app.id) }, app.id))), filteredActiveApps.length === 0 &&
|
|
87
97
|
!searchQuery.trim() &&
|
|
88
98
|
otherAppEntries.length === 0 &&
|
|
89
99
|
!curatedTemplatesLoading &&
|
|
@@ -91,7 +101,7 @@ function AppsPanel({ apps, isLoading, connectedApps, connectedAppsError, connect
|
|
|
91
101
|
!curatedTemplatesError &&
|
|
92
102
|
!connectedAppsError ? (_jsx("p", { className: "px-4 py-3 text-sm text-muted-foreground", children: t("dispatch.pages.noApps", {
|
|
93
103
|
defaultValue: "No apps yet.",
|
|
94
|
-
}) })) : null,
|
|
104
|
+
}) })) : null, _jsx(OtherAppsSection, { templates: curatedTemplates, connectedApps: connectedApps, workspaceApps: apps, templatesLoading: curatedTemplatesLoading, connectedAppsLoading: connectedAppsLoading, templatesError: curatedTemplatesError, connectedAppsError: connectedAppsError, query: searchQuery, onRetryTemplates: onRetryCuratedTemplates, onRetryConnectedApps: onRetryConnectedApps, heading: null, embeddedInList: true })] }) })), pendingApps.length > 0 &&
|
|
95
105
|
(!searchQuery.trim() || filteredPendingApps.length > 0) ? (_jsx(Collapsible, { open: showPending || Boolean(searchQuery.trim()), onOpenChange: setShowPending, children: _jsxs("div", { className: "space-y-3 border-t pt-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconClockHour4, { size: 15, className: "shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "text-xs font-semibold text-foreground", children: t("dispatch.pages.pendingApps") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.pendingAppsDescription", {
|
|
96
106
|
count: pendingApps.length,
|
|
97
107
|
}) })] })] }), _jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 gap-1.5 px-2 text-xs", children: [showPending || Boolean(searchQuery.trim())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-control-plane.js","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,4BAA4B,EAC5B,mCAAmC,EACnC,aAAa,GACd,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,uCAAuC,GAExC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,mBAAmB,EACnB,OAAO,EACP,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAGhC,SAAS,aAAa,CAAC,EACrB,KAAK,EACL,MAAM,GAIP;IACC,OAAO,CACL,eAAK,SAAS,EAAC,iDAAiD,aAC9D,aAAI,SAAS,EAAC,gDAAgD,YAC3D,KAAK,GACH,EACJ,MAAM,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,UAAU,YAAE,MAAM,GAAO,CAAC,CAAC,CAAC,IAAI,IACrD,CACP,CAAC;AACJ,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EACJ,eAAe,EACf,SAAS,EAAE,gBAAgB,EAC3B,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,GACd,GAAG,aAAa,CAAC,EAAE,UAAU,EAAE,4BAA4B,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,iBAAiB,GAAG;QACxB,CAAC,CAAC,wCAAwC,EAAE;YAC1C,YAAY,EAAE,uCAAuC;SACtD,CAAC;QACF,CAAC,CAAC,0CAA0C,EAAE;YAC5C,YAAY,EAAE,4CAA4C;SAC3D,CAAC;KACH,CAAC;IAEF,SAAS,IAAI,CAAC,OAAe;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,mCAAmC,CAAC,QAAQ,EAAE,OAAO,EAAE;YACrD,KAAK,EAAE;gBACL,cAAc,EAAE;oBACd,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;oBAC7D,OAAO,EAAE,OAAO;oBAChB,aAAa;oBACb,cAAc;oBACd,cAAc;iBACf;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CACL,kBAAS,SAAS,EAAC,eAAe,YAChC,eAAK,SAAS,EAAC,yDAAyD,aACtE,eAAK,SAAS,EAAC,kBAAkB,aAC/B,aAAI,SAAS,EAAC,mEAAmE,YAC9E,CAAC,CAAC,+BAA+B,EAAE;gCAClC,YAAY,EAAE,uBAAuB;6BACtC,CAAC,GACC,EACL,YAAG,SAAS,EAAC,+DAA+D,YACzE,CAAC,CAAC,0CAA0C,EAAE;gCAC7C,YAAY,EACV,qEAAqE;6BACxE,CAAC,GACA,IACA,EACN,KAAC,cAAc,IACb,eAAe,EAAE,eAAe,EAChC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,CAAC,CAAC,0CAA0C,EAAE;wBACzD,YAAY,EAAE,0BAA0B;qBACzC,CAAC,EACF,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAC,SAAS,EACvB,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAC9B,EACF,cAAK,SAAS,EAAC,0CAA0C,YACtD,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CACrC,iBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAC/B,SAAS,EAAC,sLAAsL,YAE/L,UAAU,IALN,UAAU,CAMR,CACV,CAAC,GACE,IACF,GACE,CACX,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,EACjB,IAAI,EACJ,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,GAYxB;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAC3E,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,EAAE,CAAC,uCAAuC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CACvE,CAAC;IACF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAC1E,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC1D,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5D,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,MAAM,gBAAgB,GACpB,kBAAkB,CAAC,MAAM,GAAG,CAAC,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;IAClE,MAAM,eAAe,GAAG,oBAAoB,CAAC;QAC3C,SAAS,EAAE,gBAAgB;QAC3B,aAAa;QACb,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;IACH,MAAM,aAAa,GACjB,SAAS,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC;IAEnE,OAAO,CACL,mBAAS,SAAS,EAAC,mDAAmD,aACpE,KAAC,aAAa,IACZ,KAAK,EAAC,MAAM,EACZ,MAAM,EACJ,eAAK,SAAS,EAAC,yDAAyD,aACtE,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,kBACvC,KAAC,IAAI,IAAC,EAAE,EAAC,OAAO,EAAC,SAAS,EAAC,uBAAuB,yBAE3C,GACA,EACR,CAAC,aAAa,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1C,KAAC,kBAAkB,IACjB,SAAS,EAAC,WAAW,EACrB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,cAAc,GAC7B,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,gBAAgB,IACf,KAAK,EAAC,KAAK,EACX,OAAO,EACL,MAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,SAAS,aACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,GAAI,EACrB,CAAC,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,IAC7C,GAEX,IACE,GAER,EACD,CAAC,aAAa,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAC9D,YAAG,SAAS,EAAC,+BAA+B,EAAC,IAAI,EAAC,QAAQ,YACvD,gBAAgB,KAAK,MAAM;oBAC1B,CAAC,CAAC,CAAC,CAAC,iCAAiC,EAAE;wBACnC,YAAY,EAAE,8BAA8B;qBAC7C,CAAC;oBACJ,CAAC,CAAC,CAAC,CAAC,mCAAmC,EAAE;wBACrC,YAAY,EAAE,yCAAyC;qBACxD,CAAC,GACJ,CACL,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,oBAAoB,KAAG,CACzB,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAC5C,KAAC,uBAAuB,IACtB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,GACjC,CACH,CAAC,CAAC,CAAC,CACF,4BACE,MAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,aACpC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC/B,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,EAClC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAC3C,cAAc,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAJrC,GAAG,CAAC,EAAE,CAKX,CACH,CAAC,EACD,kBAAkB,CAAC,MAAM,KAAK,CAAC;4BAChC,CAAC,WAAW,CAAC,IAAI,EAAE;4BACnB,eAAe,CAAC,MAAM,KAAK,CAAC;4BAC5B,CAAC,uBAAuB;4BACxB,CAAC,oBAAoB;4BACrB,CAAC,qBAAqB;4BACtB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CACpB,YAAG,SAAS,EAAC,yCAAyC,YACnD,CAAC,CAAC,uBAAuB,EAAE;gCAC1B,YAAY,EAAE,cAAc;6BAC7B,CAAC,GACA,CACL,CAAC,CAAC,CAAC,IAAI,EACP,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CACrB,KAAC,gBAAgB,IACf,SAAS,EAAE,gBAAgB,EAC3B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,IAAI,EACnB,gBAAgB,EAAE,uBAAuB,EACzC,oBAAoB,EAAE,oBAAoB,EAC1C,cAAc,EAAE,qBAAqB,EACrC,kBAAkB,EAAE,kBAAkB,EACtC,gBAAgB,EAAE,uBAAuB,EACzC,oBAAoB,EAAE,oBAAoB,EAC1C,OAAO,EAAE,IAAI,EACb,cAAc,SACd,CACH,CAAC,CAAC,CAAC,IAAI,IACA,GACT,CACJ,EACA,WAAW,CAAC,MAAM,GAAG,CAAC;gBACvB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CACxD,KAAC,WAAW,IACV,IAAI,EAAE,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAChD,YAAY,EAAE,cAAc,YAE5B,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,cAAc,IACb,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,uCAAuC,YAClD,CAAC,CAAC,4BAA4B,CAAC,GAC7B,EACL,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,uCAAuC,EAAE;wDAC1C,KAAK,EAAE,WAAW,CAAC,MAAM;qDAC1B,CAAC,GACA,IACA,IACF,EACN,KAAC,kBAAkB,IAAC,OAAO,kBACzB,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,0BAA0B,aAEnC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;gDACzC,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC;gDACrC,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,EACvC,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,SAAS,EACP,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE;oDAC/B,CAAC,CAAC,YAAY;oDACd,CAAC,CAAC,SAAS,GAEf,IACK,GACU,IACjB,EACN,KAAC,kBAAkB,cACjB,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,mBAAmB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAChC,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,GACS,IACjB,GACM,CACf,CAAC,CAAC,CAAC,IAAI,IACA,CACX,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,CACL,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3C,eAEE,SAAS,EAAE,EAAE,CACX,sEAAsE,EACtE,uBAAuB,CACxB,aAED,KAAC,QAAQ,IAAC,SAAS,EAAC,4BAA4B,GAAG,EACnD,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,EACN,KAAC,QAAQ,IAAC,SAAS,EAAC,8BAA8B,GAAG,KAXhD,KAAK,CAYN,CACP,CAAC,GACM,CACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,eAAe,CAAC,qCAAoB,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,cAAc,CAC9B,qBAAqB,EACrB,EAAE,iBAAiB,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,CACpD,CAAC;IACF,MAAM,kBAAkB,GAAG,cAAc,CACvC,uBAAuB,EACvB,EAAE,CACH,CAAC;IACF,MAAM,qBAAqB,GAAG,cAAc,CAC1C,kCAAkC,EAClC,EAAE,CACH,CAAC;IACF,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IAEvE,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,YAAY,KAAG,EACf,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CACnB,KAAC,gBAAgB,IACf,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,OAAO,EAAE,GACvC,CACH,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IACR,IAAI,EAAE,aAAa,IAAI,EAAE,EACzB,SAAS,EAAE,WAAW,EACtB,aAAa,EAAE,kBAAkB,CAAC,IAAI,IAAI,EAAE,EAC5C,kBAAkB,EAAE,kBAAkB,CAAC,KAAK,EAC5C,oBAAoB,EAAE,kBAAkB,CAAC,SAAS,EAClD,oBAAoB,EAAE,GAAG,EAAE,CAAC,KAAK,kBAAkB,CAAC,OAAO,EAAE,EAC7D,gBAAgB,EAAE,qBAAqB,CAAC,IAAI,EAC5C,qBAAqB,EAAE,qBAAqB,CAAC,KAAK,EAClD,uBAAuB,EAAE,qBAAqB,CAAC,SAAS,EACxD,uBAAuB,EAAE,GAAG,EAAE,CAAC,KAAK,qBAAqB,CAAC,OAAO,EAAE,GACnE,CACH,IACG,CACP,CAAC;AACJ,CAAC","sourcesContent":["import {\n chatModelSelectionStorageKey,\n navigateWithAgentChatViewTransition,\n useChatModels,\n} from \"@agent-native/core/client/agent-chat\";\nimport { PromptComposer } from \"@agent-native/core/client/composer\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconChevronDown, IconClockHour4, IconPlus } from \"@tabler/icons-react\";\nimport type { ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { Link, useNavigate } from \"react-router\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport { cn } from \"../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n AppList,\n APP_LIST_GRID_ROW_CLASS,\n} from \"./app-list-row\";\nimport { CreateAppPopover } from \"./create-app-popover\";\nimport { useSetPageTitle } from \"./layout/HeaderActions\";\nimport { mergeOtherAppEntries, OtherAppsSection } from \"./other-apps-section\";\nimport { Button } from \"./ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"./ui/collapsible\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { WorkspaceAppCard } from \"./workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"./workspace-app-search\";\nimport type { CuratedWorkspaceTemplatesResult } from \"./workspace-template-card\";\n\nfunction SectionHeader({\n title,\n action,\n}: {\n title: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex min-w-0 items-center justify-between gap-3\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {title}\n </h2>\n {action ? <div className=\"shrink-0\">{action}</div> : null}\n </div>\n );\n}\n\nfunction CommandPanel() {\n const t = useT();\n const {\n availableModels,\n isLoading: modelListLoading,\n onEffortChange,\n onModelChange,\n selectedEffort,\n selectedEngine,\n selectedModel,\n } = useChatModels({ storageKey: chatModelSelectionStorageKey(\"dispatch\") });\n const navigate = useNavigate();\n const promptSuggestions = [\n t(\"dispatch.pages.suggestionOnboardingApp\", {\n defaultValue: \"Create an app for onboarding requests\",\n }),\n t(\"dispatch.pages.suggestionAnalyticsAgents\", {\n defaultValue: \"Check which agents can help with analytics\",\n }),\n ];\n\n function send(message: string) {\n const trimmed = message.trim();\n if (!trimmed) return;\n\n navigateWithAgentChatViewTransition(navigate, \"/chat\", {\n state: {\n dispatchPrompt: {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n message: trimmed,\n selectedModel,\n selectedEngine,\n selectedEffort,\n },\n },\n });\n }\n\n return (\n <section className=\"flex flex-col\">\n <div className=\"mx-auto flex w-full max-w-[750px] flex-col pt-4 sm:pt-6\">\n <div className=\"mb-5 text-center\">\n <h2 className=\"text-2xl font-semibold tracking-tight text-foreground sm:text-3xl\">\n {t(\"dispatch.pages.chatAcrossApps\", {\n defaultValue: \"Chat across your apps\",\n })}\n </h2>\n <p className=\"mx-auto mt-2 max-w-xl text-sm leading-6 text-muted-foreground\">\n {t(\"dispatch.pages.chatAcrossAppsDescription\", {\n defaultValue:\n \"Route work, inspect status, or create something new from one place.\",\n })}\n </p>\n </div>\n <PromptComposer\n availableModels={availableModels}\n modelListLoading={modelListLoading}\n placeholder={t(\"dispatch.pages.overviewPromptPlaceholder\", {\n defaultValue: \"Ask Dispatch anything...\",\n })}\n selectedEffort={selectedEffort}\n selectedEngine={selectedEngine}\n selectedModel={selectedModel}\n rootClassName=\"bg-card\"\n onEffortChange={onEffortChange}\n onModelChange={onModelChange}\n onSubmit={(text) => send(text)}\n />\n <div className=\"mt-3 flex flex-wrap justify-center gap-2\">\n {promptSuggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => send(suggestion)}\n className=\"cursor-pointer rounded-md border border-transparent bg-muted/60 px-2.5 py-1.5 text-xs text-muted-foreground transition-[background-color,color] hover:bg-muted hover:text-foreground\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\nfunction AppsPanel({\n apps,\n isLoading,\n connectedApps,\n connectedAppsError,\n connectedAppsLoading,\n onRetryConnectedApps,\n curatedTemplates,\n curatedTemplatesError,\n curatedTemplatesLoading,\n onRetryCuratedTemplates,\n}: {\n apps: WorkspaceAppSummary[];\n isLoading: boolean;\n connectedApps: ConnectedAppSummary[];\n connectedAppsError?: Error | null;\n connectedAppsLoading: boolean;\n onRetryConnectedApps: () => void;\n curatedTemplates?: CuratedWorkspaceTemplatesResult;\n curatedTemplatesError?: Error | null;\n curatedTemplatesLoading: boolean;\n onRetryCuratedTemplates: () => void;\n}) {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const visibleApps = apps.filter(\n (app) => isWorkspaceAppVisibleInDefaultLaunchers(app) && !app.archived,\n );\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 || filteredPendingApps.length > 0;\n const otherAppEntries = mergeOtherAppEntries({\n templates: curatedTemplates,\n connectedApps,\n workspaceApps: apps,\n });\n const showSkeletons =\n isLoading && activeApps.length === 0 && pendingApps.length === 0;\n\n return (\n <section className=\"mx-auto flex w-full max-w-[1000px] flex-col gap-3\">\n <SectionHeader\n title=\"Apps\"\n action={\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-1.5\">\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link to=\"/apps\" className=\"text-muted-foreground\">\n View all\n </Link>\n </Button>\n {!showSkeletons && visibleApps.length > 0 ? (\n <WorkspaceAppSearch\n className=\"w-[220px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button variant=\"default\" size=\"sm\" className=\"gap-1.5\">\n <IconPlus size={14} />\n {t(\"dispatch.pages.newApp\", { defaultValue: \"New\" })}\n </Button>\n }\n />\n </div>\n }\n />\n {!showSkeletons && visibleApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n {showSkeletons ? (\n <OverviewAppsSkeleton />\n ) : searchQuery.trim() && !hasSearchResults ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : (\n <>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id)}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n {filteredActiveApps.length === 0 &&\n !searchQuery.trim() &&\n otherAppEntries.length === 0 &&\n !curatedTemplatesLoading &&\n !connectedAppsLoading &&\n !curatedTemplatesError &&\n !connectedAppsError ? (\n <p className=\"px-4 py-3 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noApps\", {\n defaultValue: \"No apps yet.\",\n })}\n </p>\n ) : null}\n {!searchQuery.trim() ? (\n <OtherAppsSection\n templates={curatedTemplates}\n connectedApps={connectedApps}\n workspaceApps={apps}\n templatesLoading={curatedTemplatesLoading}\n connectedAppsLoading={connectedAppsLoading}\n templatesError={curatedTemplatesError}\n connectedAppsError={connectedAppsError}\n onRetryTemplates={onRetryCuratedTemplates}\n onRetryConnectedApps={onRetryConnectedApps}\n heading={null}\n embeddedInList\n />\n ) : null}\n </AppList>\n </>\n )}\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <div className=\"space-y-3 border-t pt-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={15}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h3 className=\"text-xs font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingAppsDescription\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 gap-1.5 px-2 text-xs\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={13}\n className={\n showPending || searchQuery.trim()\n ? \"rotate-180\"\n : undefined\n }\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </div>\n </Collapsible>\n ) : null}\n </section>\n );\n}\n\nfunction OverviewAppsSkeleton() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nexport function DispatchControlPlane() {\n useSetPageTitle(<span aria-hidden />);\n const appsQuery = useActionQuery<WorkspaceAppSummary[]>(\n \"list-workspace-apps\",\n { includeAgentCards: false, includeArchived: true },\n );\n const connectedAppsQuery = useActionQuery<ConnectedAppSummary[]>(\n \"list-connected-agents\",\n {},\n );\n const curatedTemplatesQuery = useActionQuery<CuratedWorkspaceTemplatesResult>(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: workspaceApps = [], isLoading: appsLoading } = appsQuery;\n\n return (\n <div className=\"flex flex-col gap-8\">\n <CommandPanel />\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : (\n <AppsPanel\n apps={workspaceApps ?? []}\n isLoading={appsLoading}\n connectedApps={connectedAppsQuery.data ?? []}\n connectedAppsError={connectedAppsQuery.error}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n curatedTemplates={curatedTemplatesQuery.data}\n curatedTemplatesError={curatedTemplatesQuery.error}\n curatedTemplatesLoading={curatedTemplatesQuery.isLoading}\n onRetryCuratedTemplates={() => void curatedTemplatesQuery.refetch()}\n />\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dispatch-control-plane.js","sourceRoot":"","sources":["../../src/components/dispatch-control-plane.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n chatModelSelectionStorageKey,\n navigateWithAgentChatViewTransition,\n useChatModels,\n} from \"@agent-native/core/client/agent-chat\";\nimport { PromptComposer } from \"@agent-native/core/client/composer\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconChevronDown, IconClockHour4, IconPlus } from \"@tabler/icons-react\";\nimport type { ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { Link, useNavigate } from \"react-router\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport { cn } from \"../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n AppList,\n APP_LIST_GRID_ROW_CLASS,\n} from \"./app-list-row\";\nimport { CreateAppPopover } from \"./create-app-popover\";\nimport { useSetPageTitle } from \"./layout/HeaderActions\";\nimport {\n filterOtherAppEntries,\n mergeOtherAppEntries,\n OtherAppsSection,\n} from \"./other-apps-section\";\nimport { Button } from \"./ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"./ui/collapsible\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { WorkspaceAppCard } from \"./workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"./workspace-app-search\";\nimport type { CuratedWorkspaceTemplatesResult } from \"./workspace-template-card\";\n\nfunction SectionHeader({\n title,\n action,\n}: {\n title: string;\n action?: ReactNode;\n}) {\n return (\n <div className=\"flex min-w-0 items-center justify-between gap-3\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {title}\n </h2>\n {action ? <div className=\"shrink-0\">{action}</div> : null}\n </div>\n );\n}\n\nfunction CommandPanel() {\n const t = useT();\n const {\n availableModels,\n isLoading: modelListLoading,\n onEffortChange,\n onModelChange,\n selectedEffort,\n selectedEngine,\n selectedModel,\n } = useChatModels({ storageKey: chatModelSelectionStorageKey(\"dispatch\") });\n const navigate = useNavigate();\n const promptSuggestions = [\n t(\"dispatch.pages.suggestionOnboardingApp\", {\n defaultValue: \"Create an app for onboarding requests\",\n }),\n t(\"dispatch.pages.suggestionAnalyticsAgents\", {\n defaultValue: \"Check which agents can help with analytics\",\n }),\n ];\n\n function send(message: string) {\n const trimmed = message.trim();\n if (!trimmed) return;\n\n navigateWithAgentChatViewTransition(navigate, \"/chat\", {\n state: {\n dispatchPrompt: {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n message: trimmed,\n selectedModel,\n selectedEngine,\n selectedEffort,\n },\n },\n });\n }\n\n return (\n <section className=\"flex flex-col\">\n <div className=\"mx-auto flex w-full max-w-[750px] flex-col pt-4 sm:pt-6\">\n <div className=\"mb-5 text-center\">\n <h2 className=\"text-2xl font-semibold tracking-tight text-foreground sm:text-3xl\">\n {t(\"dispatch.pages.chatAcrossApps\", {\n defaultValue: \"Chat across your apps\",\n })}\n </h2>\n <p className=\"mx-auto mt-2 max-w-xl text-sm leading-6 text-muted-foreground\">\n {t(\"dispatch.pages.chatAcrossAppsDescription\", {\n defaultValue:\n \"Route work, inspect status, or create something new from one place.\",\n })}\n </p>\n </div>\n <PromptComposer\n availableModels={availableModels}\n modelListLoading={modelListLoading}\n placeholder={t(\"dispatch.pages.overviewPromptPlaceholder\", {\n defaultValue: \"Ask Dispatch anything...\",\n })}\n selectedEffort={selectedEffort}\n selectedEngine={selectedEngine}\n selectedModel={selectedModel}\n rootClassName=\"bg-card\"\n onEffortChange={onEffortChange}\n onModelChange={onModelChange}\n onSubmit={(text) => send(text)}\n />\n <div className=\"mt-3 flex flex-wrap justify-center gap-2\">\n {promptSuggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => send(suggestion)}\n className=\"cursor-pointer rounded-md border border-transparent bg-muted/60 px-2.5 py-1.5 text-xs text-muted-foreground transition-[background-color,color] hover:bg-muted hover:text-foreground\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\nfunction AppsPanel({\n apps,\n isLoading,\n connectedApps,\n connectedAppsError,\n connectedAppsLoading,\n onRetryConnectedApps,\n curatedTemplates,\n curatedTemplatesError,\n curatedTemplatesLoading,\n onRetryCuratedTemplates,\n}: {\n apps: WorkspaceAppSummary[];\n isLoading: boolean;\n connectedApps: ConnectedAppSummary[];\n connectedAppsError?: Error | null;\n connectedAppsLoading: boolean;\n onRetryConnectedApps: () => void;\n curatedTemplates?: CuratedWorkspaceTemplatesResult;\n curatedTemplatesError?: Error | null;\n curatedTemplatesLoading: boolean;\n onRetryCuratedTemplates: () => void;\n}) {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const visibleApps = apps.filter(\n (app) => isWorkspaceAppVisibleInDefaultLaunchers(app) && !app.archived,\n );\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const otherAppEntries = filterOtherAppEntries(\n mergeOtherAppEntries({\n templates: curatedTemplates,\n connectedApps,\n workspaceApps: apps,\n }),\n searchQuery,\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n otherAppEntries.length > 0;\n const otherAppsLoading = curatedTemplatesLoading || connectedAppsLoading;\n const otherAppsError = curatedTemplatesError || connectedAppsError;\n const showSkeletons =\n isLoading && activeApps.length === 0 && pendingApps.length === 0;\n\n return (\n <section className=\"mx-auto flex w-full max-w-[1000px] flex-col gap-3\">\n <SectionHeader\n title=\"Apps\"\n action={\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-1.5\">\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link to=\"/apps\" className=\"text-muted-foreground\">\n View all\n </Link>\n </Button>\n {!showSkeletons &&\n (visibleApps.length > 0 ||\n otherAppEntries.length > 0 ||\n Boolean(searchQuery.trim())) ? (\n <WorkspaceAppSearch\n className=\"w-[220px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button variant=\"default\" size=\"sm\" className=\"gap-1.5\">\n <IconPlus size={14} />\n {t(\"dispatch.pages.newApp\", { defaultValue: \"New\" })}\n </Button>\n }\n />\n </div>\n }\n />\n {!showSkeletons && visibleApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n {showSkeletons ? (\n <OverviewAppsSkeleton />\n ) : searchQuery.trim() &&\n !hasSearchResults &&\n !otherAppsLoading &&\n !otherAppsError ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : (\n <>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id)}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n {filteredActiveApps.length === 0 &&\n !searchQuery.trim() &&\n otherAppEntries.length === 0 &&\n !curatedTemplatesLoading &&\n !connectedAppsLoading &&\n !curatedTemplatesError &&\n !connectedAppsError ? (\n <p className=\"px-4 py-3 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noApps\", {\n defaultValue: \"No apps yet.\",\n })}\n </p>\n ) : null}\n <OtherAppsSection\n templates={curatedTemplates}\n connectedApps={connectedApps}\n workspaceApps={apps}\n templatesLoading={curatedTemplatesLoading}\n connectedAppsLoading={connectedAppsLoading}\n templatesError={curatedTemplatesError}\n connectedAppsError={connectedAppsError}\n query={searchQuery}\n onRetryTemplates={onRetryCuratedTemplates}\n onRetryConnectedApps={onRetryConnectedApps}\n heading={null}\n embeddedInList\n />\n </AppList>\n </>\n )}\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <div className=\"space-y-3 border-t pt-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={15}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h3 className=\"text-xs font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingAppsDescription\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 gap-1.5 px-2 text-xs\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={13}\n className={\n showPending || searchQuery.trim()\n ? \"rotate-180\"\n : undefined\n }\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </div>\n </Collapsible>\n ) : null}\n </section>\n );\n}\n\nfunction OverviewAppsSkeleton() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nexport function DispatchControlPlane() {\n useSetPageTitle(<span aria-hidden />);\n const appsQuery = useActionQuery<WorkspaceAppSummary[]>(\n \"list-workspace-apps\",\n { includeAgentCards: false, includeArchived: true },\n );\n const connectedAppsQuery = useActionQuery<ConnectedAppSummary[]>(\n \"list-connected-agents\",\n {},\n );\n const curatedTemplatesQuery = useActionQuery<CuratedWorkspaceTemplatesResult>(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: workspaceApps = [], isLoading: appsLoading } = appsQuery;\n\n return (\n <div className=\"flex flex-col gap-8\">\n <CommandPanel />\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : (\n <AppsPanel\n apps={workspaceApps ?? []}\n isLoading={appsLoading}\n connectedApps={connectedAppsQuery.data ?? []}\n connectedAppsError={connectedAppsQuery.error}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n curatedTemplates={curatedTemplatesQuery.data}\n curatedTemplatesError={curatedTemplatesQuery.error}\n curatedTemplatesLoading={curatedTemplatesQuery.isLoading}\n onRetryCuratedTemplates={() => void curatedTemplatesQuery.refetch()}\n />\n )}\n </div>\n );\n}\n"]}
|
|
@@ -8,7 +8,7 @@ import { ActionQueryError } from "../../components/action-query-error.js";
|
|
|
8
8
|
import { APP_LIST_GRID_CLASS, APP_LIST_GRID_ROW_CLASS, AppList, } from "../../components/app-list-row.js";
|
|
9
9
|
import { CreateAppPopover } from "../../components/create-app-popover.js";
|
|
10
10
|
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
11
|
-
import {
|
|
11
|
+
import { filterOtherAppEntries, mergeOtherAppEntries, OtherAppsSection, } from "../../components/other-apps-section.js";
|
|
12
12
|
import { Button } from "../../components/ui/button.js";
|
|
13
13
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../../components/ui/collapsible.js";
|
|
14
14
|
import { Skeleton } from "../../components/ui/skeleton.js";
|
|
@@ -47,15 +47,13 @@ function AppsRoute() {
|
|
|
47
47
|
const archivedApps = allApps.filter((app) => app.archived);
|
|
48
48
|
const connectedApps = connectedAppsQuery.data ?? [];
|
|
49
49
|
const curatedTemplates = curatedTemplatesQuery.data;
|
|
50
|
-
const
|
|
50
|
+
const filteredOtherApps = filterOtherAppEntries(mergeOtherAppEntries({
|
|
51
51
|
templates: curatedTemplates,
|
|
52
52
|
connectedApps,
|
|
53
53
|
workspaceApps: allApps,
|
|
54
|
-
});
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
!otherAppsSearchReady ||
|
|
58
|
-
otherAppEntries.some((entry) => otherAppEntryMatchesQuery(entry, searchQuery));
|
|
54
|
+
}), searchQuery);
|
|
55
|
+
const otherAppsLoading = curatedTemplatesQuery.isLoading || connectedAppsQuery.isLoading;
|
|
56
|
+
const otherAppsError = curatedTemplatesQuery.error || connectedAppsQuery.error;
|
|
59
57
|
const orderedActiveApps = orderWorkspaceApps(activeApps, layout);
|
|
60
58
|
const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);
|
|
61
59
|
const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);
|
|
@@ -65,7 +63,7 @@ function AppsRoute() {
|
|
|
65
63
|
const hasSearchResults = filteredActiveApps.length > 0 ||
|
|
66
64
|
filteredPendingApps.length > 0 ||
|
|
67
65
|
filteredArchivedApps.length > 0 ||
|
|
68
|
-
|
|
66
|
+
filteredOtherApps.length > 0;
|
|
69
67
|
const showAppSkeletons = appsLoading && allApps.length === 0;
|
|
70
68
|
const templateLabels = {
|
|
71
69
|
appId: t("dispatch.pages.remixAppIdLabel"),
|
|
@@ -86,7 +84,10 @@ function AppsRoute() {
|
|
|
86
84
|
? t("dispatch.pages.appsDescriptionWithWorkspace", {
|
|
87
85
|
workspace: workspaceLabel,
|
|
88
86
|
})
|
|
89
|
-
: t("dispatch.pages.appsDescription"), children: _jsxs("div", { className: "space-y-8", children: [_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [_jsx(IconApps, { size: 16, className: "mt-0.5 shrink-0 text-muted-foreground" }), _jsx("div", { className: "min-w-0", children: _jsx("h2", { className: "truncate text-sm font-semibold text-foreground", children: t("dispatch.pages.yourApps", { defaultValue: "Your apps" }) }) })] }), _jsxs("div", { className: "flex min-w-0 flex-wrap items-center justify-end gap-2", children: [!showAppSkeletons &&
|
|
87
|
+
: t("dispatch.pages.appsDescription"), children: _jsxs("div", { className: "space-y-8", children: [_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [_jsx(IconApps, { size: 16, className: "mt-0.5 shrink-0 text-muted-foreground" }), _jsx("div", { className: "min-w-0", children: _jsx("h2", { className: "truncate text-sm font-semibold text-foreground", children: t("dispatch.pages.yourApps", { defaultValue: "Your apps" }) }) })] }), _jsxs("div", { className: "flex min-w-0 flex-wrap items-center justify-end gap-2", children: [!showAppSkeletons &&
|
|
88
|
+
(allApps.length > 0 ||
|
|
89
|
+
filteredOtherApps.length > 0 ||
|
|
90
|
+
Boolean(searchQuery.trim())) ? (_jsx(WorkspaceAppSearch, { className: "w-full sm:w-[250px]", query: searchQuery, onQueryChange: setSearchQuery })) : null, activeApps.length > 0 || pendingApps.length > 0 ? (_jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { size: "sm", variant: "outline", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), t("dispatch.pages.addApp", {
|
|
90
91
|
defaultValue: "Add app",
|
|
91
92
|
})] }) })) : null] })] }), !showAppSkeletons && allApps.length > 0 && persistenceError ? (_jsx("p", { className: "text-xs text-muted-foreground", role: "status", children: persistenceError === "both"
|
|
92
93
|
? t("dispatch.pages.appPinSaveFailed", {
|
|
@@ -94,7 +95,10 @@ function AppsRoute() {
|
|
|
94
95
|
})
|
|
95
96
|
: t("dispatch.pages.appPinSavedLocally", {
|
|
96
97
|
defaultValue: "App pins are saved on this device only.",
|
|
97
|
-
}) })) : null, appsQuery.isError ? (_jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() })) : showAppSkeletons ? (_jsx(AppsSkeletonGrid, {})) : !hasSearchResults &&
|
|
98
|
+
}) })) : null, appsQuery.isError ? (_jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() })) : showAppSkeletons ? (_jsx(AppsSkeletonGrid, {})) : !hasSearchResults &&
|
|
99
|
+
searchQuery.trim() &&
|
|
100
|
+
!otherAppsLoading &&
|
|
101
|
+
!otherAppsError ? (_jsx(WorkspaceAppSearchEmpty, { query: searchQuery, onClear: () => setSearchQuery("") })) : filteredActiveApps.length > 0 ? (_jsx(AppList, { className: APP_LIST_GRID_CLASS, children: filteredActiveApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: APP_LIST_GRID_ROW_CLASS, isPinned: layout.pinnedIds.includes(app.id), onTogglePinned: () => togglePinned(app.id) }, app.id))) })) : searchQuery.trim() ? null : pendingApps.length > 0 ? (_jsx(EmptyActiveAppsState, {})) : (_jsx(EmptyAppsState, {}))] }), pendingApps.length > 0 &&
|
|
98
102
|
(!searchQuery.trim() || filteredPendingApps.length > 0) ? (_jsx(Collapsible, { open: showPending || Boolean(searchQuery.trim()), onOpenChange: setShowPending, children: _jsxs("section", { className: "space-y-3 border-t pt-6", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconClockHour4, { size: 16, className: "shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.pendingApps") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.pendingCount", {
|
|
99
103
|
count: pendingApps.length,
|
|
100
104
|
}) })] })] }), _jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "gap-1.5", children: [showPending || Boolean(searchQuery.trim())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport {\n mergeOtherAppEntries,\n otherAppEntryMatchesQuery,\n OtherAppsSection,\n} from \"../../components/other-apps-section\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport type {\n CuratedWorkspaceTemplatesResult,\n WorkspaceTemplateLabels,\n} from \"../../components/workspace-template-card\";\nimport type { ConnectedAppSummary } from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery(\"list-connected-agents\", {});\n const curatedTemplatesQuery = useActionQuery(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const connectedApps =\n (connectedAppsQuery.data as ConnectedAppSummary[] | undefined) ?? [];\n const curatedTemplates = curatedTemplatesQuery.data as\n | CuratedWorkspaceTemplatesResult\n | undefined;\n const otherAppEntries = mergeOtherAppEntries({\n templates: curatedTemplates,\n connectedApps,\n workspaceApps: allApps,\n });\n const otherAppsSearchReady =\n !connectedAppsQuery.isLoading && !curatedTemplatesQuery.isLoading;\n const otherAppsMatchSearch =\n !searchQuery.trim() ||\n !otherAppsSearchReady ||\n otherAppEntries.some((entry) =>\n otherAppEntryMatchesQuery(entry, searchQuery),\n );\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0 ||\n otherAppsMatchSearch;\n const showAppSkeletons = appsLoading && allApps.length === 0;\n const templateLabels: WorkspaceTemplateLabels = {\n appId: t(\"dispatch.pages.remixAppIdLabel\"),\n appIdDescription: t(\"dispatch.pages.remixAppIdDescription\"),\n cancel: t(\"dispatch.pages.cancel\"),\n integrationSetup: t(\"dispatch.pages.integrationSetup\"),\n installed: t(\"dispatch.pages.alreadyInWorkspace\"),\n remix: t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" }),\n remixing: t(\"dispatch.pages.remixing\"),\n remixSuccess: t(\"dispatch.pages.remixSuccess\"),\n remixError: t(\"dispatch.pages.remixError\"),\n appIdRequired: t(\"dispatch.pages.appIdRequired\"),\n source: t(\"dispatch.pages.source\"),\n openApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open app\" }),\n viewLiveApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open\" }),\n };\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons && allApps.length > 0 ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : !hasSearchResults && searchQuery.trim() ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : filteredActiveApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id)}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n </AppList>\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n <OtherAppsSection\n templates={curatedTemplates}\n connectedApps={connectedApps}\n workspaceApps={allApps}\n query={searchQuery}\n templatesLoading={curatedTemplatesQuery.isLoading}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n templatesError={curatedTemplatesQuery.error}\n connectedAppsError={connectedAppsQuery.error}\n onRetryTemplates={() => void curatedTemplatesQuery.refetch()}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n templateLabels={templateLabels}\n onRemixSuccess={() => {\n void appsQuery.refetch();\n void curatedTemplatesQuery.refetch();\n }}\n />\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport {\n filterOtherAppEntries,\n mergeOtherAppEntries,\n OtherAppsSection,\n} from \"../../components/other-apps-section\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport type {\n CuratedWorkspaceTemplatesResult,\n WorkspaceTemplateLabels,\n} from \"../../components/workspace-template-card\";\nimport type { ConnectedAppSummary } from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery(\"list-connected-agents\", {});\n const curatedTemplatesQuery = useActionQuery(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const connectedApps =\n (connectedAppsQuery.data as ConnectedAppSummary[] | undefined) ?? [];\n const curatedTemplates = curatedTemplatesQuery.data as\n | CuratedWorkspaceTemplatesResult\n | undefined;\n const filteredOtherApps = filterOtherAppEntries(\n mergeOtherAppEntries({\n templates: curatedTemplates,\n connectedApps,\n workspaceApps: allApps,\n }),\n searchQuery,\n );\n const otherAppsLoading =\n curatedTemplatesQuery.isLoading || connectedAppsQuery.isLoading;\n const otherAppsError =\n curatedTemplatesQuery.error || connectedAppsQuery.error;\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0 ||\n filteredOtherApps.length > 0;\n const showAppSkeletons = appsLoading && allApps.length === 0;\n const templateLabels: WorkspaceTemplateLabels = {\n appId: t(\"dispatch.pages.remixAppIdLabel\"),\n appIdDescription: t(\"dispatch.pages.remixAppIdDescription\"),\n cancel: t(\"dispatch.pages.cancel\"),\n integrationSetup: t(\"dispatch.pages.integrationSetup\"),\n installed: t(\"dispatch.pages.alreadyInWorkspace\"),\n remix: t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" }),\n remixing: t(\"dispatch.pages.remixing\"),\n remixSuccess: t(\"dispatch.pages.remixSuccess\"),\n remixError: t(\"dispatch.pages.remixError\"),\n appIdRequired: t(\"dispatch.pages.appIdRequired\"),\n source: t(\"dispatch.pages.source\"),\n openApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open app\" }),\n viewLiveApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open\" }),\n };\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons &&\n (allApps.length > 0 ||\n filteredOtherApps.length > 0 ||\n Boolean(searchQuery.trim())) ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : !hasSearchResults &&\n searchQuery.trim() &&\n !otherAppsLoading &&\n !otherAppsError ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : filteredActiveApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id)}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n </AppList>\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n <OtherAppsSection\n templates={curatedTemplates}\n connectedApps={connectedApps}\n workspaceApps={allApps}\n query={searchQuery}\n templatesLoading={curatedTemplatesQuery.isLoading}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n templatesError={curatedTemplatesQuery.error}\n connectedAppsError={connectedAppsQuery.error}\n onRetryTemplates={() => void curatedTemplatesQuery.refetch()}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n templateLabels={templateLabels}\n onRemixSuccess={() => {\n void appsQuery.refetch();\n void curatedTemplatesQuery.refetch();\n }}\n />\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.18-nightly-20260825123905",
|
|
4
4
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -101,10 +101,10 @@
|
|
|
101
101
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
102
102
|
"vite": "8.1.0",
|
|
103
103
|
"vitest": "^4.1.5",
|
|
104
|
-
"@agent-native/core": "0.173.
|
|
104
|
+
"@agent-native/core": "0.173.1-nightly-20260825123905"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
|
-
"@agent-native/core": "
|
|
107
|
+
"@agent-native/core": "0.173.1-nightly-20260825123905",
|
|
108
108
|
"react": ">=19.2.7",
|
|
109
109
|
"react-dom": ">=19.2.7",
|
|
110
110
|
"react-router": ">=8"
|
|
@@ -104,6 +104,21 @@ describe("DispatchControlPlane", () => {
|
|
|
104
104
|
let root: Root;
|
|
105
105
|
let queryClient: QueryClient;
|
|
106
106
|
|
|
107
|
+
async function searchApps(query: string) {
|
|
108
|
+
const input = container.querySelector<HTMLInputElement>(
|
|
109
|
+
'input[placeholder="Search apps"]',
|
|
110
|
+
);
|
|
111
|
+
expect(input).not.toBeNull();
|
|
112
|
+
const valueSetter = Object.getOwnPropertyDescriptor(
|
|
113
|
+
HTMLInputElement.prototype,
|
|
114
|
+
"value",
|
|
115
|
+
)?.set;
|
|
116
|
+
await act(async () => {
|
|
117
|
+
valueSetter?.call(input, query);
|
|
118
|
+
input?.dispatchEvent(new Event("input", { bubbles: true }));
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
107
122
|
beforeEach(() => {
|
|
108
123
|
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
109
124
|
clientState.inBuilderFrame = false;
|
|
@@ -343,4 +358,57 @@ describe("DispatchControlPlane", () => {
|
|
|
343
358
|
expect(clipsHref).toContain("https://clips.agent-native.com");
|
|
344
359
|
expect(clipsHref).not.toContain("/share/");
|
|
345
360
|
});
|
|
361
|
+
|
|
362
|
+
it("searches available apps case-insensitively before showing the empty state", async () => {
|
|
363
|
+
clientState.workspaceApps = [
|
|
364
|
+
{
|
|
365
|
+
id: "analytics",
|
|
366
|
+
name: "Analytics",
|
|
367
|
+
path: "/analytics",
|
|
368
|
+
status: "ready",
|
|
369
|
+
isDispatch: false,
|
|
370
|
+
},
|
|
371
|
+
];
|
|
372
|
+
clientState.curatedTemplates = [
|
|
373
|
+
{
|
|
374
|
+
id: "brain",
|
|
375
|
+
name: "Brain",
|
|
376
|
+
description: "Search cited company knowledge",
|
|
377
|
+
liveUrl: "https://brain.agent-native.com",
|
|
378
|
+
installed: false,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
id: "assets",
|
|
382
|
+
name: "Assets",
|
|
383
|
+
description: "Manage brand assets",
|
|
384
|
+
liveUrl: "https://assets.agent-native.com",
|
|
385
|
+
installed: false,
|
|
386
|
+
},
|
|
387
|
+
];
|
|
388
|
+
|
|
389
|
+
await act(async () => {
|
|
390
|
+
root.render(
|
|
391
|
+
<MemoryRouter initialEntries={["/overview"]}>
|
|
392
|
+
<TooltipProvider>
|
|
393
|
+
<QueryClientProvider client={queryClient}>
|
|
394
|
+
<DispatchControlPlane />
|
|
395
|
+
</QueryClientProvider>
|
|
396
|
+
</TooltipProvider>
|
|
397
|
+
</MemoryRouter>,
|
|
398
|
+
);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
await searchApps("Brain");
|
|
402
|
+
expect(container.textContent).toContain("Brain");
|
|
403
|
+
expect(container.textContent).not.toContain("Assets");
|
|
404
|
+
expect(container.textContent).not.toContain("No apps match your search");
|
|
405
|
+
|
|
406
|
+
await searchApps("brain");
|
|
407
|
+
expect(container.textContent).toContain("Brain");
|
|
408
|
+
expect(container.textContent).not.toContain("Assets");
|
|
409
|
+
|
|
410
|
+
await searchApps("missing app");
|
|
411
|
+
expect(container.textContent).toContain("No apps match your search");
|
|
412
|
+
expect(container.textContent).not.toContain("Brain");
|
|
413
|
+
});
|
|
346
414
|
});
|
|
@@ -30,7 +30,11 @@ import {
|
|
|
30
30
|
} from "./app-list-row";
|
|
31
31
|
import { CreateAppPopover } from "./create-app-popover";
|
|
32
32
|
import { useSetPageTitle } from "./layout/HeaderActions";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
filterOtherAppEntries,
|
|
35
|
+
mergeOtherAppEntries,
|
|
36
|
+
OtherAppsSection,
|
|
37
|
+
} from "./other-apps-section";
|
|
34
38
|
import { Button } from "./ui/button";
|
|
35
39
|
import {
|
|
36
40
|
Collapsible,
|
|
@@ -187,13 +191,20 @@ function AppsPanel({
|
|
|
187
191
|
const filteredPendingApps = orderedPendingApps.filter((app) =>
|
|
188
192
|
workspaceAppMatchesQuery(app, searchQuery),
|
|
189
193
|
);
|
|
194
|
+
const otherAppEntries = filterOtherAppEntries(
|
|
195
|
+
mergeOtherAppEntries({
|
|
196
|
+
templates: curatedTemplates,
|
|
197
|
+
connectedApps,
|
|
198
|
+
workspaceApps: apps,
|
|
199
|
+
}),
|
|
200
|
+
searchQuery,
|
|
201
|
+
);
|
|
190
202
|
const hasSearchResults =
|
|
191
|
-
filteredActiveApps.length > 0 ||
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
203
|
+
filteredActiveApps.length > 0 ||
|
|
204
|
+
filteredPendingApps.length > 0 ||
|
|
205
|
+
otherAppEntries.length > 0;
|
|
206
|
+
const otherAppsLoading = curatedTemplatesLoading || connectedAppsLoading;
|
|
207
|
+
const otherAppsError = curatedTemplatesError || connectedAppsError;
|
|
197
208
|
const showSkeletons =
|
|
198
209
|
isLoading && activeApps.length === 0 && pendingApps.length === 0;
|
|
199
210
|
|
|
@@ -208,7 +219,10 @@ function AppsPanel({
|
|
|
208
219
|
View all
|
|
209
220
|
</Link>
|
|
210
221
|
</Button>
|
|
211
|
-
{!showSkeletons &&
|
|
222
|
+
{!showSkeletons &&
|
|
223
|
+
(visibleApps.length > 0 ||
|
|
224
|
+
otherAppEntries.length > 0 ||
|
|
225
|
+
Boolean(searchQuery.trim())) ? (
|
|
212
226
|
<WorkspaceAppSearch
|
|
213
227
|
className="w-[220px]"
|
|
214
228
|
query={searchQuery}
|
|
@@ -240,7 +254,10 @@ function AppsPanel({
|
|
|
240
254
|
) : null}
|
|
241
255
|
{showSkeletons ? (
|
|
242
256
|
<OverviewAppsSkeleton />
|
|
243
|
-
) : searchQuery.trim() &&
|
|
257
|
+
) : searchQuery.trim() &&
|
|
258
|
+
!hasSearchResults &&
|
|
259
|
+
!otherAppsLoading &&
|
|
260
|
+
!otherAppsError ? (
|
|
244
261
|
<WorkspaceAppSearchEmpty
|
|
245
262
|
query={searchQuery}
|
|
246
263
|
onClear={() => setSearchQuery("")}
|
|
@@ -270,21 +287,20 @@ function AppsPanel({
|
|
|
270
287
|
})}
|
|
271
288
|
</p>
|
|
272
289
|
) : null}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
) : null}
|
|
290
|
+
<OtherAppsSection
|
|
291
|
+
templates={curatedTemplates}
|
|
292
|
+
connectedApps={connectedApps}
|
|
293
|
+
workspaceApps={apps}
|
|
294
|
+
templatesLoading={curatedTemplatesLoading}
|
|
295
|
+
connectedAppsLoading={connectedAppsLoading}
|
|
296
|
+
templatesError={curatedTemplatesError}
|
|
297
|
+
connectedAppsError={connectedAppsError}
|
|
298
|
+
query={searchQuery}
|
|
299
|
+
onRetryTemplates={onRetryCuratedTemplates}
|
|
300
|
+
onRetryConnectedApps={onRetryConnectedApps}
|
|
301
|
+
heading={null}
|
|
302
|
+
embeddedInList
|
|
303
|
+
/>
|
|
288
304
|
</AppList>
|
|
289
305
|
</>
|
|
290
306
|
)}
|
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
import { CreateAppPopover } from "../../components/create-app-popover";
|
|
20
20
|
import { DispatchShell } from "../../components/dispatch-shell";
|
|
21
21
|
import {
|
|
22
|
+
filterOtherAppEntries,
|
|
22
23
|
mergeOtherAppEntries,
|
|
23
|
-
otherAppEntryMatchesQuery,
|
|
24
24
|
OtherAppsSection,
|
|
25
25
|
} from "../../components/other-apps-section";
|
|
26
26
|
import { Button } from "../../components/ui/button";
|
|
@@ -101,19 +101,18 @@ function AppsRoute() {
|
|
|
101
101
|
const curatedTemplates = curatedTemplatesQuery.data as
|
|
102
102
|
| CuratedWorkspaceTemplatesResult
|
|
103
103
|
| undefined;
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
);
|
|
104
|
+
const filteredOtherApps = filterOtherAppEntries(
|
|
105
|
+
mergeOtherAppEntries({
|
|
106
|
+
templates: curatedTemplates,
|
|
107
|
+
connectedApps,
|
|
108
|
+
workspaceApps: allApps,
|
|
109
|
+
}),
|
|
110
|
+
searchQuery,
|
|
111
|
+
);
|
|
112
|
+
const otherAppsLoading =
|
|
113
|
+
curatedTemplatesQuery.isLoading || connectedAppsQuery.isLoading;
|
|
114
|
+
const otherAppsError =
|
|
115
|
+
curatedTemplatesQuery.error || connectedAppsQuery.error;
|
|
117
116
|
const orderedActiveApps = orderWorkspaceApps(activeApps, layout);
|
|
118
117
|
const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);
|
|
119
118
|
const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);
|
|
@@ -130,7 +129,7 @@ function AppsRoute() {
|
|
|
130
129
|
filteredActiveApps.length > 0 ||
|
|
131
130
|
filteredPendingApps.length > 0 ||
|
|
132
131
|
filteredArchivedApps.length > 0 ||
|
|
133
|
-
|
|
132
|
+
filteredOtherApps.length > 0;
|
|
134
133
|
const showAppSkeletons = appsLoading && allApps.length === 0;
|
|
135
134
|
const templateLabels: WorkspaceTemplateLabels = {
|
|
136
135
|
appId: t("dispatch.pages.remixAppIdLabel"),
|
|
@@ -174,7 +173,10 @@ function AppsRoute() {
|
|
|
174
173
|
</div>
|
|
175
174
|
</div>
|
|
176
175
|
<div className="flex min-w-0 flex-wrap items-center justify-end gap-2">
|
|
177
|
-
{!showAppSkeletons &&
|
|
176
|
+
{!showAppSkeletons &&
|
|
177
|
+
(allApps.length > 0 ||
|
|
178
|
+
filteredOtherApps.length > 0 ||
|
|
179
|
+
Boolean(searchQuery.trim())) ? (
|
|
178
180
|
<WorkspaceAppSearch
|
|
179
181
|
className="w-full sm:w-[250px]"
|
|
180
182
|
query={searchQuery}
|
|
@@ -216,7 +218,10 @@ function AppsRoute() {
|
|
|
216
218
|
/>
|
|
217
219
|
) : showAppSkeletons ? (
|
|
218
220
|
<AppsSkeletonGrid />
|
|
219
|
-
) : !hasSearchResults &&
|
|
221
|
+
) : !hasSearchResults &&
|
|
222
|
+
searchQuery.trim() &&
|
|
223
|
+
!otherAppsLoading &&
|
|
224
|
+
!otherAppsError ? (
|
|
220
225
|
<WorkspaceAppSearchEmpty
|
|
221
226
|
query={searchQuery}
|
|
222
227
|
onClear={() => setSearchQuery("")}
|