@nextclaw/ui 0.26.5 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/.vite/manifest.json +1342 -1227
  3. package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-BT0_ycaq.js} +1 -1
  4. package/dist/assets/account-panel-BVNV8XqM.js +1 -0
  5. package/dist/assets/agents-CfpN8PQc.js +1 -0
  6. package/dist/assets/agents-E4nu-17c.js +1 -0
  7. package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.js → aiden0z-pptx-renderer.es-ClCaf_Wh.js} +1 -1
  8. package/dist/assets/api-CI6_8Qt1.js +20 -0
  9. package/dist/assets/app-presenter-provider-2DwHRRle.js +28 -0
  10. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
  11. package/dist/assets/appearance-settings-page-Cn9w3F-K.js +1 -0
  12. package/dist/assets/apps-YFlJirpx.js +1 -0
  13. package/dist/assets/{arc-DBRedCax.js → arc-cmSdpq1Z.js} +1 -1
  14. package/dist/assets/architecture-TIHT7OUA-BImoGh10.js +1 -0
  15. package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-aYglVeoS.js} +1 -1
  16. package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-Di_PBl5q.js} +1 -1
  17. package/dist/assets/{book-open-Bcnn2_uV.js → book-open-i_BjUBqL.js} +1 -1
  18. package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CfuxybOL.js} +1 -1
  19. package/dist/assets/{card-Cqs73hGI.js → card-DokH7OBp.js} +1 -1
  20. package/dist/assets/channel-BDQry0ob.js +1 -0
  21. package/dist/assets/channels-list-page-B7G9lHUm.js +8 -0
  22. package/dist/assets/chunk-2Q5K7J3B-DkgSFfIy.js +1 -0
  23. package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-CCGc4qg4.js} +1 -1
  24. package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-aJoxU2Ow.js} +1 -1
  25. package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-CGwtZSax.js} +1 -1
  26. package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-DqaMSMeS.js} +1 -1
  27. package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-DnabINcd.js} +1 -1
  28. package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BhpKv1k2.js} +1 -1
  29. package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DvkRPit_.js} +1 -1
  30. package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CgDQOLnC.js} +1 -1
  31. package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-9FEv5b7T.js} +1 -1
  32. package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-CNGFAFYL.js} +1 -1
  33. package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DovTZx0M.js} +1 -1
  34. package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-DpLEgYa1.js} +1 -1
  35. package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D4NuN01W.js} +1 -1
  36. package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-D8Jf4kc2.js} +1 -1
  37. package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-BdHymAs0.js} +2 -2
  38. package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-Dd_Ycn9Z.js} +1 -1
  39. package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-BRPUu3ff.js} +1 -1
  40. package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DnCasQja.js} +1 -1
  41. package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-C3CkbEj1.js} +1 -1
  42. package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-Pi--K4-1.js} +1 -1
  43. package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-3VTspvlh.js} +1 -1
  44. package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-BetLLyJt.js} +1 -1
  45. package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-D1VcupAj.js} +1 -1
  46. package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-Cy4G8SjV.js} +1 -1
  47. package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-UYxXzi7_.js} +1 -1
  48. package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-CHiGeRY1.js} +1 -1
  49. package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-C5kVJus8.js} +1 -1
  50. package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-C6cuuEBn.js} +1 -1
  51. package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-CM0EK7Y0.js} +1 -1
  52. package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DWJZIsME.js} +1 -1
  53. package/dist/assets/chunk-VAUOI2AC-CsTIB8qD.js +1 -0
  54. package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-CY5KYeEi.js} +1 -1
  55. package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-B30N3ZP8.js} +3 -3
  56. package/dist/assets/chunk-XXDRQBXY-DK6dz0Q3.js +1 -0
  57. package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-CBu82JpO.js} +1 -1
  58. package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BN5NX5qA.js} +1 -1
  59. package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DcDXK29L.js} +1 -1
  60. package/dist/assets/{circle-dashed-EY1ScSMe.js → circle-dashed-Cx8CIEbg.js} +1 -1
  61. package/dist/assets/classDiagram-OUVF2IWQ-BYygHCrp.js +1 -0
  62. package/dist/assets/classDiagram-v2-EOCWNBFH-BgQ0XKYz.js +1 -0
  63. package/dist/assets/{client-CH7w6yRV.js → client-CUJUci3r.js} +1 -1
  64. package/dist/assets/config-split-page-hY1xug28.js +1 -0
  65. package/dist/assets/confirm-dialog-B-ejV666.js +1 -0
  66. package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
  67. package/dist/assets/context-menu-dGVv8klA.js +211 -0
  68. package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-CmeJVoTw.js} +1 -1
  69. package/dist/assets/{createLucideIcon-Cfo2ySi5.js → createLucideIcon-reFMl-W-.js} +1 -1
  70. package/dist/assets/cron-CH5c55CR.js +1 -0
  71. package/dist/assets/cynefin-VYW2F7L2-DKbotNWS.js +1 -0
  72. package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DGOUMgPP.js} +1 -1
  73. package/dist/assets/{dagre-CrgsRasE.js → dagre-CMxSkbJJ.js} +1 -1
  74. package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-3YUBEXwo.js} +1 -1
  75. package/dist/assets/{desktop-capabilities-page-BDYITStl.js → desktop-capabilities-page-CYJTQ3nC.js} +1 -1
  76. package/dist/assets/desktop-update-config-guKAozXO.js +1 -0
  77. package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-Br1g--ww.js} +1 -1
  78. package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D1wJCBgr.js} +1 -1
  79. package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-Cgg2auLH.js} +1 -1
  80. package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-R-wHiWqh.js} +1 -1
  81. package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-CsNnKV0P.js} +1 -1
  82. package/dist/assets/dialog-DLOwdjT1.js +1 -0
  83. package/dist/assets/dist-ZaFFmAGl.js +41 -0
  84. package/dist/assets/doc-browser-ClDUWo9V.js +1 -0
  85. package/dist/assets/doc-browser-context-CTmOmuqa.js +1 -0
  86. package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-kPn_EtAr.js} +1 -1
  87. package/dist/assets/{download-BoaKzDJk.js → download-DovI3Yvf.js} +1 -1
  88. package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-DCyhIPdi.js} +1 -1
  89. package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-D0ZJYAUf.js} +1 -1
  90. package/dist/assets/eventmodeling-45OFAUF4-SIhbIFIw.js +1 -0
  91. package/dist/assets/extensions-BZ3qrM8M.js +1 -0
  92. package/dist/assets/external-link-DUD3AbsF.js +1 -0
  93. package/dist/assets/flowDiagram-23GEKE2U-DdAjkU7I.js +1 -0
  94. package/dist/assets/{form-actions-D9JWSFQu.js → form-actions-B8VniHts.js} +1 -1
  95. package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-CiXDcXZD.js} +1 -1
  96. package/dist/assets/gitGraph-TEB2WS4Q-DnMNpESZ.js +1 -0
  97. package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-BSiIV48S.js} +1 -1
  98. package/dist/assets/{i18n-Bm3Ov7Fy.js → i18n-IGQbjBqS.js} +2 -2
  99. package/dist/assets/inbox-BjBZIbgx.js +1 -0
  100. package/dist/assets/inbox-ClAG7SI_.js +1 -0
  101. package/dist/assets/info-DKCQHKI2-BSm-69p_.js +1 -0
  102. package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-CCIgBCVq.js} +1 -1
  103. package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-nQ_baN5u.js} +1 -1
  104. package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-ABueIPzj.js} +1 -1
  105. package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-8FKS3fmQ.js} +1 -1
  106. package/dist/assets/katex-DPgHtix3.js +1 -0
  107. package/dist/assets/keyboard-shortcuts-settings-page-BqfbbKir.js +1 -0
  108. package/dist/assets/{line-D_bHubTL.js → line-Biw8iEUz.js} +1 -1
  109. package/dist/assets/{linear-ChlwuS5y.js → linear-D7CWUHTF.js} +1 -1
  110. package/dist/assets/login-page-BxSMwUsc.js +1 -0
  111. package/dist/assets/{login-page-C-DvcG3L.js → login-page-DYaozpzz.js} +1 -1
  112. package/dist/assets/main-CWYF9QU_.js +2 -0
  113. package/dist/assets/main-D_zmSVS1.css +1 -0
  114. package/dist/assets/main-i18n-catalog.config-itg3Gvzp.js +1 -0
  115. package/dist/assets/{map-oGHTsIu8.js → map-CDu47gTf.js} +1 -1
  116. package/dist/assets/marketplace-CnQ5USfr.js +1 -0
  117. package/dist/assets/mcp-marketplace-page-Dor6H9IC.js +1 -0
  118. package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-Cc9wjl82.js} +2 -2
  119. package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-GWlaVWz1.js} +3 -3
  120. package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-oqnKsz-R.js} +1 -1
  121. package/dist/assets/model-config-page-Cduyz2Hy.js +1 -0
  122. package/dist/assets/{navigation-link-CjxNC8aT.js → navigation-link-D-JSWFxj.js} +2 -2
  123. package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-DImbxqBz.js} +1 -1
  124. package/dist/assets/packet-7NZHBO7P-1YQvC6mT.js +1 -0
  125. package/dist/assets/panel-app-BBTg0tVp.js +1 -0
  126. package/dist/assets/panel-app-i18n-catalog.config-BfLHr1tc.js +1 -0
  127. package/dist/assets/panel-apps-C-izvtu9.js +1 -0
  128. package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
  129. package/dist/assets/panelStandalone-oHxbXvYt.js +2 -0
  130. package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-DYAB8CEz.js} +1 -1
  131. package/dist/assets/pie-RZYD4A2V-BGoNOSwu.js +1 -0
  132. package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-DGsH0Kk5.js} +1 -1
  133. package/dist/assets/plus-DUdl68Eo.js +1 -0
  134. package/dist/assets/privacy-settings-page-DG9E8N-F.js +1 -0
  135. package/dist/assets/projects-CzBaTOTL.js +1 -0
  136. package/dist/assets/provider-models-COzjYl29.js +1 -0
  137. package/dist/assets/provider-scoped-model-input-Cvy74uj8.js +1 -0
  138. package/dist/assets/providers-config-page-7rCwVnhh.js +1 -0
  139. package/dist/assets/puzzle-C5Wfpjk_.js +1 -0
  140. package/dist/assets/pwa-CAg_9zFs.js +1 -0
  141. package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-BegGcT3l.js} +1 -1
  142. package/dist/assets/radar-I7S5WNFK-uPku9RRq.js +1 -0
  143. package/dist/assets/railroad-3IZDKUUU-DHnmbuIo.js +1 -0
  144. package/dist/assets/railroad-abnf-AHOZXSZD-DiZs--Iw.js +1 -0
  145. package/dist/assets/railroad-ebnf-EBAXGLYW-Nr53gnNE.js +1 -0
  146. package/dist/assets/railroad-peg-LSFZ7HO6-Cm_PuwJS.js +1 -0
  147. package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-B3yJ2yxE.js} +1 -1
  148. package/dist/assets/{refresh-cw-BlXDrVP0.js → refresh-cw-OhwaPDn1.js} +1 -1
  149. package/dist/assets/remote-DvCdHjzA.js +1 -0
  150. package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-DtEyoEXG.js} +1 -1
  151. package/dist/assets/{rotate-cw-ei6rPD6z.js → rotate-cw-aBponvp7.js} +1 -1
  152. package/dist/assets/runtime-config-page-BF1wxvzR.js +1 -0
  153. package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-h9AYS2UB.js} +1 -1
  154. package/dist/assets/{save-DdF-bXgC.js → save-394QCMXn.js} +1 -1
  155. package/dist/assets/search-BG2qAlNZ.js +1 -0
  156. package/dist/assets/search-config-page-D4LeiB9y.js +1 -0
  157. package/dist/assets/secrets-config-page-BzGcr5Vw.js +3 -0
  158. package/dist/assets/security-config-vD_V0BQF.js +1 -0
  159. package/dist/assets/select-xUXYV0Gr.js +1 -0
  160. package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-D-uxCkob.js} +1 -1
  161. package/dist/assets/service-apps-panel-D3wwPRzV.js +1 -0
  162. package/dist/assets/{settings-2-CrNhfInU.js → settings-2-CWOGRRaA.js} +1 -1
  163. package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-DBzZytQo.js} +1 -1
  164. package/dist/assets/{src-C8AUg09O.js → src-zrGbZsfc.js} +1 -1
  165. package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-DyDy7AHq.js} +1 -1
  166. package/dist/assets/stateDiagram-v2-6OUMAXLB-CtkpO6aA.js +1 -0
  167. package/dist/assets/{status-dot-C3SRFEta.js → status-dot-CYifnSnt.js} +1 -1
  168. package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BzOduS38.js} +2 -2
  169. package/dist/assets/swimlanesDiagram-G3AALYLV-BSdi6mvi.js +8 -0
  170. package/dist/assets/tag-chip-CjM6lyeh.js +1 -0
  171. package/dist/assets/theme-provider-BToFZGZG.js +1 -0
  172. package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-CmgnEF2t.js} +1 -1
  173. package/dist/assets/trash-2-DvJ6duOW.js +1 -0
  174. package/dist/assets/treeView-QDETBFTQ-DBoqypPR.js +1 -0
  175. package/dist/assets/treemap-6X3UGDF4-BMeL3P0q.js +1 -0
  176. package/dist/assets/use-config-COusaY5p.js +1 -0
  177. package/dist/assets/{use-desktop-capabilities-BYDjFlpt.js → use-desktop-capabilities-B-u6ojjW.js} +1 -1
  178. package/dist/assets/use-viewport-layout-IKKGpjzF.js +1 -0
  179. package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-DwS7D2kg.js} +1 -1
  180. package/dist/assets/wardley-OPB4EBWU-Dqxe7zN6.js +1 -0
  181. package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-B4X8OOL4.js} +1 -1
  182. package/dist/assets/x-E9VB4HQx.js +1 -0
  183. package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-BjRQ_0nx.js} +1 -1
  184. package/dist/index.html +44 -106
  185. package/dist/panel-standalone.html +19 -13
  186. package/index.html +15 -66
  187. package/package.json +5 -5
  188. package/src/app/styles/design-system.css +85 -1
  189. package/src/app/styles/island-theme.css +8 -6
  190. package/src/features/agents/components/__tests__/agents-page.test.tsx +8 -5
  191. package/src/features/agents/components/agent-details-dialog.tsx +24 -18
  192. package/src/features/agents/components/agents-page.tsx +27 -38
  193. package/src/features/app-data/components/app-retained-data-section.tsx +4 -4
  194. package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
  195. package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
  196. package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
  197. package/src/features/apps/components/app-document-access-section.tsx +17 -14
  198. package/src/features/apps/components/app-marketplace-catalog.tsx +69 -42
  199. package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
  200. package/src/features/apps/components/app-marketplace-detail.tsx +20 -8
  201. package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
  202. package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
  203. package/src/features/apps/components/app-package-card.tsx +224 -147
  204. package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
  205. package/src/features/apps/components/app-packages-panel.tsx +162 -147
  206. package/src/features/apps/components/apps-panel.tsx +43 -12
  207. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
  208. package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
  209. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
  210. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
  211. package/src/features/chat/components/providers/chat-runtime.provider.tsx +1 -1
  212. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +0 -1
  213. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +13 -2
  214. package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
  215. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +9 -1
  216. package/src/features/chat/features/conversation/components/session-conversation-input-top-slot.tsx +44 -0
  217. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +4 -38
  218. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +86 -10
  219. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +44 -1
  220. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +85 -73
  221. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +5 -15
  222. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +53 -13
  223. package/src/features/chat/features/conversation/hooks/use-session-submission-recovery.ts +83 -0
  224. package/src/features/chat/features/conversation/types/session-conversation-input.types.ts +38 -0
  225. package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +1 -29
  226. package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +1 -8
  227. package/src/features/chat/features/message/components/__tests__/chat-message-list-skill-preview.container.test.tsx +14 -1
  228. package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +7 -2
  229. package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
  230. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
  231. package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
  232. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
  233. package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
  234. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
  235. package/src/features/chat/features/session/utils/__tests__/chat-session-route.utils.test.ts +26 -0
  236. package/src/features/chat/features/session/utils/chat-session-preference-governance.utils.ts +14 -8
  237. package/src/features/chat/features/session/utils/chat-session-route.utils.ts +9 -12
  238. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
  239. package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
  240. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
  241. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
  242. package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
  243. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
  244. package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
  245. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
  246. package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
  247. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.selection.test.tsx +14 -2
  248. package/src/features/chat/features/workspace/components/__tests__/session-cron-job-content.test.tsx +5 -1
  249. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
  250. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -7
  251. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +6 -5
  252. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
  253. package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
  254. package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
  255. package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
  256. package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
  257. package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
  258. package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +13 -26
  259. package/src/features/chat/index.ts +1 -0
  260. package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +37 -47
  261. package/src/features/chat/pages/ncp-chat-page.tsx +3 -3
  262. package/src/features/chat/stores/__tests__/chat-composer-draft.store.test.ts +67 -1
  263. package/src/features/chat/stores/chat-composer-draft.store.ts +230 -29
  264. package/src/features/cron/components/__tests__/cron-config.test.tsx +8 -2
  265. package/src/features/cron/components/cron-config.tsx +6 -17
  266. package/src/features/cron/components/cron-job-detail-dialog.tsx +10 -9
  267. package/src/features/cron/components/cron-job-resource.tsx +51 -0
  268. package/src/features/cron/components/cron-job-row.tsx +5 -4
  269. package/src/features/cron/index.ts +1 -0
  270. package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
  271. package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
  272. package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
  273. package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
  274. package/src/features/inbox/managers/inbox.manager.ts +18 -4
  275. package/src/features/inbox/pages/inbox-page.test.ts +4 -2
  276. package/src/features/inbox/pages/inbox-page.tsx +14 -10
  277. package/src/features/marketplace/components/__tests__/marketplace-page-detail.test.tsx +1 -0
  278. package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +1 -0
  279. package/src/features/marketplace/components/mcp/__tests__/mcp-marketplace-page.test.tsx +2 -0
  280. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
  281. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +23 -1
  282. package/src/features/marketplace/hooks/use-marketplace-item-detail.ts +11 -0
  283. package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
  284. package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
  285. package/src/features/panel-apps/index.ts +1 -0
  286. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
  287. package/src/features/projects/components/work/project-work-item-drawer.tsx +7 -10
  288. package/src/features/projects/components/work/project-work-items.tsx +1 -1
  289. package/src/features/projects/pages/project-home-page.tsx +18 -23
  290. package/src/features/projects/pages/projects-page.test.tsx +4 -1
  291. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
  292. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
  293. package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
  294. package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +74 -6
  295. package/src/features/right-panel-resources/components/native-object-resource.tsx +134 -0
  296. package/src/features/right-panel-resources/components/page-resource-icon.tsx +16 -8
  297. package/src/features/right-panel-resources/components/system-object-resource.tsx +66 -1
  298. package/src/features/right-panel-resources/components/workspace-file-resource.tsx +9 -0
  299. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +11 -21
  300. package/src/features/right-panel-resources/index.ts +3 -0
  301. package/src/features/right-panel-resources/managers/__tests__/page-resource.manager.test.ts +14 -4
  302. package/src/features/right-panel-resources/managers/page-resource.manager.ts +38 -21
  303. package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +17 -0
  304. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
  305. package/src/features/service-apps/components/service-action-row.tsx +4 -3
  306. package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
  307. package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
  308. package/src/features/service-apps/components/service-apps-panel.tsx +5 -2
  309. package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
  310. package/src/features/settings/pages/providers-config-page.tsx +3 -2
  311. package/src/index.css +42 -8
  312. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +16 -0
  313. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +2 -2
  314. package/src/shared/components/doc-browser/__tests__/resource-link-interceptor.test.tsx +29 -1
  315. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
  316. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +13 -7
  317. package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +2 -1
  318. package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
  319. package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
  320. package/src/shared/components/ui/actions/action-feedback.ts +1 -8
  321. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  322. package/src/shared/components/ui/confirm-dialog.tsx +1 -2
  323. package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
  324. package/src/shared/components/ui/dialog.tsx +29 -7
  325. package/src/shared/components/ui/popover.tsx +14 -3
  326. package/src/shared/components/ui/skeleton.tsx +16 -2
  327. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -2
  328. package/src/shared/components/ui/tooltip.tsx +2 -1
  329. package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
  330. package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
  331. package/src/shared/components/workbench/workbench-surface.tsx +4 -1
  332. package/src/shared/lib/i18n/locales/en-US/chat.json +21 -7
  333. package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
  334. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
  335. package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
  336. package/src/shared/lib/i18n/locales/zh-CN/chat.json +21 -7
  337. package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
  338. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
  339. package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
  340. package/src/shared/lib/theme/index.test.ts +28 -1
  341. package/src/shared/lib/theme/index.ts +14 -3
  342. package/src/shared/lib/transport/__tests__/local-transport.service.test.ts +24 -0
  343. package/src/shared/lib/transport/local-transport.service.ts +8 -6
  344. package/dist/assets/account-panel-BAH7FW6z.js +0 -1
  345. package/dist/assets/api-DjiZvIa0.js +0 -20
  346. package/dist/assets/app-presenter-provider-CCRFsFYr.js +0 -232
  347. package/dist/assets/appearance-settings-page-CdP86QJ7.js +0 -1
  348. package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
  349. package/dist/assets/channel-CpMstUPF.js +0 -1
  350. package/dist/assets/channels-list-page-5qGagKuE.js +0 -8
  351. package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
  352. package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
  353. package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
  354. package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
  355. package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
  356. package/dist/assets/config-split-page-CuEGQL8Z.js +0 -1
  357. package/dist/assets/confirm-dialog-CxfecBzO.js +0 -1
  358. package/dist/assets/context-menu-BsCj2fRs.js +0 -1
  359. package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
  360. package/dist/assets/desktop-update-config-e-zhkJuS.js +0 -1
  361. package/dist/assets/dialog-QjQoKbIV.js +0 -5
  362. package/dist/assets/doc-browser-CLEdkH9z.js +0 -1
  363. package/dist/assets/doc-browser-context-DwgG6wrz.js +0 -1
  364. package/dist/assets/es2015-Bp6cuSGh.js +0 -41
  365. package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
  366. package/dist/assets/extensions-CgShSIkd.js +0 -1
  367. package/dist/assets/eye-kisejBFH.js +0 -1
  368. package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
  369. package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
  370. package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
  371. package/dist/assets/katex-B4FQSo9k.js +0 -1
  372. package/dist/assets/keyboard-shortcuts-settings-page-DZ8A1iLg.js +0 -1
  373. package/dist/assets/loader-circle-Bd1fTm-x.js +0 -1
  374. package/dist/assets/login-page-D99JjH9F.js +0 -1
  375. package/dist/assets/main-Bt5r6b21.js +0 -2
  376. package/dist/assets/main-DXd_aKJV.css +0 -1
  377. package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +0 -1
  378. package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +0 -1
  379. package/dist/assets/model-config-page-9NNf-mzK.js +0 -1
  380. package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
  381. package/dist/assets/panel-app-BYfQu_TS.js +0 -1
  382. package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +0 -1
  383. package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
  384. package/dist/assets/panelStandalone-BaUzY8Wy.js +0 -2
  385. package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
  386. package/dist/assets/privacy-settings-page-CVMBFuak.js +0 -1
  387. package/dist/assets/projects-BEsU3box.js +0 -1
  388. package/dist/assets/provider-models-Dm-pmWAA.js +0 -1
  389. package/dist/assets/provider-scoped-model-input-CzrXg4cX.js +0 -1
  390. package/dist/assets/providers-config-page-839uUADZ.js +0 -1
  391. package/dist/assets/puzzle-BGvD2DPZ.js +0 -1
  392. package/dist/assets/pwa-DNNK_8E9.js +0 -1
  393. package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
  394. package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
  395. package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
  396. package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
  397. package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
  398. package/dist/assets/remote-B5qIuUbT.js +0 -1
  399. package/dist/assets/runtime-config-page-Bf-4JYxQ.js +0 -1
  400. package/dist/assets/search-config-page-C0qA3j-T.js +0 -1
  401. package/dist/assets/secrets-config-page-DxfZWpnk.js +0 -3
  402. package/dist/assets/security-config-CItfIQZ4.js +0 -1
  403. package/dist/assets/select-CWyjnar7.js +0 -1
  404. package/dist/assets/service-apps-panel-D3SOkRVv.js +0 -1
  405. package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
  406. package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
  407. package/dist/assets/tag-chip-BIuavK2K.js +0 -1
  408. package/dist/assets/theme-provider-CWUz4yO9.js +0 -1
  409. package/dist/assets/trash-2-hAbJh9VZ.js +0 -1
  410. package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
  411. package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
  412. package/dist/assets/use-config-evzage09.js +0 -1
  413. package/dist/assets/use-viewport-layout-D_9XWGDV.js +0 -1
  414. package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
  415. package/dist/assets/x-ChPbNv39.js +0 -1
  416. package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
  417. /package/dist/assets/{array-BV9OtnO8.js → array-DsNX3jRj.js} +0 -0
  418. /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-BOAXXeyv.js} +0 -0
  419. /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-CHjSjwoV.js} +0 -0
  420. /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-CaB3I7KP.js} +0 -0
  421. /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-j4J9a91l.js} +0 -0
  422. /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-Bmxjp-V_.js} +0 -0
  423. /package/dist/assets/{dist-BVCSkfWY.js → dist-DwLj1Wg5.js} +0 -0
  424. /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-CC0HTn1v.js} +0 -0
  425. /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-B107nwS3.js} +0 -0
  426. /package/dist/assets/{init-BF6GH5oe.js → init-Biz9Rus1.js} +0 -0
  427. /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-DQvBVV_R.js} +0 -0
  428. /package/dist/assets/{katex-CsAM73R9.js → katex-BzT-4KBu.js} +0 -0
  429. /package/dist/assets/{navigation-history-CzErJuPG.js → navigation-history-CCnxsAKR.js} +0 -0
  430. /package/dist/assets/{path-C56XkznJ.js → path-4azsBPZv.js} +0 -0
  431. /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  432. /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-w1lBArN6.js} +0 -0
  433. /package/dist/assets/{xlsx-sds5nUpL.js → xlsx--SB9KlFl.js} +0 -0
@@ -1,5 +1,4 @@
1
1
  import { useRef, useState } from "react";
2
- import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
3
2
  import type { AppDataEntry, AppPackageOperationView, AppPackageView } from "@nextclaw/client-sdk";
4
3
  import {
5
4
  AlertCircle,
@@ -9,27 +8,33 @@ import {
9
8
  CheckSquare2,
10
9
  ChevronRight,
11
10
  MoreVertical,
11
+ Info,
12
+ Power,
12
13
  NotebookText,
13
14
  RefreshCw,
14
15
  RotateCcw,
15
- Server,
16
16
  Trash2,
17
17
  LoaderCircle,
18
- HardDrive,
19
- ShieldAlert,
20
- ShieldCheck,
21
18
  type LucideIcon,
22
19
  } from "lucide-react";
23
20
  import { AppArtwork } from "@/features/apps/components/app-artwork";
24
- import { AppDocumentAccessSection } from "@/features/apps/components/app-document-access-section";
25
- import { AppDataRemovalChoice, AppStorageUsageDetails, formatBytes } from "@/features/app-data";
21
+ import { AppPackageDetailsDialog } from "@/features/apps/components/app-package-details-dialog";
22
+ import { AppDataRemovalChoice, AppStorageUsageDetails } from "@/features/app-data";
26
23
  import { isAppPackageOperationActive } from "@/features/apps/hooks/use-app-packages";
27
24
  import { readAppPackageAvailability } from "@/features/apps/utils/app-package-readiness.utils";
28
25
  import type { PanelAppEntryView } from "@/shared/lib/api";
29
26
  import { Button } from "@/shared/components/ui/button";
27
+ import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
30
28
  import { Card } from "@/shared/components/ui/card";
31
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/shared/components/ui/dialog";
32
- import { Popover, PopoverContent, PopoverTrigger } from "@/shared/components/ui/popover";
29
+ import {
30
+ Dialog,
31
+ DialogContent,
32
+ DialogDescription,
33
+ DialogFooter,
34
+ DialogHeader,
35
+ DialogTitle,
36
+ } from "@/shared/components/ui/dialog";
37
+ import { ContextMenu, ContextMenuTrigger } from "@/shared/components/ui/context-menu/context-menu";
33
38
  import { getLanguage, t } from "@/shared/lib/i18n";
34
39
  import { cn } from "@/shared/lib/utils";
35
40
 
@@ -64,29 +69,49 @@ export function AppPackageCard({
64
69
  storageUsageUnavailable: boolean;
65
70
  unavailableMessage?: string;
66
71
  }) {
67
- const [menuOpen, setMenuOpen] = useState(false);
72
+ const [detailsOpen, setDetailsOpen] = useState(false);
73
+ const detailsTriggerRef = useRef<HTMLButtonElement>(null);
68
74
  const [uninstallOpen, setUninstallOpen] = useState(false);
69
75
  const [purgeData, setPurgeData] = useState(false);
70
- const skipMenuFocusRestoreRef = useRef(false);
71
76
  const uninstallCancelRef = useRef<HTMLButtonElement>(null);
72
77
  const panelComponents = appPackage.components.filter((component) => component.kind === "panel");
73
- const serviceCount = appPackage.components.length - panelComponents.length;
74
78
  const rollbackVersions = appPackage.installedVersions.filter((version) => version !== appPackage.activeVersion);
75
79
  const displayName = readLocalizedText(appPackage.name, appPackage.nameI18n) ?? appPackage.id;
76
80
  const displayDescription = readLocalizedText(appPackage.description, appPackage.descriptionI18n);
77
81
  const operationActive = operation ? isAppPackageOperationActive(operation.status) : false;
78
82
  const pending = isPending || operationActive;
79
83
  const availability = readAppPackageAvailability(appPackage, unavailableMessage);
80
- const storageUsageLabel = resolveStorageUsageLabel(storageUsage, storageUsageLoading, storageUsageUnavailable);
84
+ const singlePanel =
85
+ panelComponents.length === 1 ? panelApps.find((entry) => entry.appId === panelComponents[0].id) : undefined;
86
+ const primaryAction = !appPackage.enabled ? "enable" : panelComponents.length === 1 ? "open" : "details";
87
+ const primaryDisabled =
88
+ pending || (primaryAction !== "details" && !availability.interactive) || (primaryAction === "open" && !singlePanel);
89
+ const primaryLabel = { enable: "appPackagesEnable", open: "appPackagesOpen", details: "appPackagesDetails" } as const;
81
90
 
82
91
  return (
83
- <Card surface="flat" hover={false} className="overflow-hidden border-border/60 shadow-[0_1px_2px_rgba(0,0,0,0.025)]">
84
- <div className="flex max-md:grid max-md:grid-cols-[auto_minmax(0,1fr)] items-start gap-3.5 px-4 pb-3.5 pt-4">
92
+ <Card
93
+ surface="flat"
94
+ hover={false}
95
+ className="[container-type:inline-size] overflow-hidden rounded-none border-0 shadow-none"
96
+ >
97
+ <div className="grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3 px-3 py-4">
85
98
  <AppArtwork icon={appPackage.icon} name={displayName} />
86
99
  <div className="min-w-0 flex-1">
87
- <div className="flex min-w-0 items-center gap-2">
88
- <h2 className="truncate max-md:whitespace-normal max-md:break-words text-sm font-semibold text-foreground">{displayName}</h2>
89
- <span className={cn("shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium", availability.className)}>{availability.label}</span>
100
+ <div className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1">
101
+ <h2 className="min-w-0 max-w-full text-sm font-semibold text-foreground">
102
+ <button
103
+ ref={detailsTriggerRef}
104
+ type="button"
105
+ onClick={() => setDetailsOpen(true)}
106
+ className="block max-w-full truncate rounded-sm text-left hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
107
+ title={displayName}
108
+ >
109
+ {displayName}
110
+ </button>
111
+ </h2>
112
+ <span className={cn("shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium", availability.className)}>
113
+ {availability.label}
114
+ </span>
90
115
  </div>
91
116
  {availability.message ? (
92
117
  <p role="alert" className={cn("mt-2 text-xs leading-5", availability.messageClassName)}>
@@ -103,109 +128,119 @@ export function AppPackageCard({
103
128
  ))}
104
129
  </ul>
105
130
  ) : null}
106
- {displayDescription ? <p className="mt-1 line-clamp-2 text-xs leading-5 text-muted-foreground">{displayDescription}</p> : null}
107
- <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-muted-foreground/75">
108
- <span>v{appPackage.activeVersion}</span>
109
- {appPackage.builtIn ? <span>{t("appPackagesBuiltIn")}</span> : null}
110
- {serviceCount > 0 ? (
111
- <span className="inline-flex items-center gap-1">
112
- <Server className="h-3 w-3" />
113
- {t("appPackagesLocalService")}
114
- </span>
115
- ) : null}
116
- <span className={cn("inline-flex items-center gap-1", appPackage.isolation === "full-user" && "text-amber-700 dark:text-amber-300")}>
117
- {appPackage.isolation === "full-user" ? <ShieldAlert className="h-3 w-3" /> : <ShieldCheck className="h-3 w-3" />}
118
- {appPackage.isolation === "full-user" ? t("appPackagesIsolationFullUser") : appPackage.isolation === "host-mediated" ? t("appPackagesIsolationMediated") : t("appPackagesIsolationPanel")}
119
- </span>
120
- </div>
121
- <div className="mt-2 flex min-w-0 items-center gap-1.5 rounded-md bg-muted/35 px-2 py-1 text-[10px] text-muted-foreground" title={appPackage.storage.dataDirectory}>
122
- <HardDrive className="h-3 w-3 shrink-0" />
123
- <span className="shrink-0">
124
- {t("appPackagesDataUsage")} {storageUsageLabel}
125
- </span>
126
- <code className="min-w-0 truncate font-mono text-[10px]">{appPackage.storage.dataDirectory}</code>
127
- </div>
131
+ {displayDescription ? (
132
+ <p className="mt-1 line-clamp-2 text-xs leading-5 text-muted-foreground">{displayDescription}</p>
133
+ ) : null}
128
134
  </div>
129
- <div className="flex shrink-0 items-center gap-1 max-md:col-start-2 max-md:justify-end">
135
+ <div className="flex shrink-0 items-center justify-end gap-1">
130
136
  <Button
131
137
  type="button"
132
138
  size="sm"
133
- variant={appPackage.enabled ? "outline" : "default"}
134
- disabled={pending || !availability.interactive}
139
+ variant="outline"
140
+ disabled={primaryDisabled}
135
141
  title={availability.message}
136
- onClick={appPackage.enabled ? onDisable : onEnable}
142
+ onClick={() => {
143
+ if (!appPackage.enabled) onEnable();
144
+ else if (singlePanel) onOpenPanelApp(singlePanel);
145
+ else setDetailsOpen(true);
146
+ }}
137
147
  >
138
- {renderPrimaryActionLabel({
139
- enabled: appPackage.enabled,
140
- isPending,
141
- operation,
142
- operationActive,
143
- })}
148
+ {pending
149
+ ? renderPrimaryActionLabel({ enabled: appPackage.enabled, isPending, operation, operationActive })
150
+ : t(primaryLabel[primaryAction])}
144
151
  </Button>
145
- <Popover open={menuOpen} onOpenChange={setMenuOpen}>
146
- <PopoverTrigger asChild>
147
- <button
148
- type="button"
149
- aria-label={t("appPackagesMoreActions")}
150
- title={t("appPackagesMoreActions")}
151
- disabled={pending}
152
- className="max-md:min-h-11 max-md:min-w-11 inline-flex items-center justify-center rounded-full p-2 text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:opacity-50"
153
- >
154
- <MoreVertical className="h-4 w-4" />
155
- </button>
156
- </PopoverTrigger>
157
- <PopoverContent
158
- align="end"
159
- className="w-52 rounded-xl p-1.5"
160
- onCloseAutoFocus={(event) => {
161
- if (skipMenuFocusRestoreRef.current) {
162
- event.preventDefault();
163
- skipMenuFocusRestoreRef.current = false;
164
- }
165
- }}
166
- >
167
- <AppPackageMenuItem
168
- icon={RefreshCw}
169
- label={t("appPackagesCheckUpdate")}
170
- onClick={() => {
171
- setMenuOpen(false);
172
- onUpdate();
173
- }}
174
- />
175
- {rollbackVersions.map((version) => (
176
- <AppPackageMenuItem
177
- key={version}
178
- icon={RotateCcw}
179
- label={`${t("appPackagesRollback")} v${version}`}
180
- onClick={() => {
181
- setMenuOpen(false);
182
- onRollback(version);
183
- }}
152
+ <ContextMenu
153
+ label={t("appPackagesMoreActions")}
154
+ groups={
155
+ pending
156
+ ? []
157
+ : [
158
+ {
159
+ key: "manage",
160
+ items: [
161
+ {
162
+ key: "details",
163
+ icon: <Info className="h-4 w-4" />,
164
+ label: t("appPackagesDetails"),
165
+ restoreFocus: false,
166
+ onSelect: () => setDetailsOpen(true),
167
+ },
168
+ ...(appPackage.enabled
169
+ ? [
170
+ {
171
+ key: "disable",
172
+ icon: <Power className="h-4 w-4" />,
173
+ label: t("appPackagesDisable"),
174
+ onSelect: onDisable,
175
+ },
176
+ ]
177
+ : []),
178
+ {
179
+ key: "update",
180
+ icon: <RefreshCw className="h-4 w-4" />,
181
+ label: t("appPackagesCheckUpdate"),
182
+ onSelect: onUpdate,
183
+ },
184
+ ...rollbackVersions.map((version) => ({
185
+ key: version,
186
+ icon: <RotateCcw className="h-4 w-4" />,
187
+ label: `${t("appPackagesRollback")} v${version}`,
188
+ onSelect: () => onRollback(version),
189
+ })),
190
+ ],
191
+ },
192
+ {
193
+ key: "remove",
194
+ items: [
195
+ {
196
+ key: "uninstall",
197
+ destructive: true,
198
+ icon: <Trash2 className="h-4 w-4" />,
199
+ label: t("appPackagesUninstall"),
200
+ restoreFocus: false,
201
+ onSelect: () => {
202
+ setPurgeData(false);
203
+ setUninstallOpen(true);
204
+ },
205
+ },
206
+ ],
207
+ },
208
+ ]
209
+ }
210
+ >
211
+ <div>
212
+ <ContextMenuTrigger>
213
+ <IconActionButton
214
+ icon={<MoreVertical className="h-4 w-4" />}
215
+ label={t("appPackagesMoreActions")}
216
+ disabled={pending}
184
217
  />
185
- ))}
186
- <AppPackageMenuItem
187
- destructive
188
- icon={Trash2}
189
- label={t("appPackagesUninstall")}
190
- onClick={() => {
191
- skipMenuFocusRestoreRef.current = true;
192
- setMenuOpen(false);
193
- setPurgeData(false);
194
- setUninstallOpen(true);
195
- }}
196
- />
197
- </PopoverContent>
198
- </Popover>
218
+ </ContextMenuTrigger>
219
+ </div>
220
+ </ContextMenu>
199
221
  </div>
200
222
  </div>
201
223
 
202
- {operation && (operationActive || operation.status === "failed" || operation.status === "interrupted") ? <PackageOperationStatus operation={operation} /> : null}
224
+ <AppPackageDetailsDialog
225
+ appPackage={appPackage}
226
+ disabled={pending || Boolean(unavailableMessage)}
227
+ displayName={displayName}
228
+ displayDescription={displayDescription}
229
+ open={detailsOpen}
230
+ onOpenChange={setDetailsOpen}
231
+ onFocusReturn={() => detailsTriggerRef.current?.focus()}
232
+ storageUsage={storageUsage}
233
+ storageUsageLoading={storageUsageLoading}
234
+ storageUsageUnavailable={storageUsageUnavailable}
235
+ />
203
236
 
204
- <AppDocumentAccessSection appId={appPackage.id} appName={displayName} disabled={pending || !availability.interactive} scopes={appPackage.documentAccess ?? []} />
237
+ {operation && (operationActive || operation.status === "failed" || operation.status === "interrupted") ? (
238
+ <PackageOperationStatus operation={operation} />
239
+ ) : null}
205
240
 
206
- {panelComponents.length > 0 ? (
207
- <div className="border-t border-border/60 bg-muted/20 p-2">
208
- <div className="grid grid-cols-2 gap-1.5">
241
+ {appPackage.enabled && panelComponents.length > 1 ? (
242
+ <div className="px-3 pb-3 [@container(min-width:28rem)]:pl-16">
243
+ <div className="grid grid-cols-1 gap-1 [@container(min-width:20rem)]:grid-cols-2">
209
244
  {panelComponents.map((component) => {
210
245
  const panelApp = panelApps.find((entry) => entry.appId === component.id);
211
246
  const Icon = resolveComponentIcon(component.id);
@@ -214,7 +249,7 @@ export function AppPackageCard({
214
249
  <button
215
250
  key={component.id}
216
251
  type="button"
217
- disabled={!appPackage.enabled || !panelApp || pending || !availability.interactive}
252
+ disabled={!panelApp || pending || !availability.interactive}
218
253
  onClick={() =>
219
254
  panelApp &&
220
255
  onOpenPanelApp({
@@ -224,13 +259,13 @@ export function AppPackageCard({
224
259
  })
225
260
  }
226
261
  className="group flex min-w-0 items-center gap-2 rounded-lg px-2.5 py-2 text-left transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-default disabled:opacity-55"
227
- title={availability.message ?? (!appPackage.enabled ? t("appPackagesEnableToOpen") : componentTitle)}
262
+ title={availability.message ?? componentTitle}
228
263
  >
229
- <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-card text-muted-foreground shadow-sm ring-1 ring-border/60">
264
+ <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-muted-foreground">
230
265
  <ComponentIcon icon={component.icon} fallback={Icon} />
231
266
  </span>
232
267
  <span className="min-w-0 flex-1 truncate text-xs font-medium text-foreground">{componentTitle}</span>
233
- {appPackage.enabled ? <ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground/50 transition-transform group-hover:translate-x-0.5" /> : null}
268
+ <ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground/50 transition-transform group-hover:translate-x-0.5" />
234
269
  </button>
235
270
  );
236
271
  })}
@@ -240,25 +275,51 @@ export function AppPackageCard({
240
275
 
241
276
  <Dialog open={uninstallOpen} onOpenChange={setUninstallOpen}>
242
277
  <DialogContent
243
- className="max-w-md [&>:last-child]:hidden"
278
+ className="max-w-md"
279
+ onCloseAutoFocus={(event) => {
280
+ event.preventDefault();
281
+ detailsTriggerRef.current?.focus();
282
+ }}
244
283
  onOpenAutoFocus={(event) => {
245
284
  event.preventDefault();
246
285
  uninstallCancelRef.current?.focus();
247
286
  }}
248
287
  >
249
- <DialogHeader>
288
+ <DialogHeader showClose={false}>
250
289
  <DialogTitle>{t("appPackagesUninstallTitle")}</DialogTitle>
251
290
  <DialogDescription>{t("appPackagesUninstallDescription")}</DialogDescription>
252
291
  </DialogHeader>
253
292
  <div className="mt-4 grid gap-2">
254
- <AppDataRemovalChoice checked={!purgeData} description={t("appPackagesKeepDataDescription")} label={t("appPackagesKeepData")} onClick={() => setPurgeData(false)} />
255
- <AppDataRemovalChoice checked={purgeData} destructive description={t("appPackagesDeleteDataDescription")} label={t("appPackagesDeleteData")} onClick={() => setPurgeData(true)} />
293
+ <AppDataRemovalChoice
294
+ checked={!purgeData}
295
+ description={t("appPackagesKeepDataDescription")}
296
+ label={t("appPackagesKeepData")}
297
+ onClick={() => setPurgeData(false)}
298
+ />
299
+ <AppDataRemovalChoice
300
+ checked={purgeData}
301
+ destructive
302
+ description={t("appPackagesDeleteDataDescription")}
303
+ label={t("appPackagesDeleteData")}
304
+ onClick={() => setPurgeData(true)}
305
+ />
256
306
  </div>
257
307
  <div className="mt-3">
258
- <AppPackageStorageUsage loading={storageUsageLoading} storage={appPackage.storage} usage={storageUsage} unavailable={storageUsageUnavailable} />
308
+ <AppPackageStorageUsage
309
+ loading={storageUsageLoading}
310
+ storage={appPackage.storage}
311
+ usage={storageUsage}
312
+ unavailable={storageUsageUnavailable}
313
+ />
259
314
  </div>
260
315
  <DialogFooter className="mt-5 gap-2 sm:gap-0">
261
- <Button ref={uninstallCancelRef} autoFocus type="button" variant="outline" onClick={() => setUninstallOpen(false)}>
316
+ <Button
317
+ ref={uninstallCancelRef}
318
+ autoFocus
319
+ type="button"
320
+ variant="outline"
321
+ onClick={() => setUninstallOpen(false)}
322
+ >
262
323
  {t("cancel")}
263
324
  </Button>
264
325
  <Button
@@ -278,7 +339,17 @@ export function AppPackageCard({
278
339
  );
279
340
  }
280
341
 
281
- function AppPackageStorageUsage({ loading, storage, unavailable, usage }: { loading: boolean; storage: AppPackageView["storage"]; unavailable: boolean; usage?: AppDataEntry["usage"] }) {
342
+ function AppPackageStorageUsage({
343
+ loading,
344
+ storage,
345
+ unavailable,
346
+ usage,
347
+ }: {
348
+ loading: boolean;
349
+ storage: AppPackageView["storage"];
350
+ unavailable: boolean;
351
+ usage?: AppDataEntry["usage"];
352
+ }) {
282
353
  if (usage) {
283
354
  return <AppStorageUsageDetails storage={storage} usage={usage} />;
284
355
  }
@@ -290,13 +361,17 @@ function AppPackageStorageUsage({ loading, storage, unavailable, usage }: { load
290
361
  );
291
362
  }
292
363
 
293
- function resolveStorageUsageLabel(usage: AppDataEntry["usage"] | undefined, loading: boolean, unavailable: boolean): string {
294
- if (usage) return formatBytes(usage.totalBytes);
295
- if (loading) return t("appPackagesLoading");
296
- return t(unavailable ? "appPackagesDataUsageUnavailable" : "appPackagesNoDataYet");
297
- }
298
-
299
- function renderPrimaryActionLabel({ enabled, isPending, operation, operationActive }: { enabled: boolean; isPending: boolean; operation?: AppPackageOperationView; operationActive: boolean }) {
364
+ function renderPrimaryActionLabel({
365
+ enabled,
366
+ isPending,
367
+ operation,
368
+ operationActive,
369
+ }: {
370
+ enabled: boolean;
371
+ isPending: boolean;
372
+ operation?: AppPackageOperationView;
373
+ operationActive: boolean;
374
+ }) {
300
375
  if (operationActive) {
301
376
  return (
302
377
  <>
@@ -309,24 +384,11 @@ function renderPrimaryActionLabel({ enabled, isPending, operation, operationActi
309
384
  return enabled ? t("appPackagesDisable") : t("appPackagesEnable");
310
385
  }
311
386
 
312
- function AppPackageMenuItem({ destructive = false, icon: Icon, label, onClick }: { destructive?: boolean; icon: LucideIcon; label: string; onClick: () => void }) {
313
- return (
314
- <button
315
- type="button"
316
- onClick={onClick}
317
- className={cn(
318
- ACTION_MENU_ITEM_CLASS,
319
- destructive ? ACTION_FEEDBACK.destructive : `text-foreground ${ACTION_FEEDBACK.item}`,
320
- )}
321
- >
322
- <Icon className="h-4 w-4 shrink-0" />
323
- <span>{label}</span>
324
- </button>
325
- );
326
- }
327
-
328
387
  function ComponentIcon({ fallback: Fallback, icon }: { fallback: LucideIcon; icon?: string }) {
329
- if (icon && (icon.startsWith("data:") || icon.startsWith("/") || icon.startsWith("http://") || icon.startsWith("https://"))) {
388
+ if (
389
+ icon &&
390
+ (icon.startsWith("data:") || icon.startsWith("/") || icon.startsWith("http://") || icon.startsWith("https://"))
391
+ ) {
330
392
  return <img src={icon} alt="" className="h-4 w-4 rounded object-cover" />;
331
393
  }
332
394
  if (icon) {
@@ -341,11 +403,23 @@ function PackageOperationStatus({ operation }: { operation: AppPackageOperationV
341
403
  return (
342
404
  <div className="border-t border-border/50 px-4 py-2.5" role={failed ? "alert" : "status"} aria-live="polite">
343
405
  <div className="flex items-center gap-2 text-[11px]">
344
- {failed ? <AlertCircle className="h-3.5 w-3.5 text-destructive" /> : <LoaderCircle className="h-3.5 w-3.5 animate-spin text-primary" />}
345
- <span className={failed ? "text-destructive" : "text-muted-foreground"}>{failed ? (operation.error ?? t("appPackagesActionFailed")) : operationLabel(operation)}</span>
406
+ {failed ? (
407
+ <AlertCircle className="h-3.5 w-3.5 text-destructive" />
408
+ ) : (
409
+ <LoaderCircle className="h-3.5 w-3.5 animate-spin text-primary" />
410
+ )}
411
+ <span className={failed ? "text-destructive" : "text-muted-foreground"}>
412
+ {failed ? (operation.error ?? t("appPackagesActionFailed")) : operationLabel(operation)}
413
+ </span>
346
414
  </div>
347
415
  <div className="mt-2 h-1 overflow-hidden rounded-full bg-muted">
348
- <div className={cn("h-full rounded-full transition-[width] duration-300", failed ? "bg-destructive" : "bg-primary")} style={{ width: failed ? "100%" : `${progress}%` }} />
416
+ <div
417
+ className={cn(
418
+ "h-full rounded-full transition-[width] duration-300",
419
+ failed ? "bg-destructive" : "bg-primary",
420
+ )}
421
+ style={{ width: failed ? "100%" : `${progress}%` }}
422
+ />
349
423
  </div>
350
424
  </div>
351
425
  );
@@ -385,7 +459,10 @@ function resolveComponentIcon(componentId: string): LucideIcon {
385
459
  return AppWindow;
386
460
  }
387
461
 
388
- function readLocalizedText(fallback: string | undefined, localized: Record<string, string> | undefined): string | undefined {
462
+ function readLocalizedText(
463
+ fallback: string | undefined,
464
+ localized: Record<string, string> | undefined,
465
+ ): string | undefined {
389
466
  const languageTag = getLanguage() === "zh" ? "zh-CN" : "en-US";
390
467
  return localized?.[languageTag] ?? fallback;
391
468
  }
@@ -0,0 +1,103 @@
1
+ import type { AppDataEntry, AppPackageView } from "@nextclaw/client-sdk";
2
+ import { HardDrive, Server, ShieldAlert, ShieldCheck } from "lucide-react";
3
+ import { formatBytes } from "@/features/app-data";
4
+ import { AppDocumentAccessSection } from "@/features/apps/components/app-document-access-section";
5
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/shared/components/ui/dialog";
6
+ import { t } from "@/shared/lib/i18n";
7
+ import { cn } from "@/shared/lib/utils";
8
+
9
+ export function AppPackageDetailsDialog({
10
+ appPackage,
11
+ disabled,
12
+ displayName,
13
+ displayDescription,
14
+ open,
15
+ onOpenChange,
16
+ onFocusReturn,
17
+ storageUsage,
18
+ storageUsageLoading,
19
+ storageUsageUnavailable,
20
+ }: {
21
+ appPackage: AppPackageView;
22
+ disabled: boolean;
23
+ displayName: string;
24
+ displayDescription?: string;
25
+ open: boolean;
26
+ onOpenChange: (open: boolean) => void;
27
+ onFocusReturn: () => void;
28
+ storageUsage?: AppDataEntry["usage"];
29
+ storageUsageLoading: boolean;
30
+ storageUsageUnavailable: boolean;
31
+ }) {
32
+ const serviceCount = appPackage.components.filter((component) => component.kind !== "panel").length;
33
+ const storageUsageLabel = resolveStorageUsageLabel(storageUsage, storageUsageLoading, storageUsageUnavailable);
34
+ return (
35
+ <Dialog open={open} onOpenChange={onOpenChange}>
36
+ <DialogContent
37
+ className="max-w-xl"
38
+ onCloseAutoFocus={(event) => {
39
+ event.preventDefault();
40
+ onFocusReturn();
41
+ }}
42
+ >
43
+ <DialogHeader>
44
+ <DialogTitle>{displayName}</DialogTitle>
45
+ <DialogDescription>{displayDescription ?? t("appPackagesDetails")}</DialogDescription>
46
+ </DialogHeader>
47
+ <div className="flex flex-wrap items-center gap-x-3 gap-y-2 text-xs text-muted-foreground">
48
+ <span>v{appPackage.activeVersion}</span>
49
+ {appPackage.builtIn ? <span>{t("appPackagesBuiltIn")}</span> : null}
50
+ {serviceCount > 0 ? (
51
+ <span className="inline-flex items-center gap-1">
52
+ <Server className="h-3 w-3" />
53
+ {t("appPackagesLocalService")}
54
+ </span>
55
+ ) : null}
56
+ <span
57
+ className={cn(
58
+ "inline-flex items-center gap-1",
59
+ appPackage.isolation === "full-user" && "text-amber-700 dark:text-amber-300",
60
+ )}
61
+ >
62
+ {appPackage.isolation === "full-user" ? (
63
+ <ShieldAlert className="h-3 w-3" />
64
+ ) : (
65
+ <ShieldCheck className="h-3 w-3" />
66
+ )}
67
+ {appPackage.isolation === "full-user"
68
+ ? t("appPackagesIsolationFullUser")
69
+ : appPackage.isolation === "host-mediated"
70
+ ? t("appPackagesIsolationMediated")
71
+ : t("appPackagesIsolationPanel")}
72
+ </span>
73
+ </div>
74
+ <div
75
+ className="flex min-w-0 items-center gap-1.5 rounded-md bg-muted/35 px-2 py-1 text-xs text-muted-foreground"
76
+ title={appPackage.storage.dataDirectory}
77
+ >
78
+ <HardDrive className="h-3 w-3 shrink-0" />
79
+ <span className="shrink-0">
80
+ {t("appPackagesDataUsage")} {storageUsageLabel}
81
+ </span>
82
+ <code className="min-w-0 truncate font-mono text-xs">{appPackage.storage.dataDirectory}</code>
83
+ </div>
84
+ <AppDocumentAccessSection
85
+ appId={appPackage.id}
86
+ appName={displayName}
87
+ disabled={disabled}
88
+ scopes={appPackage.documentAccess ?? []}
89
+ />
90
+ </DialogContent>
91
+ </Dialog>
92
+ );
93
+ }
94
+
95
+ function resolveStorageUsageLabel(
96
+ usage: AppDataEntry["usage"] | undefined,
97
+ loading: boolean,
98
+ unavailable: boolean,
99
+ ): string {
100
+ if (usage) return formatBytes(usage.totalBytes);
101
+ if (loading) return t("appPackagesLoading");
102
+ return t(unavailable ? "appPackagesDataUsageUnavailable" : "appPackagesNoDataYet");
103
+ }