@agent-native/dispatch 0.41.1-nightly-20261104110058 → 0.42.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.
Files changed (195) hide show
  1. package/CHANGELOG.md +26 -55
  2. package/dist/actions/get-hosted-apps-settings.d.ts +5 -0
  3. package/dist/actions/get-hosted-apps-settings.d.ts.map +1 -0
  4. package/dist/actions/get-hosted-apps-settings.js +25 -0
  5. package/dist/actions/get-hosted-apps-settings.js.map +1 -0
  6. package/dist/actions/index.d.ts.map +1 -1
  7. package/dist/actions/index.js +4 -0
  8. package/dist/actions/index.js.map +1 -1
  9. package/dist/actions/list-connected-agents.d.ts +1 -0
  10. package/dist/actions/list-connected-agents.js +11 -10
  11. package/dist/actions/list-connected-agents.js.map +1 -1
  12. package/dist/actions/list_apps.js +3 -2
  13. package/dist/actions/list_apps.js.map +1 -1
  14. package/dist/actions/provider-api-register.d.ts +10 -10
  15. package/dist/actions/set-hosted-apps-settings.d.ts +7 -0
  16. package/dist/actions/set-hosted-apps-settings.d.ts.map +1 -0
  17. package/dist/actions/set-hosted-apps-settings.js +35 -0
  18. package/dist/actions/set-hosted-apps-settings.js.map +1 -0
  19. package/dist/components/app-card-tiers.d.ts +13 -0
  20. package/dist/components/app-card-tiers.d.ts.map +1 -0
  21. package/dist/components/app-card-tiers.js +22 -0
  22. package/dist/components/app-card-tiers.js.map +1 -0
  23. package/dist/components/app-list-row.d.ts +12 -4
  24. package/dist/components/app-list-row.d.ts.map +1 -1
  25. package/dist/components/app-list-row.js +19 -4
  26. package/dist/components/app-list-row.js.map +1 -1
  27. package/dist/components/app-open-actions.d.ts +4 -0
  28. package/dist/components/app-open-actions.d.ts.map +1 -1
  29. package/dist/components/app-open-actions.js +9 -0
  30. package/dist/components/app-open-actions.js.map +1 -1
  31. package/dist/components/app-pin-button.d.ts +9 -0
  32. package/dist/components/app-pin-button.d.ts.map +1 -0
  33. package/dist/components/app-pin-button.js +29 -0
  34. package/dist/components/app-pin-button.js.map +1 -0
  35. package/dist/components/app-tier-sections.d.ts +27 -0
  36. package/dist/components/app-tier-sections.d.ts.map +1 -0
  37. package/dist/components/app-tier-sections.js +44 -0
  38. package/dist/components/app-tier-sections.js.map +1 -0
  39. package/dist/components/chat-home-apps.d.ts.map +1 -1
  40. package/dist/components/chat-home-apps.js +19 -26
  41. package/dist/components/chat-home-apps.js.map +1 -1
  42. package/dist/components/connected-app-card.d.ts +3 -1
  43. package/dist/components/connected-app-card.d.ts.map +1 -1
  44. package/dist/components/connected-app-card.js +6 -3
  45. package/dist/components/connected-app-card.js.map +1 -1
  46. package/dist/components/create-app-popover.d.ts +4 -0
  47. package/dist/components/create-app-popover.d.ts.map +1 -1
  48. package/dist/components/create-app-popover.js +6 -0
  49. package/dist/components/create-app-popover.js.map +1 -1
  50. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  51. package/dist/components/dispatch-control-plane.js +25 -35
  52. package/dist/components/dispatch-control-plane.js.map +1 -1
  53. package/dist/components/hosted-apps-settings-group.d.ts +6 -0
  54. package/dist/components/hosted-apps-settings-group.d.ts.map +1 -0
  55. package/dist/components/hosted-apps-settings-group.js +76 -0
  56. package/dist/components/hosted-apps-settings-group.js.map +1 -0
  57. package/dist/components/layout/Layout.d.ts +6 -4
  58. package/dist/components/layout/Layout.d.ts.map +1 -1
  59. package/dist/components/layout/Layout.js +97 -80
  60. package/dist/components/layout/Layout.js.map +1 -1
  61. package/dist/components/workspace-app-card.d.ts.map +1 -1
  62. package/dist/components/workspace-app-card.js +9 -20
  63. package/dist/components/workspace-app-card.js.map +1 -1
  64. package/dist/components/workspace-app-layout-notice.d.ts +9 -0
  65. package/dist/components/workspace-app-layout-notice.d.ts.map +1 -0
  66. package/dist/components/workspace-app-layout-notice.js +27 -0
  67. package/dist/components/workspace-app-layout-notice.js.map +1 -0
  68. package/dist/components/workspace-app-search.d.ts.map +1 -1
  69. package/dist/components/workspace-app-search.js +11 -5
  70. package/dist/components/workspace-app-search.js.map +1 -1
  71. package/dist/components/workspace-template-card.d.ts.map +1 -1
  72. package/dist/components/workspace-template-card.js +7 -2
  73. package/dist/components/workspace-template-card.js.map +1 -1
  74. package/dist/db/index.d.ts.map +1 -1
  75. package/dist/db/index.js +1 -0
  76. package/dist/db/index.js.map +1 -1
  77. package/dist/lib/other-apps.d.ts +10 -1
  78. package/dist/lib/other-apps.d.ts.map +1 -1
  79. package/dist/lib/other-apps.js +7 -1
  80. package/dist/lib/other-apps.js.map +1 -1
  81. package/dist/lib/workspace-app-layout.d.ts +62 -6
  82. package/dist/lib/workspace-app-layout.d.ts.map +1 -1
  83. package/dist/lib/workspace-app-layout.js +196 -41
  84. package/dist/lib/workspace-app-layout.js.map +1 -1
  85. package/dist/lib/workspace-app-lists.d.ts +17 -0
  86. package/dist/lib/workspace-app-lists.d.ts.map +1 -0
  87. package/dist/lib/workspace-app-lists.js +21 -0
  88. package/dist/lib/workspace-app-lists.js.map +1 -0
  89. package/dist/lib/workspace-apps.d.ts +3 -1
  90. package/dist/lib/workspace-apps.d.ts.map +1 -1
  91. package/dist/lib/workspace-apps.js +5 -1
  92. package/dist/lib/workspace-apps.js.map +1 -1
  93. package/dist/routes/pages/apps.d.ts.map +1 -1
  94. package/dist/routes/pages/apps.js +23 -35
  95. package/dist/routes/pages/apps.js.map +1 -1
  96. package/dist/routes/pages/settings-page.d.ts.map +1 -1
  97. package/dist/routes/pages/settings-page.js +24 -3
  98. package/dist/routes/pages/settings-page.js.map +1 -1
  99. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  100. package/dist/server/lib/app-creation-store.js +13 -18
  101. package/dist/server/lib/app-creation-store.js.map +1 -1
  102. package/dist/server/lib/app-roles.d.ts +2 -0
  103. package/dist/server/lib/app-roles.d.ts.map +1 -1
  104. package/dist/server/lib/app-roles.js +26 -7
  105. package/dist/server/lib/app-roles.js.map +1 -1
  106. package/dist/server/lib/hosted-apps-settings-schema.d.ts +6 -0
  107. package/dist/server/lib/hosted-apps-settings-schema.d.ts.map +1 -0
  108. package/dist/server/lib/hosted-apps-settings-schema.js +6 -0
  109. package/dist/server/lib/hosted-apps-settings-schema.js.map +1 -0
  110. package/dist/server/lib/hosted-apps-settings.d.ts +27 -0
  111. package/dist/server/lib/hosted-apps-settings.d.ts.map +1 -0
  112. package/dist/server/lib/hosted-apps-settings.js +72 -0
  113. package/dist/server/lib/hosted-apps-settings.js.map +1 -0
  114. package/dist/server/plugins/agent-chat.js +6 -3
  115. package/dist/server/plugins/agent-chat.js.map +1 -1
  116. package/dist/server/plugins/integrations.js +3 -3
  117. package/dist/server/plugins/integrations.js.map +1 -1
  118. package/dist/shared/hosted-apps-settings.d.ts +3 -0
  119. package/dist/shared/hosted-apps-settings.d.ts.map +1 -0
  120. package/dist/shared/hosted-apps-settings.js +3 -0
  121. package/dist/shared/hosted-apps-settings.js.map +1 -0
  122. package/package.json +4 -4
  123. package/src/actions/get-hosted-apps-settings.ts +29 -0
  124. package/src/actions/hosted-apps-settings.spec.ts +100 -0
  125. package/src/actions/index.ts +4 -0
  126. package/src/actions/list-connected-agents.spec.ts +67 -0
  127. package/src/actions/list-connected-agents.ts +14 -15
  128. package/src/actions/list_apps.spec.ts +16 -0
  129. package/src/actions/list_apps.ts +5 -2
  130. package/src/actions/set-hosted-apps-settings.ts +42 -0
  131. package/src/components/app-card-tiers.tsx +85 -0
  132. package/src/components/app-list-row.spec.tsx +54 -0
  133. package/src/components/app-list-row.tsx +50 -8
  134. package/src/components/app-open-actions.tsx +16 -0
  135. package/src/components/app-pin-button.spec.tsx +68 -0
  136. package/src/components/app-pin-button.tsx +66 -0
  137. package/src/components/app-tier-sections.spec.tsx +155 -0
  138. package/src/components/app-tier-sections.tsx +158 -0
  139. package/src/components/chat-home-apps.spec.tsx +135 -29
  140. package/src/components/chat-home-apps.tsx +115 -111
  141. package/src/components/connected-app-card.spec.tsx +18 -2
  142. package/src/components/connected-app-card.tsx +18 -1
  143. package/src/components/create-app-popover.tsx +22 -0
  144. package/src/components/dispatch-control-plane.spec.tsx +89 -20
  145. package/src/components/dispatch-control-plane.tsx +91 -125
  146. package/src/components/hosted-apps-settings-group.spec.tsx +218 -0
  147. package/src/components/hosted-apps-settings-group.tsx +189 -0
  148. package/src/components/layout/Layout.spec.tsx +356 -49
  149. package/src/components/layout/Layout.tsx +189 -142
  150. package/src/components/workspace-app-card.spec.tsx +33 -29
  151. package/src/components/workspace-app-card.tsx +13 -31
  152. package/src/components/workspace-app-layout-notice.spec.tsx +106 -0
  153. package/src/components/workspace-app-layout-notice.tsx +65 -0
  154. package/src/components/workspace-app-search.spec.tsx +53 -0
  155. package/src/components/workspace-app-search.tsx +39 -32
  156. package/src/components/workspace-template-card.spec.tsx +10 -0
  157. package/src/components/workspace-template-card.tsx +7 -2
  158. package/src/db/index.spec.ts +9 -0
  159. package/src/db/index.ts +1 -0
  160. package/src/lib/other-apps.spec.ts +25 -0
  161. package/src/lib/other-apps.ts +9 -0
  162. package/src/lib/workspace-app-layout.spec.ts +61 -3
  163. package/src/lib/workspace-app-layout.store.spec.tsx +261 -0
  164. package/src/lib/workspace-app-layout.ts +265 -48
  165. package/src/lib/workspace-app-lists.ts +32 -0
  166. package/src/lib/workspace-apps.ts +10 -2
  167. package/src/routes/pages/apps.spec.tsx +133 -5
  168. package/src/routes/pages/apps.tsx +79 -140
  169. package/src/routes/pages/chat.spec.tsx +66 -49
  170. package/src/routes/pages/settings-page.tsx +31 -3
  171. package/src/routes/pages/settings.spec.tsx +37 -0
  172. package/src/server/lib/app-creation-store.spec.ts +14 -0
  173. package/src/server/lib/app-creation-store.ts +16 -29
  174. package/src/server/lib/app-creation-store.write-observation.spec.ts +216 -0
  175. package/src/server/lib/app-roles.spec.ts +48 -1
  176. package/src/server/lib/app-roles.ts +44 -12
  177. package/src/server/lib/hosted-apps-settings-schema.ts +6 -0
  178. package/src/server/lib/hosted-apps-settings.spec.ts +154 -0
  179. package/src/server/lib/hosted-apps-settings.ts +108 -0
  180. package/src/server/plugins/agent-chat.spec.ts +16 -0
  181. package/src/server/plugins/agent-chat.ts +7 -2
  182. package/src/server/plugins/integrations.ts +3 -3
  183. package/src/shared/hosted-apps-settings.ts +3 -0
  184. package/src/styles/dispatch.css +40 -11
  185. package/dist/components/available-apps-section.d.ts +0 -9
  186. package/dist/components/available-apps-section.d.ts.map +0 -1
  187. package/dist/components/available-apps-section.js +0 -97
  188. package/dist/components/available-apps-section.js.map +0 -1
  189. package/dist/components/other-apps-section.d.ts +0 -35
  190. package/dist/components/other-apps-section.d.ts.map +0 -1
  191. package/dist/components/other-apps-section.js +0 -79
  192. package/dist/components/other-apps-section.js.map +0 -1
  193. package/src/components/available-apps-section.tsx +0 -239
  194. package/src/components/other-apps-section.spec.ts +0 -50
  195. package/src/components/other-apps-section.tsx +0 -254
@@ -1,12 +1,20 @@
1
- import type { ReactNode } from "react";
2
- export declare const APP_LIST_GRID_CLASS = "w-full xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none";
3
- export declare const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border xl:border-transparent xl:transition-[border-color] xl:focus-within:border-ring/50";
4
- export declare function AppList({ children, className, }: {
1
+ import { Item } from "@agent-native/toolkit/ui/item";
2
+ import { type ComponentProps, type ReactNode } from "react";
3
+ type AppListLayout = "list" | "grid";
4
+ /**
5
+ * `grid` is the two-column app list on Home, New chat, All apps and the
6
+ * catalogs; its rows are shadcn `Item`s. `list` is a bordered, divided list.
7
+ */
8
+ export declare function AppList({ children, className, layout, }: {
5
9
  children: ReactNode;
6
10
  className?: string;
11
+ layout?: AppListLayout;
7
12
  }): import("node_modules/@types/react").JSX.Element;
13
+ /** One app in a grid app list. */
14
+ export declare function AppGridItem({ className, ...props }: ComponentProps<typeof Item>): import("node_modules/@types/react").JSX.Element;
8
15
  export declare function AppListRow({ children, className, }: {
9
16
  children: ReactNode;
10
17
  className?: string;
11
18
  }): import("node_modules/@types/react").JSX.Element;
19
+ export {};
12
20
  //# sourceMappingURL=app-list-row.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-list-row.d.ts","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,mBAAmB,+EAC8C,CAAC;AAC/E,eAAO,MAAM,uBAAuB,+GAC0E,CAAC;AAE/G,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAMA;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAWA"}
1
+ {"version":3,"file":"app-list-row.d.ts","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAIrC;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,EACT,MAAe,GAChB,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,mDAeA;AAED,kCAAkC;AAClC,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,IAAI,CAAC,mDAY7B;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAeA"}
@@ -1,11 +1,26 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Item } from "@agent-native/toolkit/ui/item";
3
+ import { createContext, useContext, } from "react";
2
4
  import { cn } from "../lib/utils.js";
3
- export const APP_LIST_GRID_CLASS = "w-full xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none";
4
- export const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border xl:border-transparent xl:transition-[border-color] xl:focus-within:border-ring/50";
5
- export function AppList({ children, className, }) {
6
- return (_jsx("div", { className: cn("overflow-hidden rounded-2xl", className), children: children }));
5
+ const AppListLayoutContext = createContext("list");
6
+ /**
7
+ * `grid` is the two-column app list on Home, New chat, All apps and the
8
+ * catalogs; its rows are shadcn `Item`s. `list` is a bordered, divided list.
9
+ */
10
+ export function AppList({ children, className, layout = "list", }) {
11
+ return (_jsx(AppListLayoutContext.Provider, { value: layout, children: _jsx("div", { className: cn(layout === "grid"
12
+ ? "grid w-full grid-cols-1 gap-2 sm:grid-cols-2"
13
+ : "overflow-hidden rounded-2xl", className), children: children }) }));
14
+ }
15
+ /** One app in a grid app list. */
16
+ export function AppGridItem({ className, ...props }) {
17
+ return (_jsx(Item, { variant: "muted", size: "sm", className: cn("group min-w-0 flex-nowrap focus-within:border-ring/50", className), ...props }));
7
18
  }
8
19
  export function AppListRow({ children, className, }) {
20
+ const layout = useContext(AppListLayoutContext);
21
+ if (layout === "grid") {
22
+ return _jsx(AppGridItem, { className: className, children: children });
23
+ }
9
24
  return (_jsx("div", { className: cn("group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] focus-within:bg-muted/30", className), children: children }));
10
25
  }
11
26
  //# sourceMappingURL=app-list-row.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-list-row.js","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAC9B,4EAA4E,CAAC;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAClC,4GAA4G,CAAC;AAE/G,MAAM,UAAU,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,6BAA6B,EAAE,SAAS,CAAC,YACzD,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,gJAAgJ,EAChJ,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nexport const APP_LIST_GRID_CLASS =\n \"w-full xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none\";\nexport const APP_LIST_GRID_ROW_CLASS =\n \"xl:rounded-2xl xl:border xl:border-transparent xl:transition-[border-color] xl:focus-within:border-ring/50\";\n\nexport function AppList({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"overflow-hidden rounded-2xl\", className)}>\n {children}\n </div>\n );\n}\n\nexport function AppListRow({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n \"group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] focus-within:bg-muted/30\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"app-list-row.js","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EACL,aAAa,EACb,UAAU,GAGX,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAIlC,MAAM,oBAAoB,GAAG,aAAa,CAAgB,MAAM,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,EACT,MAAM,GAAG,MAAM,GAKhB;IACC,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAC1C,cACE,SAAS,EAAE,EAAE,CACX,MAAM,KAAK,MAAM;gBACf,CAAC,CAAC,8CAA8C;gBAChD,CAAC,CAAC,6BAA6B,EACjC,SAAS,CACV,YAEA,QAAQ,GACL,GACwB,CACjC,CAAC;AACJ,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACoB;IAC5B,OAAO,CACL,KAAC,IAAI,IACH,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAE,EAAE,CACX,uDAAuD,EACvD,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GAIV;IACC,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAChD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,KAAC,WAAW,IAAC,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAe,CAAC;IACrE,CAAC;IACD,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,gJAAgJ,EAChJ,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { Item } from \"@agent-native/toolkit/ui/item\";\nimport {\n createContext,\n useContext,\n type ComponentProps,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\ntype AppListLayout = \"list\" | \"grid\";\n\nconst AppListLayoutContext = createContext<AppListLayout>(\"list\");\n\n/**\n * `grid` is the two-column app list on Home, New chat, All apps and the\n * catalogs; its rows are shadcn `Item`s. `list` is a bordered, divided list.\n */\nexport function AppList({\n children,\n className,\n layout = \"list\",\n}: {\n children: ReactNode;\n className?: string;\n layout?: AppListLayout;\n}) {\n return (\n <AppListLayoutContext.Provider value={layout}>\n <div\n className={cn(\n layout === \"grid\"\n ? \"grid w-full grid-cols-1 gap-2 sm:grid-cols-2\"\n : \"overflow-hidden rounded-2xl\",\n className,\n )}\n >\n {children}\n </div>\n </AppListLayoutContext.Provider>\n );\n}\n\n/** One app in a grid app list. */\nexport function AppGridItem({\n className,\n ...props\n}: ComponentProps<typeof Item>) {\n return (\n <Item\n variant=\"muted\"\n size=\"sm\"\n className={cn(\n \"group min-w-0 flex-nowrap focus-within:border-ring/50\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function AppListRow({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n const layout = useContext(AppListLayoutContext);\n if (layout === \"grid\") {\n return <AppGridItem className={className}>{children}</AppGridItem>;\n }\n return (\n <div\n className={cn(\n \"group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] focus-within:bg-muted/30\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n"]}
@@ -1,2 +1,6 @@
1
+ import type { useT } from "@agent-native/core/client/i18n";
2
+ import type { AppOpenActionLabels } from "@agent-native/toolkit/app/chat/chat-first/app-open-actions";
1
3
  export { AppOpenActions, type AppOpenActionLabels, type AppOpenActionMenuItem, } from "@agent-native/toolkit/app/chat/chat-first/app-open-actions";
4
+ /** Dispatch's localized labels for an app row's Open actions. */
5
+ export declare function appOpenActionLabels(t: ReturnType<typeof useT>, name: string): Partial<AppOpenActionLabels>;
2
6
  //# sourceMappingURL=app-open-actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-open-actions.d.ts","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,4DAA4D,CAAC"}
1
+ {"version":3,"file":"app-open-actions.d.ts","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4DAA4D,CAAC;AAEtG,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,4DAA4D,CAAC;AAEpE,iEAAiE;AACjE,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,EAC1B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,CAAC,CAO9B"}
@@ -1,2 +1,11 @@
1
1
  export { AppOpenActions, } from "@agent-native/toolkit/app/chat/chat-first/app-open-actions";
2
+ /** Dispatch's localized labels for an app row's Open actions. */
3
+ export function appOpenActionLabels(t, name) {
4
+ return {
5
+ openApp: t("dispatch.pages.openApp", { defaultValue: "Open" }),
6
+ openAppAccessible: t("dispatch.pages.chatFirstOpenApp", { name }),
7
+ openInNewTab: t("dispatch.pages.chatFirstOpenInNewTab"),
8
+ moreOptions: t("extensions.optionsFor", { name }),
9
+ };
10
+ }
2
11
  //# sourceMappingURL=app-open-actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-open-actions.js","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,4DAA4D,CAAC","sourcesContent":["export {\n AppOpenActions,\n type AppOpenActionLabels,\n type AppOpenActionMenuItem,\n} from \"@agent-native/toolkit/app/chat/chat-first/app-open-actions\";\n"]}
1
+ {"version":3,"file":"app-open-actions.js","sourceRoot":"","sources":["../../src/components/app-open-actions.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,GAGf,MAAM,4DAA4D,CAAC;AAEpE,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CACjC,CAA0B,EAC1B,IAAY;IAEZ,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAC9D,iBAAiB,EAAE,CAAC,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,CAAC;QACjE,YAAY,EAAE,CAAC,CAAC,sCAAsC,CAAC;QACvD,WAAW,EAAE,CAAC,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC","sourcesContent":["import type { useT } from \"@agent-native/core/client/i18n\";\nimport type { AppOpenActionLabels } from \"@agent-native/toolkit/app/chat/chat-first/app-open-actions\";\n\nexport {\n AppOpenActions,\n type AppOpenActionLabels,\n type AppOpenActionMenuItem,\n} from \"@agent-native/toolkit/app/chat/chat-first/app-open-actions\";\n\n/** Dispatch's localized labels for an app row's Open actions. */\nexport function appOpenActionLabels(\n t: ReturnType<typeof useT>,\n name: string,\n): Partial<AppOpenActionLabels> {\n return {\n openApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open\" }),\n openAppAccessible: t(\"dispatch.pages.chatFirstOpenApp\", { name }),\n openInNewTab: t(\"dispatch.pages.chatFirstOpenInNewTab\"),\n moreOptions: t(\"extensions.optionsFor\", { name }),\n };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /** Shown on row hover or focus, always when pinned or on touch screens. */
2
+ export declare function AppPinButton({ appId, name, pinned, onToggle, className, }: {
3
+ appId: string;
4
+ name: string;
5
+ pinned: boolean;
6
+ onToggle: () => void;
7
+ className?: string;
8
+ }): import("node_modules/@types/react").JSX.Element;
9
+ //# sourceMappingURL=app-pin-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-pin-button.d.ts","sourceRoot":"","sources":["../../src/components/app-pin-button.tsx"],"names":[],"mappings":"AAOA,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDA6CA"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useT } from "@agent-native/core/client/i18n";
3
+ import { IconPin, IconPinFilled } from "@tabler/icons-react";
4
+ import { cn } from "../lib/utils.js";
5
+ import { Button } from "./ui/button.js";
6
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip.js";
7
+ /** Shown on row hover or focus, always when pinned or on touch screens. */
8
+ export function AppPinButton({ appId, name, pinned, onToggle, className, }) {
9
+ const t = useT();
10
+ const label = t(pinned ? "dispatch.pages.unpinApp" : "dispatch.pages.pinApp", {
11
+ name,
12
+ });
13
+ const Icon = pinned ? IconPinFilled : IconPin;
14
+ const toggle = () => {
15
+ onToggle();
16
+ // Pinning moves the row to another section, which remounts it; keep
17
+ // keyboard focus on this app's pin button rather than dropping to <body>.
18
+ requestAnimationFrame(() => {
19
+ if (document.activeElement && document.activeElement !== document.body) {
20
+ return;
21
+ }
22
+ document
23
+ .querySelector(`[data-pin-app-id="${CSS.escape(appId)}"]`)
24
+ ?.focus();
25
+ });
26
+ };
27
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": label, "aria-pressed": pinned, "data-pinned": pinned, "data-pin-app-id": appId, onClick: toggle, className: cn("size-7 shrink-0 p-0 text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 data-[pinned=true]:text-foreground data-[pinned=true]:opacity-100 [@media(pointer:coarse)]:opacity-100", className), children: _jsx(Icon, { size: 15, "aria-hidden": "true" }) }) }), _jsx(TooltipContent, { children: label })] }));
28
+ }
29
+ //# sourceMappingURL=app-pin-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-pin-button.js","sourceRoot":"","sources":["../../src/components/app-pin-button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvE,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAS,GAOV;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,CAAC,CACb,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,uBAAuB,EAC5D;QACE,IAAI;KACL,CACF,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,QAAQ,EAAE,CAAC;QACX,oEAAoE;QACpE,0EAA0E;QAC1E,qBAAqB,CAAC,GAAG,EAAE;YACzB,IAAI,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,aAAa,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACvE,OAAO;YACT,CAAC;YACD,QAAQ;iBACL,aAAa,CAAc,qBAAqB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBACvE,EAAE,KAAK,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO,CACL,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,gBACG,KAAK,kBACH,MAAM,iBACP,MAAM,qBACF,KAAK,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,EAAE,CACX,sRAAsR,EACtR,SAAS,CACV,YAED,KAAC,IAAI,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,GAC9B,GACM,EACjB,KAAC,cAAc,cAAE,KAAK,GAAkB,IAChC,CACX,CAAC;AACJ,CAAC","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { IconPin, IconPinFilled } from \"@tabler/icons-react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./ui/button\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./ui/tooltip\";\n\n/** Shown on row hover or focus, always when pinned or on touch screens. */\nexport function AppPinButton({\n appId,\n name,\n pinned,\n onToggle,\n className,\n}: {\n appId: string;\n name: string;\n pinned: boolean;\n onToggle: () => void;\n className?: string;\n}) {\n const t = useT();\n const label = t(\n pinned ? \"dispatch.pages.unpinApp\" : \"dispatch.pages.pinApp\",\n {\n name,\n },\n );\n const Icon = pinned ? IconPinFilled : IconPin;\n const toggle = () => {\n onToggle();\n // Pinning moves the row to another section, which remounts it; keep\n // keyboard focus on this app's pin button rather than dropping to <body>.\n requestAnimationFrame(() => {\n if (document.activeElement && document.activeElement !== document.body) {\n return;\n }\n document\n .querySelector<HTMLElement>(`[data-pin-app-id=\"${CSS.escape(appId)}\"]`)\n ?.focus();\n });\n };\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={label}\n aria-pressed={pinned}\n data-pinned={pinned}\n data-pin-app-id={appId}\n onClick={toggle}\n className={cn(\n \"size-7 shrink-0 p-0 text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 data-[pinned=true]:text-foreground data-[pinned=true]:opacity-100 [@media(pointer:coarse)]:opacity-100\",\n className,\n )}\n >\n <Icon size={15} aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{label}</TooltipContent>\n </Tooltip>\n );\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from "react";
2
+ import type { WorkspaceAppTiers } from "../lib/workspace-app-layout.js";
3
+ /** The Apps tier's empty text when the workspace has no apps of its own. */
4
+ export declare function NoWorkspaceAppsText(): import("node_modules/@types/react").JSX.Element;
5
+ /** View all, search and New app: the header cluster of every app list. */
6
+ export declare function AppListActions({ viewAllHref, search, newApp, }: {
7
+ viewAllHref?: string | undefined;
8
+ search?: ReactNode;
9
+ newApp?: ReactNode;
10
+ }): import("node_modules/@types/react").JSX.Element;
11
+ /**
12
+ * Pinned (only when something is pinned), Apps, then Hosted apps. The Apps
13
+ * tier always renders. `actions` sit in the first header; `hasPinnedApps` is
14
+ * decided before a search filters, so a query that matches no pinned app does
15
+ * not move the search while typing.
16
+ */
17
+ export declare function AppTierSections<T>({ tiers, appsTitle, actions, hasPinnedApps, appsFallback, renderItems, className, }: {
18
+ tiers: WorkspaceAppTiers<T>;
19
+ appsTitle: string;
20
+ actions?: ReactNode;
21
+ hasPinnedApps?: boolean | undefined;
22
+ /** Shown in the Apps tier when it has no rows (loading, empty, no matches). */
23
+ appsFallback?: ReactNode;
24
+ renderItems: (items: T[]) => ReactNode;
25
+ className?: string;
26
+ }): import("node_modules/@types/react").JSX.Element;
27
+ //# sourceMappingURL=app-tier-sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-tier-sections.d.ts","sourceRoot":"","sources":["../../src/components/app-tier-sections.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAkBrE,4EAA4E;AAC5E,wBAAgB,mBAAmB,oDAOlC;AAiCD,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,EAC7B,WAAW,EACX,MAAM,EACN,MAAM,GACP,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,mDAuBA;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,EACjC,KAAK,EACL,SAAS,EACT,OAAO,EACP,aAAuC,EACvC,YAAY,EACZ,WAAW,EACX,SAAS,GACV,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,+EAA+E;IAC/E,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAkCA"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useT } from "@agent-native/core/client/i18n";
3
+ import { useOrgRole } from "@agent-native/core/client/org";
4
+ import { buildSettingsRoute } from "@agent-native/core/navigation";
5
+ import { Link } from "react-router";
6
+ import { cn } from "../lib/utils.js";
7
+ import { Button } from "./ui/button.js";
8
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip.js";
9
+ function TierHeader({ title, action }) {
10
+ return (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3", children: [_jsx("h2", { className: "truncate text-sm font-semibold text-foreground", children: title }), action ? (_jsx("div", { className: "flex min-w-0 flex-1 justify-end", children: action })) : null] }));
11
+ }
12
+ /** The Apps tier's empty text when the workspace has no apps of its own. */
13
+ export function NoWorkspaceAppsText() {
14
+ const t = useT();
15
+ return (_jsx("p", { className: "px-4 py-3 text-sm text-muted-foreground", children: t("dispatch.pages.chatFirstNoWorkspaceApps") }));
16
+ }
17
+ function ManageHostedAppsLink() {
18
+ const t = useT();
19
+ const { org, canManageOrg, isLoading } = useOrgRole();
20
+ const label = t("dispatch.pages.manageHostedApps");
21
+ // Settings › Organization › Apps only exists inside an organization.
22
+ if (isLoading || !org?.orgId)
23
+ return null;
24
+ if (canManageOrg) {
25
+ return (_jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: _jsx(Link, { to: buildSettingsRoute("apps"), className: "text-muted-foreground", children: label }) }));
26
+ }
27
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { tabIndex: 0, className: "inline-flex rounded-md", children: _jsx(Button, { variant: "ghost", size: "sm", disabled: true, children: label }) }) }), _jsx(TooltipContent, { children: t("dispatch.pages.manageHostedAppsAdminOnly") })] }));
28
+ }
29
+ /** View all, search and New app: the header cluster of every app list. */
30
+ export function AppListActions({ viewAllHref, search, newApp, }) {
31
+ const t = useT();
32
+ return (_jsxs("div", { "data-app-list-actions": true, className: "flex min-w-0 flex-1 flex-wrap items-center justify-end gap-1.5 sm:flex-nowrap", children: [viewAllHref ? (_jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: _jsx(Link, { to: viewAllHref, className: "text-muted-foreground", children: t("dispatch.pages.viewAllApps") }) })) : null, search ? (_jsx("div", { className: "order-last min-w-0 basis-full sm:order-none sm:basis-auto", children: search })) : null, newApp] }));
33
+ }
34
+ /**
35
+ * Pinned (only when something is pinned), Apps, then Hosted apps. The Apps
36
+ * tier always renders. `actions` sit in the first header; `hasPinnedApps` is
37
+ * decided before a search filters, so a query that matches no pinned app does
38
+ * not move the search while typing.
39
+ */
40
+ export function AppTierSections({ tiers, appsTitle, actions, hasPinnedApps = tiers.pinned.length > 0, appsFallback, renderItems, className, }) {
41
+ const t = useT();
42
+ return (_jsxs("div", { className: cn("flex flex-col gap-6", className), children: [hasPinnedApps ? (_jsxs("section", { "aria-label": t("dispatch.pages.pinnedApps"), className: "flex flex-col gap-3", children: [_jsx(TierHeader, { title: t("dispatch.pages.pinnedApps"), action: actions }), tiers.pinned.length > 0 ? renderItems(tiers.pinned) : null] })) : null, _jsxs("section", { "aria-label": appsTitle, className: "flex flex-col gap-3", children: [_jsx(TierHeader, { title: appsTitle, action: hasPinnedApps ? undefined : actions }), tiers.apps.length > 0 ? renderItems(tiers.apps) : appsFallback] }), tiers.hosted.length > 0 ? (_jsxs("section", { "aria-label": t("dispatch.pages.hostedApps"), className: "flex flex-col gap-3", children: [_jsx(TierHeader, { title: t("dispatch.pages.hostedApps"), action: _jsx(ManageHostedAppsLink, {}) }), renderItems(tiers.hosted)] })) : null] }));
43
+ }
44
+ //# sourceMappingURL=app-tier-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-tier-sections.js","sourceRoot":"","sources":["../../src/components/app-tier-sections.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { useOrgRole } from \"@agent-native/core/client/org\";\nimport { buildSettingsRoute } from \"@agent-native/core/navigation\";\nimport type { ReactNode } from \"react\";\nimport { Link } from \"react-router\";\n\nimport { cn } from \"../lib/utils\";\nimport type { WorkspaceAppTiers } from \"../lib/workspace-app-layout\";\nimport { Button } from \"./ui/button\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./ui/tooltip\";\n\nfunction TierHeader({ title, action }: { title: string; action?: ReactNode }) {\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 {/* Takes the rest of the row so a wide action wraps inside it. */}\n {action ? (\n <div className=\"flex min-w-0 flex-1 justify-end\">{action}</div>\n ) : null}\n </div>\n );\n}\n\n/** The Apps tier's empty text when the workspace has no apps of its own. */\nexport function NoWorkspaceAppsText() {\n const t = useT();\n return (\n <p className=\"px-4 py-3 text-sm text-muted-foreground\">\n {t(\"dispatch.pages.chatFirstNoWorkspaceApps\")}\n </p>\n );\n}\n\nfunction ManageHostedAppsLink() {\n const t = useT();\n const { org, canManageOrg, isLoading } = useOrgRole();\n const label = t(\"dispatch.pages.manageHostedApps\");\n // Settings › Organization › Apps only exists inside an organization.\n if (isLoading || !org?.orgId) return null;\n if (canManageOrg) {\n return (\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link to={buildSettingsRoute(\"apps\")} className=\"text-muted-foreground\">\n {label}\n </Link>\n </Button>\n );\n }\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <span tabIndex={0} className=\"inline-flex rounded-md\">\n <Button variant=\"ghost\" size=\"sm\" disabled>\n {label}\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>\n {t(\"dispatch.pages.manageHostedAppsAdminOnly\")}\n </TooltipContent>\n </Tooltip>\n );\n}\n\n/** View all, search and New app: the header cluster of every app list. */\nexport function AppListActions({\n viewAllHref,\n search,\n newApp,\n}: {\n viewAllHref?: string | undefined;\n search?: ReactNode;\n newApp?: ReactNode;\n}) {\n const t = useT();\n return (\n // Below `sm` the search takes its own full-width line under the buttons.\n <div\n data-app-list-actions\n className=\"flex min-w-0 flex-1 flex-wrap items-center justify-end gap-1.5 sm:flex-nowrap\"\n >\n {viewAllHref ? (\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link to={viewAllHref} className=\"text-muted-foreground\">\n {t(\"dispatch.pages.viewAllApps\")}\n </Link>\n </Button>\n ) : null}\n {search ? (\n <div className=\"order-last min-w-0 basis-full sm:order-none sm:basis-auto\">\n {search}\n </div>\n ) : null}\n {newApp}\n </div>\n );\n}\n\n/**\n * Pinned (only when something is pinned), Apps, then Hosted apps. The Apps\n * tier always renders. `actions` sit in the first header; `hasPinnedApps` is\n * decided before a search filters, so a query that matches no pinned app does\n * not move the search while typing.\n */\nexport function AppTierSections<T>({\n tiers,\n appsTitle,\n actions,\n hasPinnedApps = tiers.pinned.length > 0,\n appsFallback,\n renderItems,\n className,\n}: {\n tiers: WorkspaceAppTiers<T>;\n appsTitle: string;\n actions?: ReactNode;\n hasPinnedApps?: boolean | undefined;\n /** Shown in the Apps tier when it has no rows (loading, empty, no matches). */\n appsFallback?: ReactNode;\n renderItems: (items: T[]) => ReactNode;\n className?: string;\n}) {\n const t = useT();\n return (\n <div className={cn(\"flex flex-col gap-6\", className)}>\n {hasPinnedApps ? (\n <section\n aria-label={t(\"dispatch.pages.pinnedApps\")}\n className=\"flex flex-col gap-3\"\n >\n <TierHeader title={t(\"dispatch.pages.pinnedApps\")} action={actions} />\n {tiers.pinned.length > 0 ? renderItems(tiers.pinned) : null}\n </section>\n ) : null}\n <section aria-label={appsTitle} className=\"flex flex-col gap-3\">\n <TierHeader\n title={appsTitle}\n action={hasPinnedApps ? undefined : actions}\n />\n {tiers.apps.length > 0 ? renderItems(tiers.apps) : appsFallback}\n </section>\n {tiers.hosted.length > 0 ? (\n <section\n aria-label={t(\"dispatch.pages.hostedApps\")}\n className=\"flex flex-col gap-3\"\n >\n <TierHeader\n title={t(\"dispatch.pages.hostedApps\")}\n action={<ManageHostedAppsLink />}\n />\n {renderItems(tiers.hosted)}\n </section>\n ) : null}\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-home-apps.d.ts","sourceRoot":"","sources":["../../src/components/chat-home-apps.tsx"],"names":[],"mappings":"AA0BA,wBAAgB,oBAAoB,2DA4InC"}
1
+ {"version":3,"file":"chat-home-apps.d.ts","sourceRoot":"","sources":["../../src/components/chat-home-apps.tsx"],"names":[],"mappings":"AA+BA,wBAAgB,oBAAoB,2DA2InC"}
@@ -1,52 +1,45 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
- import { AppOpenActions } from "@agent-native/toolkit/app/chat/chat-first/app-open-actions";
4
- import { IconArrowUpRight, IconPlus } from "@tabler/icons-react";
5
3
  import { useMemo, useState } from "react";
6
- import { Link } from "react-router";
7
- import { orderWorkspaceApps, useWorkspaceAppLayout, workspaceAppMatchesQuery, } from "../lib/workspace-app-layout.js";
4
+ import { hasPinnedWorkspaceApp, tierWorkspaceApps, useWorkspaceAppLayout, workspaceAppMatchesQuery, } from "../lib/workspace-app-layout.js";
8
5
  import { workspaceAppHref } from "../lib/workspace-apps.js";
9
6
  import { ActionQueryError } from "./action-query-error.js";
10
7
  import { AppIcon } from "./app-icon.js";
11
- import { CreateAppPopover } from "./create-app-popover.js";
8
+ import { AppGridItem, AppList, AppListRow } from "./app-list-row.js";
9
+ import { AppOpenActions, appOpenActionLabels } from "./app-open-actions.js";
10
+ import { AppPinButton } from "./app-pin-button.js";
11
+ import { AppListActions, AppTierSections, NoWorkspaceAppsText, } from "./app-tier-sections.js";
12
+ import { NewAppButton } from "./create-app-popover.js";
12
13
  import { dispatchNavLinkTarget, useDispatchWorkspaceAppLauncher, } from "./layout/Layout.js";
13
- import { Button } from "./ui/button.js";
14
14
  import { Skeleton } from "./ui/skeleton.js";
15
15
  import { WorkspaceAppSearch, WorkspaceAppSearchEmpty, } from "./workspace-app-search.js";
16
16
  export function DispatchChatHomeApps() {
17
17
  const t = useT();
18
18
  const launcher = useDispatchWorkspaceAppLauncher();
19
- const { layout } = useWorkspaceAppLayout();
19
+ const { layout, togglePinned } = useWorkspaceAppLayout();
20
20
  const [query, setQuery] = useState("");
21
- const apps = useMemo(() => orderWorkspaceApps(launcher?.workspaceApps ?? [], layout)
21
+ const tiers = useMemo(() => tierWorkspaceApps((launcher?.workspaceApps ?? [])
22
22
  .map((app) => ({
23
+ id: app.id,
24
+ name: app.name,
25
+ source: app.source,
23
26
  app,
24
27
  description: app.defaultDescriptionKey
25
28
  ? t(app.defaultDescriptionKey)
26
29
  : app.description,
27
30
  }))
28
- .filter(({ app, description }) => workspaceAppMatchesQuery({ ...app, description }, query)), [launcher?.workspaceApps, layout, query, t]);
31
+ .filter((row) => workspaceAppMatchesQuery(row, query)), layout), [launcher?.workspaceApps, layout, query, t]);
32
+ const hasMatches = tiers.pinned.length + tiers.apps.length + tiers.hosted.length > 0;
29
33
  if (!launcher)
30
34
  return null;
31
- if (launcher.error && launcher.workspaceApps.length === 0) {
35
+ const hasOwnApps = launcher.workspaceApps.some((app) => app.source !== "builtin");
36
+ if (launcher.workspaceAppsStatus === "error") {
32
37
  return (_jsx("div", { className: "mx-auto w-full max-w-[1000px]", children: _jsx(ActionQueryError, { error: launcher.error, onRetry: launcher.retry, queryName: launcher.errorQueryName }) }));
33
38
  }
34
- if (!launcher.isLoading && launcher.workspaceApps.length === 0)
35
- return null;
36
- return (_jsxs("div", { className: "mx-auto w-full max-w-[1000px]", children: [launcher.error ? (_jsx(ActionQueryError, { error: launcher.error, onRetry: launcher.retry, className: "mb-3", queryName: launcher.errorQueryName })) : null, _jsxs("section", { "aria-label": t("dispatch.nav.apps"), children: [_jsxs("header", { className: "mb-3 flex flex-wrap items-center justify-between gap-3", children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("dispatch.nav.apps") }), _jsxs("div", { className: "flex min-w-0 flex-1 items-center justify-end gap-2 sm:flex-none", children: [_jsx(WorkspaceAppSearch, { query: query, onQueryChange: setQuery, className: "w-full max-w-[280px]" }), _jsx(CreateAppPopover, { align: "end", onCreated: launcher.retry, trigger: _jsxs(Button, { type: "button", size: "sm", variant: "outline", children: [_jsx(IconPlus, { size: 16, "aria-hidden": "true" }), t("dispatch.pages.chatFirstNewApp")] }) })] })] }), launcher.isLoading && launcher.workspaceApps.length === 0 ? (_jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: Array.from({ length: 6 }, (_, index) => (_jsxs("div", { className: "flex min-w-0 items-center gap-3 rounded-xl bg-muted/30 px-3 py-2.5", children: [_jsx(Skeleton, { className: "size-7 rounded-lg" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [_jsx(Skeleton, { className: "h-4 w-20" }), _jsx(Skeleton, { className: "h-3 w-40 max-w-full" })] }), _jsx(Skeleton, { className: "h-7 w-20" })] }, index))) })) : apps.length > 0 ? (_jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: apps.map(({ app, description }) => {
39
+ return (_jsxs("div", { className: "mx-auto w-full max-w-[1000px]", children: [launcher.error ? (_jsx(ActionQueryError, { error: launcher.error, onRetry: launcher.retry, className: "mb-3", queryName: launcher.errorQueryName })) : null, _jsx("section", { children: _jsx(AppTierSections, { tiers: tiers, appsTitle: t("dispatch.pages.workspaceApps"), hasPinnedApps: hasPinnedWorkspaceApp(launcher.workspaceApps, layout), actions: _jsx(AppListActions, { viewAllHref: dispatchNavLinkTarget("/apps"), search: _jsx(WorkspaceAppSearch, { query: query, onQueryChange: setQuery, className: "w-full sm:w-[280px]" }), newApp: _jsx(NewAppButton, { onCreated: launcher.retry }) }), appsFallback: launcher.workspaceAppsStatus === "loading" ? (_jsx(AppList, { layout: "grid", children: Array.from({ length: 6 }, (_, index) => (_jsxs(AppListRow, { children: [_jsx(Skeleton, { className: "size-7 rounded-lg" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [_jsx(Skeleton, { className: "h-4 w-20" }), _jsx(Skeleton, { className: "h-3 w-40 max-w-full" })] }), _jsx(Skeleton, { className: "h-7 w-20" })] }, index))) })) : query.trim() ? (hasMatches ? null : (_jsx(WorkspaceAppSearchEmpty, { query: query, onClear: () => setQuery("") }))) : hasOwnApps ? null : (_jsx(NoWorkspaceAppsText, {})), renderItems: (rows) => (_jsx(AppList, { layout: "grid", children: rows.map(({ app, description }) => {
37
40
  const href = workspaceAppHref(app);
38
- return (_jsxs("article", { className: "flex min-w-0 items-center gap-3 rounded-xl bg-muted/30 px-3 py-2.5 transition-colors hover:bg-muted/50", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [_jsx(AppIcon, { id: app.id, name: app.name, size: "sm" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-semibold text-foreground", children: app.name }), description ? (_jsx("span", { className: "mt-0.5 block truncate text-xs text-muted-foreground", children: description })) : null] })] }), _jsx(AppOpenActions, { name: app.name, href: href, onOpen: () => launcher.openApp(app), showNewTabOption: Boolean(href), labels: {
39
- openApp: t("dispatch.pages.openApp", {
40
- defaultValue: "Open",
41
- }),
42
- openAppAccessible: t("dispatch.pages.chatFirstOpenApp", {
43
- name: app.name,
44
- }),
45
- openInNewTab: t("dispatch.pages.chatFirstOpenInNewTab"),
46
- moreOptions: t("extensions.optionsFor", {
47
- name: app.name,
48
- }),
49
- } })] }, app.id));
50
- }) })) : (_jsx(WorkspaceAppSearchEmpty, { query: query, onClear: () => setQuery("") })), _jsxs(Link, { to: dispatchNavLinkTarget("/apps"), className: "mt-3 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground", children: [t("dispatch.pages.allApps"), _jsx(IconArrowUpRight, { size: 14, "aria-hidden": "true" })] })] })] }));
41
+ const pinned = layout.pinnedIds.includes(app.id.toLowerCase());
42
+ return (_jsx(AppGridItem, { asChild: true, children: _jsxs("article", { children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [_jsx(AppIcon, { id: app.id, name: app.name, size: "sm" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-semibold text-foreground", children: app.name }), description ? (_jsx("span", { className: "mt-0.5 block truncate text-xs text-muted-foreground", children: description })) : null] })] }), _jsx(AppPinButton, { appId: app.id, name: app.name, pinned: pinned, onToggle: () => togglePinned(app.id) }), _jsx(AppOpenActions, { name: app.name, href: href, onOpen: () => launcher.openApp(app), showNewTabOption: Boolean(href), external: app.source === "builtin", labels: appOpenActionLabels(t, app.name) })] }) }, app.id));
43
+ }) })) }) })] }));
51
44
  }
52
45
  //# sourceMappingURL=chat-home-apps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-home-apps.js","sourceRoot":"","sources":["../../src/components/chat-home-apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { AppOpenActions } from \"@agent-native/toolkit/app/chat/chat-first/app-open-actions\";\nimport { IconArrowUpRight, IconPlus } from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../lib/workspace-app-layout\";\nimport { workspaceAppHref } from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { AppIcon } from \"./app-icon\";\nimport { CreateAppPopover } from \"./create-app-popover\";\nimport {\n dispatchNavLinkTarget,\n useDispatchWorkspaceAppLauncher,\n} from \"./layout/Layout\";\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"./workspace-app-search\";\n\nexport function DispatchChatHomeApps() {\n const t = useT();\n const launcher = useDispatchWorkspaceAppLauncher();\n const { layout } = useWorkspaceAppLayout();\n const [query, setQuery] = useState(\"\");\n const apps = useMemo(\n () =>\n orderWorkspaceApps(launcher?.workspaceApps ?? [], layout)\n .map((app) => ({\n app,\n description: app.defaultDescriptionKey\n ? t(app.defaultDescriptionKey)\n : app.description,\n }))\n .filter(({ app, description }) =>\n workspaceAppMatchesQuery({ ...app, description }, query),\n ),\n [launcher?.workspaceApps, layout, query, t],\n );\n if (!launcher) return null;\n\n if (launcher.error && launcher.workspaceApps.length === 0) {\n return (\n <div className=\"mx-auto w-full max-w-[1000px]\">\n <ActionQueryError\n error={launcher.error}\n onRetry={launcher.retry}\n queryName={launcher.errorQueryName}\n />\n </div>\n );\n }\n if (!launcher.isLoading && launcher.workspaceApps.length === 0) return null;\n\n return (\n <div className=\"mx-auto w-full max-w-[1000px]\">\n {launcher.error ? (\n <ActionQueryError\n error={launcher.error}\n onRetry={launcher.retry}\n className=\"mb-3\"\n queryName={launcher.errorQueryName}\n />\n ) : null}\n <section aria-label={t(\"dispatch.nav.apps\")}>\n <header className=\"mb-3 flex flex-wrap items-center justify-between gap-3\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.nav.apps\")}\n </h2>\n <div className=\"flex min-w-0 flex-1 items-center justify-end gap-2 sm:flex-none\">\n <WorkspaceAppSearch\n query={query}\n onQueryChange={setQuery}\n className=\"w-full max-w-[280px]\"\n />\n <CreateAppPopover\n align=\"end\"\n onCreated={launcher.retry}\n trigger={\n <Button type=\"button\" size=\"sm\" variant=\"outline\">\n <IconPlus size={16} aria-hidden=\"true\" />\n {t(\"dispatch.pages.chatFirstNewApp\")}\n </Button>\n }\n />\n </div>\n </header>\n {launcher.isLoading && launcher.workspaceApps.length === 0 ? (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {Array.from({ length: 6 }, (_, index) => (\n <div\n key={index}\n className=\"flex min-w-0 items-center gap-3 rounded-xl bg-muted/30 px-3 py-2.5\"\n >\n <Skeleton className=\"size-7 rounded-lg\" />\n <div className=\"min-w-0 flex-1 space-y-1.5\">\n <Skeleton className=\"h-4 w-20\" />\n <Skeleton className=\"h-3 w-40 max-w-full\" />\n </div>\n <Skeleton className=\"h-7 w-20\" />\n </div>\n ))}\n </div>\n ) : apps.length > 0 ? (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {apps.map(({ app, description }) => {\n const href = workspaceAppHref(app);\n return (\n <article\n key={app.id}\n className=\"flex min-w-0 items-center gap-3 rounded-xl bg-muted/30 px-3 py-2.5 transition-colors hover:bg-muted/50\"\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <AppIcon id={app.id} name={app.name} size=\"sm\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-semibold text-foreground\">\n {app.name}\n </span>\n {description ? (\n <span className=\"mt-0.5 block truncate text-xs text-muted-foreground\">\n {description}\n </span>\n ) : null}\n </span>\n </div>\n <AppOpenActions\n name={app.name}\n href={href}\n onOpen={() => launcher.openApp(app)}\n showNewTabOption={Boolean(href)}\n labels={{\n openApp: t(\"dispatch.pages.openApp\", {\n defaultValue: \"Open\",\n }),\n openAppAccessible: t(\"dispatch.pages.chatFirstOpenApp\", {\n name: app.name,\n }),\n openInNewTab: t(\"dispatch.pages.chatFirstOpenInNewTab\"),\n moreOptions: t(\"extensions.optionsFor\", {\n name: app.name,\n }),\n }}\n />\n </article>\n );\n })}\n </div>\n ) : (\n <WorkspaceAppSearchEmpty query={query} onClear={() => setQuery(\"\")} />\n )}\n <Link\n to={dispatchNavLinkTarget(\"/apps\")}\n className=\"mt-3 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n {t(\"dispatch.pages.allApps\")}\n <IconArrowUpRight size={14} aria-hidden=\"true\" />\n </Link>\n </section>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"chat-home-apps.js","sourceRoot":"","sources":["../../src/components/chat-home-apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { useMemo, useState } from \"react\";\n\nimport {\n hasPinnedWorkspaceApp,\n tierWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../lib/workspace-app-layout\";\nimport { workspaceAppHref } from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppGridItem, AppList, AppListRow } from \"./app-list-row\";\nimport { AppOpenActions, appOpenActionLabels } from \"./app-open-actions\";\nimport { AppPinButton } from \"./app-pin-button\";\nimport {\n AppListActions,\n AppTierSections,\n NoWorkspaceAppsText,\n} from \"./app-tier-sections\";\nimport { NewAppButton } from \"./create-app-popover\";\nimport {\n dispatchNavLinkTarget,\n useDispatchWorkspaceAppLauncher,\n} from \"./layout/Layout\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"./workspace-app-search\";\n\nexport function DispatchChatHomeApps() {\n const t = useT();\n const launcher = useDispatchWorkspaceAppLauncher();\n const { layout, togglePinned } = useWorkspaceAppLayout();\n const [query, setQuery] = useState(\"\");\n const tiers = useMemo(\n () =>\n tierWorkspaceApps(\n (launcher?.workspaceApps ?? [])\n .map((app) => ({\n id: app.id,\n name: app.name,\n source: app.source,\n app,\n description: app.defaultDescriptionKey\n ? t(app.defaultDescriptionKey)\n : app.description,\n }))\n .filter((row) => workspaceAppMatchesQuery(row, query)),\n layout,\n ),\n [launcher?.workspaceApps, layout, query, t],\n );\n const hasMatches =\n tiers.pinned.length + tiers.apps.length + tiers.hosted.length > 0;\n if (!launcher) return null;\n const hasOwnApps = launcher.workspaceApps.some(\n (app) => app.source !== \"builtin\",\n );\n\n if (launcher.workspaceAppsStatus === \"error\") {\n return (\n <div className=\"mx-auto w-full max-w-[1000px]\">\n <ActionQueryError\n error={launcher.error}\n onRetry={launcher.retry}\n queryName={launcher.errorQueryName}\n />\n </div>\n );\n }\n return (\n <div className=\"mx-auto w-full max-w-[1000px]\">\n {launcher.error ? (\n <ActionQueryError\n error={launcher.error}\n onRetry={launcher.retry}\n className=\"mb-3\"\n queryName={launcher.errorQueryName}\n />\n ) : null}\n <section>\n <AppTierSections\n tiers={tiers}\n appsTitle={t(\"dispatch.pages.workspaceApps\")}\n hasPinnedApps={hasPinnedWorkspaceApp(launcher.workspaceApps, layout)}\n actions={\n <AppListActions\n viewAllHref={dispatchNavLinkTarget(\"/apps\")}\n search={\n <WorkspaceAppSearch\n query={query}\n onQueryChange={setQuery}\n className=\"w-full sm:w-[280px]\"\n />\n }\n newApp={<NewAppButton onCreated={launcher.retry} />}\n />\n }\n appsFallback={\n launcher.workspaceAppsStatus === \"loading\" ? (\n <AppList layout=\"grid\">\n {Array.from({ length: 6 }, (_, index) => (\n <AppListRow key={index}>\n <Skeleton className=\"size-7 rounded-lg\" />\n <div className=\"min-w-0 flex-1 space-y-1.5\">\n <Skeleton className=\"h-4 w-20\" />\n <Skeleton className=\"h-3 w-40 max-w-full\" />\n </div>\n <Skeleton className=\"h-7 w-20\" />\n </AppListRow>\n ))}\n </AppList>\n ) : query.trim() ? (\n hasMatches ? null : (\n <WorkspaceAppSearchEmpty\n query={query}\n onClear={() => setQuery(\"\")}\n />\n )\n ) : hasOwnApps ? null : (\n <NoWorkspaceAppsText />\n )\n }\n renderItems={(rows) => (\n <AppList layout=\"grid\">\n {rows.map(({ app, description }) => {\n const href = workspaceAppHref(app);\n const pinned = layout.pinnedIds.includes(app.id.toLowerCase());\n return (\n <AppGridItem key={app.id} asChild>\n <article>\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <AppIcon id={app.id} name={app.name} size=\"sm\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-semibold text-foreground\">\n {app.name}\n </span>\n {description ? (\n <span className=\"mt-0.5 block truncate text-xs text-muted-foreground\">\n {description}\n </span>\n ) : null}\n </span>\n </div>\n <AppPinButton\n appId={app.id}\n name={app.name}\n pinned={pinned}\n onToggle={() => togglePinned(app.id)}\n />\n <AppOpenActions\n name={app.name}\n href={href}\n onOpen={() => launcher.openApp(app)}\n showNewTabOption={Boolean(href)}\n external={app.source === \"builtin\"}\n labels={appOpenActionLabels(t, app.name)}\n />\n </article>\n </AppGridItem>\n );\n })}\n </AppList>\n )}\n />\n </section>\n </div>\n );\n}\n"]}
@@ -1,6 +1,8 @@
1
1
  import type { ConnectedAppSummary } from "../lib/other-apps.js";
2
- export declare function ConnectedAppCard({ app, className, }: {
2
+ export declare function ConnectedAppCard({ app, className, isPinned, onTogglePinned, }: {
3
3
  app: ConnectedAppSummary;
4
4
  className?: string;
5
+ isPinned?: boolean;
6
+ onTogglePinned?: () => void;
5
7
  }): import("node_modules/@types/react").JSX.Element;
6
8
  //# sourceMappingURL=connected-app-card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAS7D,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAiDA"}
1
+ {"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAU7D,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,EACT,QAAgB,EAChB,cAAc,GACf,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,mDA4DA"}
@@ -1,10 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useT } from "@agent-native/core/client/i18n";
2
3
  import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
3
4
  import { navigateToWorkspaceApp, shouldOpenWorkspaceAppInTopWindow, } from "../lib/workspace-apps.js";
4
5
  import { AppIcon } from "./app-icon.js";
5
6
  import { AppListRow } from "./app-list-row.js";
6
- import { AppOpenActions } from "./app-open-actions.js";
7
- export function ConnectedAppCard({ app, className, }) {
7
+ import { AppOpenActions, appOpenActionLabels } from "./app-open-actions.js";
8
+ import { AppPinButton } from "./app-pin-button.js";
9
+ export function ConnectedAppCard({ app, className, isPinned = false, onTogglePinned, }) {
10
+ const t = useT();
8
11
  const launchUrl = app.homeUrl ?? app.url;
9
12
  const trackedLaunchUrl = withBuilderUtmTrackingParams(launchUrl, {
10
13
  campaign: "product",
@@ -27,6 +30,6 @@ export function ConnectedAppCard({ app, className, }) {
27
30
  if (navigateToWorkspaceApp(anchor.href))
28
31
  event.preventDefault();
29
32
  };
30
- return (_jsxs(AppListRow, { className: className, children: [_jsx(AppIcon, { id: app.id, name: app.name, color: app.color, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), _jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || app.url })] }), _jsx("div", { className: "flex shrink-0", onClickCapture: handleActionClick, children: _jsx(AppOpenActions, { name: app.name, href: trackedLaunchUrl, rel: "noopener noreferrer", showNewTabOption: true }) })] }));
33
+ return (_jsxs(AppListRow, { className: className, children: [_jsx(AppIcon, { id: app.id, name: app.name, color: app.color, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), _jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || app.url })] }), onTogglePinned ? (_jsx(AppPinButton, { appId: app.id, name: app.name, pinned: isPinned, onToggle: onTogglePinned })) : null, _jsx("div", { className: "flex shrink-0", onClickCapture: handleActionClick, children: _jsx(AppOpenActions, { name: app.name, href: trackedLaunchUrl, rel: "noopener noreferrer", showNewTabOption: true, external: app.source === "builtin", labels: appOpenActionLabels(t, app.name) }) })] }));
31
34
  }
32
35
  //# sourceMappingURL=connected-app-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAI/F,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GAIV;IACC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC;IACzC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,SAAS,EAAE;QAC/D,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,CAAC,KAAiC,EAAE,EAAE;QAC9D,IACE,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,KAAK,CAAC,OAAO;YACb,KAAK,CAAC,OAAO;YACb,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,MAAM,EACZ,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IACE,CAAC,MAAM;YACP,MAAM,CAAC,MAAM,KAAK,QAAQ;YAC1B,CAAC,iCAAiC,EAAE,EACpC,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,cAAc,EAAE,CAAC;IAClE,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,UAAU,IAAC,SAAS,EAAE,SAAS,aAC9B,KAAC,OAAO,IAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,GAAG,EACnE,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,gDAAgD,YAC5D,GAAG,CAAC,IAAI,GACL,EACN,cAAK,SAAS,EAAC,+CAA+C,YAC3D,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,GACvB,IACF,EACN,cAAK,SAAS,EAAC,eAAe,EAAC,cAAc,EAAE,iBAAiB,YAC9D,KAAC,cAAc,IACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAC,qBAAqB,EACzB,gBAAgB,SAChB,GACE,IACK,CACd,CAAC;AACJ,CAAC","sourcesContent":["import { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\nimport type { MouseEvent } from \"react\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport {\n navigateToWorkspaceApp,\n shouldOpenWorkspaceAppInTopWindow,\n} from \"../lib/workspace-apps\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppListRow } from \"./app-list-row\";\nimport { AppOpenActions } from \"./app-open-actions\";\n\nexport function ConnectedAppCard({\n app,\n className,\n}: {\n app: ConnectedAppSummary;\n className?: string;\n}) {\n const launchUrl = app.homeUrl ?? app.url;\n const trackedLaunchUrl = withBuilderUtmTrackingParams(launchUrl, {\n campaign: \"product\",\n content: \"dispatch_app\",\n });\n const handleActionClick = (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const anchor =\n event.target instanceof Element ? event.target.closest(\"a\") : null;\n if (\n !anchor ||\n anchor.target === \"_blank\" ||\n !shouldOpenWorkspaceAppInTopWindow()\n ) {\n return;\n }\n if (navigateToWorkspaceApp(anchor.href)) event.preventDefault();\n };\n\n return (\n <AppListRow className={className}>\n <AppIcon id={app.id} name={app.name} color={app.color} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {app.description || app.url}\n </div>\n </div>\n <div className=\"flex shrink-0\" onClickCapture={handleActionClick}>\n <AppOpenActions\n name={app.name}\n href={trackedLaunchUrl}\n rel=\"noopener noreferrer\"\n showNewTabOption\n />\n </div>\n </AppListRow>\n );\n}\n"]}
1
+ {"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAI/F,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,EACT,QAAQ,GAAG,KAAK,EAChB,cAAc,GAMf;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC;IACzC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,SAAS,EAAE;QAC/D,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,CAAC,KAAiC,EAAE,EAAE;QAC9D,IACE,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,KAAK,CAAC,OAAO;YACb,KAAK,CAAC,OAAO;YACb,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,MAAM,EACZ,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IACE,CAAC,MAAM;YACP,MAAM,CAAC,MAAM,KAAK,QAAQ;YAC1B,CAAC,iCAAiC,EAAE,EACpC,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,cAAc,EAAE,CAAC;IAClE,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,UAAU,IAAC,SAAS,EAAE,SAAS,aAC9B,KAAC,OAAO,IAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,GAAG,EACnE,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,gDAAgD,YAC5D,GAAG,CAAC,IAAI,GACL,EACN,cAAK,SAAS,EAAC,+CAA+C,YAC3D,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,GACvB,IACF,EACL,cAAc,CAAC,CAAC,CAAC,CAChB,KAAC,YAAY,IACX,KAAK,EAAE,GAAG,CAAC,EAAE,EACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,MAAM,EAAE,QAAQ,EAChB,QAAQ,EAAE,cAAc,GACxB,CACH,CAAC,CAAC,CAAC,IAAI,EACR,cAAK,SAAS,EAAC,eAAe,EAAC,cAAc,EAAE,iBAAiB,YAC9D,KAAC,cAAc,IACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAC,qBAAqB,EACzB,gBAAgB,QAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,EAClC,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GACxC,GACE,IACK,CACd,CAAC;AACJ,CAAC","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\nimport { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\nimport type { MouseEvent } from \"react\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport {\n navigateToWorkspaceApp,\n shouldOpenWorkspaceAppInTopWindow,\n} from \"../lib/workspace-apps\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppListRow } from \"./app-list-row\";\nimport { AppOpenActions, appOpenActionLabels } from \"./app-open-actions\";\nimport { AppPinButton } from \"./app-pin-button\";\n\nexport function ConnectedAppCard({\n app,\n className,\n isPinned = false,\n onTogglePinned,\n}: {\n app: ConnectedAppSummary;\n className?: string;\n isPinned?: boolean;\n onTogglePinned?: () => void;\n}) {\n const t = useT();\n const launchUrl = app.homeUrl ?? app.url;\n const trackedLaunchUrl = withBuilderUtmTrackingParams(launchUrl, {\n campaign: \"product\",\n content: \"dispatch_app\",\n });\n const handleActionClick = (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const anchor =\n event.target instanceof Element ? event.target.closest(\"a\") : null;\n if (\n !anchor ||\n anchor.target === \"_blank\" ||\n !shouldOpenWorkspaceAppInTopWindow()\n ) {\n return;\n }\n if (navigateToWorkspaceApp(anchor.href)) event.preventDefault();\n };\n\n return (\n <AppListRow className={className}>\n <AppIcon id={app.id} name={app.name} color={app.color} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {app.description || app.url}\n </div>\n </div>\n {onTogglePinned ? (\n <AppPinButton\n appId={app.id}\n name={app.name}\n pinned={isPinned}\n onToggle={onTogglePinned}\n />\n ) : null}\n <div className=\"flex shrink-0\" onClickCapture={handleActionClick}>\n <AppOpenActions\n name={app.name}\n href={trackedLaunchUrl}\n rel=\"noopener noreferrer\"\n showNewTabOption\n external={app.source === \"builtin\"}\n labels={appOpenActionLabels(t, app.name)}\n />\n </div>\n </AppListRow>\n );\n}\n"]}
@@ -10,5 +10,9 @@ export declare function CreateAppFlow({ onClose, onCreated, className, }: {
10
10
  className?: string;
11
11
  }): import("node_modules/@types/react").JSX.Element;
12
12
  export declare function CreateAppPopover({ trigger, align, onCreated, }: CreateAppPopoverProps): import("node_modules/@types/react").JSX.Element;
13
+ /** The "New app" button every app list puts beside its search. */
14
+ export declare function NewAppButton({ onCreated, }: {
15
+ onCreated?: (() => void) | undefined;
16
+ }): import("node_modules/@types/react").JSX.Element;
13
17
  export {};
14
18
  //# sourceMappingURL=create-app-popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AA4BA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8BrE,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAwCD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,SAAc,GACf,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAkhBA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAgB,EAChB,SAAS,GACV,EAAE,qBAAqB,mDA6BvB"}
1
+ {"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8BrE,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAwCD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,SAAc,GACf,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAkhBA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAgB,EAChB,SAAS,GACV,EAAE,qBAAqB,mDA6BvB;AA0BD,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,EAC3B,SAAS,GACV,EAAE;IACD,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACtC,mDAcA"}
@@ -3,6 +3,7 @@ import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
3
3
  import { useDevMode } from "@agent-native/core/client/agent-chat";
4
4
  import { agentNativePath, appBasePath, } from "@agent-native/core/client/api-path";
5
5
  import { isInBuilderFrame } from "@agent-native/core/client/host";
6
+ import { useT } from "@agent-native/core/client/i18n";
6
7
  import { buildChatFirstAppCreationPrompt, docsUrl, getWorkspaceAppIdValidationError, titleFromChatFirstAppPrompt, } from "@agent-native/core/shared";
7
8
  import { PromptComposer } from "@agent-native/toolkit/app/chat/composer/index";
8
9
  import { BuilderConnectPopover } from "@agent-native/toolkit/app/settings";
@@ -271,4 +272,9 @@ function CreateAppPopoverBody({ onClose, onCreated, }) {
271
272
  return _jsx(BuildInBuilderPanel, { url: builderWorkspaceUrl });
272
273
  return (_jsx(CreateAppFlow, { onClose: onClose, ...(onCreated ? { onCreated } : {}) }));
273
274
  }
275
+ /** The "New app" button every app list puts beside its search. */
276
+ export function NewAppButton({ onCreated, }) {
277
+ const t = useT();
278
+ return (_jsx(CreateAppPopover, { align: "end", ...(onCreated ? { onCreated } : {}), trigger: _jsxs(Button, { type: "button", variant: "default", size: "sm", className: "gap-1.5", children: [_jsx(IconPlus, { size: 14, "aria-hidden": "true" }), t("dispatch.pages.newApp")] }) }));
279
+ }
274
280
  //# sourceMappingURL=create-app-popover.js.map