@nextclaw/ui 0.26.5 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/.vite/manifest.json +1271 -1227
- package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-DmeCRAkd.js} +1 -1
- package/dist/assets/account-panel-BYxGT4m4.js +1 -0
- package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.js → aiden0z-pptx-renderer.es-ChX5DHqP.js} +1 -1
- package/dist/assets/api-CG22BskB.js +20 -0
- package/dist/assets/app-presenter-provider-CJFjhVYI.js +28 -0
- package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
- package/dist/assets/appearance-settings-page-BcXr0vHp.js +1 -0
- package/dist/assets/{arc-DBRedCax.js → arc-Cu6Ols44.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-DrNB0eLE.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-08rHt6DJ.js} +1 -1
- package/dist/assets/{book-open-Bcnn2_uV.js → book-open-ClbJmmxP.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CCVgRG-u.js} +1 -1
- package/dist/assets/{card-Cqs73hGI.js → card-BdC01NFF.js} +1 -1
- package/dist/assets/channel-BgpbPyEH.js +1 -0
- package/dist/assets/channels-list-page-BrIvJlop.js +8 -0
- package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-BeCaI-JN.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-ZXIcYPYs.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-DDwTPcy8.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-WygrMYPL.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-o8T3KZgk.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BKFbUT7J.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DYxCRV86.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CvSeJlKZ.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-BhH3RHCY.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-BTL0-xL3.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DWAU4QaD.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-B7ZBMXTx.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D92HvnHE.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-DfOGKwW8.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-DUuJUrXJ.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-i3MDyUY5.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-F_pmNX6t.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DygOelrU.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-BpiZMeRl.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-CV10sB1I.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-Cf1WZNm0.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-DuSw54VR.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-_rt_XKSZ.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-BFPaAGNW.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-GE0v_E5y.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-BK_FpnlJ.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-CpYh6rGo.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-htnxL_Cl.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-wDbE4BZ7.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DDRSVFTB.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-COdhHR1o.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-DPDGhyF6.js} +3 -3
- package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-D8ir9Nx5.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BuNKD836.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DyHzq8jH.js} +1 -1
- package/dist/assets/{circle-dashed-EY1ScSMe.js → circle-dashed-nDaMRmP-.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +1 -0
- package/dist/assets/{client-CH7w6yRV.js → client-DlFB5dW5.js} +1 -1
- package/dist/assets/config-split-page-C06fU9OQ.js +1 -0
- package/dist/assets/confirm-dialog-DpcmlXhd.js +1 -0
- package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
- package/dist/assets/context-menu-DKIEaY7f.js +211 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-B1I1_P6a.js} +1 -1
- package/dist/assets/{createLucideIcon-Cfo2ySi5.js → createLucideIcon-Lnt-4LMC.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DcOnhnCo.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-hAX89lg3.js} +1 -1
- package/dist/assets/{dagre-CrgsRasE.js → dagre-nSYhf9yY.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-BDYITStl.js → desktop-capabilities-page-DPORyZAu.js} +1 -1
- package/dist/assets/desktop-update-config-BMTeWZmn.js +1 -0
- package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-C1mRMD2k.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D2XBn5al.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-3LmRsmkC.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-CFWn-osC.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-BqNRbUvU.js} +1 -1
- package/dist/assets/dialog-BNXSPMX_.js +1 -0
- package/dist/assets/dist-Cuiqqp1O.js +41 -0
- package/dist/assets/doc-browser-CDEapjmj.js +1 -0
- package/dist/assets/{doc-browser-context-DwgG6wrz.js → doc-browser-context-0QDWYorh.js} +1 -1
- package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-CunAATyC.js} +1 -1
- package/dist/assets/{download-BoaKzDJk.js → download-f_sPcoLZ.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-CYb8IwqD.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-H47mUoeK.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +1 -0
- package/dist/assets/extensions-B-0xQz3L.js +1 -0
- package/dist/assets/external-link-CbVlnlNy.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +1 -0
- package/dist/assets/{form-actions-D9JWSFQu.js → form-actions-BoTqELHB.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-hSX45zfV.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-Br0UW2qg.js} +1 -1
- package/dist/assets/{i18n-Bm3Ov7Fy.js → i18n-B0V5NkFj.js} +2 -2
- package/dist/assets/inbox-Bna8iUy0.js +1 -0
- package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-DQmP_67w.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-BHAV2oes.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-CFHax4_d.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-B4ZA9rp5.js} +1 -1
- package/dist/assets/katex-BprZ-Wwb.js +1 -0
- package/dist/assets/{keyboard-shortcuts-settings-page-DZ8A1iLg.js → keyboard-shortcuts-settings-page-BluWKrSo.js} +1 -1
- package/dist/assets/{line-D_bHubTL.js → line-BboM0HLF.js} +1 -1
- package/dist/assets/{linear-ChlwuS5y.js → linear-4K_M1oYM.js} +1 -1
- package/dist/assets/login-page-BMHW0Hh0.js +1 -0
- package/dist/assets/{login-page-C-DvcG3L.js → login-page-JNr5JCEw.js} +1 -1
- package/dist/assets/main-BCX_Untx.css +1 -0
- package/dist/assets/main-C5kbmGUV.js +2 -0
- package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +1 -0
- package/dist/assets/{map-oGHTsIu8.js → map-26GpO1wn.js} +1 -1
- package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +1 -0
- package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-BTJFnvRC.js} +2 -2
- package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-B7ufoXgq.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-BHyru6KE.js} +1 -1
- package/dist/assets/model-config-page-C-wbM6Fe.js +1 -0
- package/dist/assets/{navigation-link-CjxNC8aT.js → navigation-link-DFLSVIut.js} +2 -2
- package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-BqFe2ePF.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +1 -0
- package/dist/assets/panel-app-CSQmm_7E.js +1 -0
- package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +1 -0
- package/dist/assets/panelStandalone-PuuMF65O.js +2 -0
- package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-PVTatU5j.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-CGc-QCc7.js} +1 -1
- package/dist/assets/plus-CywSlIbG.js +1 -0
- package/dist/assets/privacy-settings-page-CPdEiouE.js +1 -0
- package/dist/assets/projects-D_cd_t4G.js +1 -0
- package/dist/assets/provider-models-XRArsply.js +1 -0
- package/dist/assets/provider-scoped-model-input-C8JI-hus.js +1 -0
- package/dist/assets/providers-config-page-fyMlVgvq.js +1 -0
- package/dist/assets/puzzle-Bk3ud1KI.js +1 -0
- package/dist/assets/pwa-Cx6Fnox4.js +1 -0
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-DGL36riv.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-CyNwvhSb.js} +1 -1
- package/dist/assets/{refresh-cw-BlXDrVP0.js → refresh-cw-Ca2napNx.js} +1 -1
- package/dist/assets/remote-D5MBQNZE.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-C31NMKJ0.js} +1 -1
- package/dist/assets/{rotate-cw-ei6rPD6z.js → rotate-cw-DXg7sNUE.js} +1 -1
- package/dist/assets/runtime-config-page--ivCxBT4.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-CwrQ_7PA.js} +1 -1
- package/dist/assets/{save-DdF-bXgC.js → save-DNigywZ9.js} +1 -1
- package/dist/assets/search-U9C0oTQJ.js +1 -0
- package/dist/assets/search-config-page-Bdx_RR1q.js +1 -0
- package/dist/assets/secrets-config-page-CvMIcsfJ.js +3 -0
- package/dist/assets/security-config-CQmMqQ8v.js +1 -0
- package/dist/assets/select-DxwDeKUR.js +1 -0
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-EFD482_y.js} +1 -1
- package/dist/assets/service-apps-panel-CiYO1Be4.js +1 -0
- package/dist/assets/{settings-2-CrNhfInU.js → settings-2-BrBUdRoY.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-TDvULTE1.js} +1 -1
- package/dist/assets/{src-C8AUg09O.js → src-CI2AvEMj.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-JdPsIYHo.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +1 -0
- package/dist/assets/{status-dot-C3SRFEta.js → status-dot-BbGsrkIX.js} +1 -1
- package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BnxpKeK_.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +8 -0
- package/dist/assets/tag-chip-BDbxcf6P.js +1 -0
- package/dist/assets/theme-provider-D98XGa-c.js +1 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-2IL22-uC.js} +1 -1
- package/dist/assets/trash-2-DwSkRfeB.js +1 -0
- package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +1 -0
- package/dist/assets/{use-config-evzage09.js → use-config-D3cNzk2k.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-BYDjFlpt.js → use-desktop-capabilities-D7odgaTB.js} +1 -1
- package/dist/assets/use-viewport-layout-BANU5E1t.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-Cjf6n5Va.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-yv4qKbBO.js} +1 -1
- package/dist/assets/x-BqGj6_Vq.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-Bmp8Ck8X.js} +1 -1
- package/dist/index.html +43 -106
- package/dist/panel-standalone.html +18 -12
- package/index.html +15 -66
- package/package.json +4 -4
- package/src/app/styles/design-system.css +85 -1
- package/src/app/styles/island-theme.css +8 -6
- package/src/features/agents/components/agent-details-dialog.tsx +5 -3
- package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
- package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
- package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
- package/src/features/apps/components/app-document-access-section.tsx +17 -14
- package/src/features/apps/components/app-marketplace-catalog.tsx +66 -39
- package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
- package/src/features/apps/components/app-marketplace-detail.tsx +9 -6
- package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
- package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
- package/src/features/apps/components/app-package-card.tsx +224 -147
- package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
- package/src/features/apps/components/app-packages-panel.tsx +159 -144
- package/src/features/apps/components/apps-panel.tsx +40 -11
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
- package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
- package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +33 -0
- package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
- package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
- package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
- package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
- package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
- package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -7
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +5 -4
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
- package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
- package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +7 -4
- package/src/features/cron/components/cron-job-row.tsx +5 -4
- package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
- package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
- package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
- package/src/features/inbox/managers/inbox.manager.ts +18 -4
- package/src/features/inbox/pages/inbox-page.test.ts +4 -2
- package/src/features/inbox/pages/inbox-page.tsx +6 -5
- package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
- package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
- package/src/features/projects/components/work/project-work-items.tsx +1 -1
- package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
- package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
- package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
- package/src/features/right-panel-resources/components/page-resource-icon.tsx +15 -7
- package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +1 -1
- package/src/features/right-panel-resources/index.ts +3 -0
- package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +5 -0
- package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
- package/src/features/service-apps/components/service-action-row.tsx +4 -3
- package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
- package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
- package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
- package/src/features/settings/pages/providers-config-page.tsx +3 -2
- package/src/index.css +42 -8
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
- package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
- package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
- package/src/shared/components/ui/actions/action-feedback.ts +1 -8
- package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
- package/src/shared/components/ui/confirm-dialog.tsx +1 -2
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
- package/src/shared/components/ui/dialog.tsx +29 -7
- package/src/shared/components/ui/popover.tsx +14 -3
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -2
- package/src/shared/components/ui/tooltip.tsx +2 -1
- package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
- package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
- package/src/shared/components/workbench/workbench-surface.tsx +4 -1
- package/src/shared/lib/i18n/locales/en-US/chat.json +13 -7
- package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
- package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +13 -7
- package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
- package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
- package/src/shared/lib/theme/index.test.ts +28 -1
- package/src/shared/lib/theme/index.ts +14 -3
- package/dist/assets/account-panel-BAH7FW6z.js +0 -1
- package/dist/assets/api-DjiZvIa0.js +0 -20
- package/dist/assets/app-presenter-provider-CCRFsFYr.js +0 -232
- package/dist/assets/appearance-settings-page-CdP86QJ7.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
- package/dist/assets/channel-CpMstUPF.js +0 -1
- package/dist/assets/channels-list-page-5qGagKuE.js +0 -8
- package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
- package/dist/assets/config-split-page-CuEGQL8Z.js +0 -1
- package/dist/assets/confirm-dialog-CxfecBzO.js +0 -1
- package/dist/assets/context-menu-BsCj2fRs.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
- package/dist/assets/desktop-update-config-e-zhkJuS.js +0 -1
- package/dist/assets/dialog-QjQoKbIV.js +0 -5
- package/dist/assets/doc-browser-CLEdkH9z.js +0 -1
- package/dist/assets/es2015-Bp6cuSGh.js +0 -41
- package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
- package/dist/assets/extensions-CgShSIkd.js +0 -1
- package/dist/assets/eye-kisejBFH.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
- package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
- package/dist/assets/katex-B4FQSo9k.js +0 -1
- package/dist/assets/loader-circle-Bd1fTm-x.js +0 -1
- package/dist/assets/login-page-D99JjH9F.js +0 -1
- package/dist/assets/main-Bt5r6b21.js +0 -2
- package/dist/assets/main-DXd_aKJV.css +0 -1
- package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +0 -1
- package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +0 -1
- package/dist/assets/model-config-page-9NNf-mzK.js +0 -1
- package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
- package/dist/assets/panel-app-BYfQu_TS.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +0 -1
- package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
- package/dist/assets/panelStandalone-BaUzY8Wy.js +0 -2
- package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
- package/dist/assets/privacy-settings-page-CVMBFuak.js +0 -1
- package/dist/assets/projects-BEsU3box.js +0 -1
- package/dist/assets/provider-models-Dm-pmWAA.js +0 -1
- package/dist/assets/provider-scoped-model-input-CzrXg4cX.js +0 -1
- package/dist/assets/providers-config-page-839uUADZ.js +0 -1
- package/dist/assets/puzzle-BGvD2DPZ.js +0 -1
- package/dist/assets/pwa-DNNK_8E9.js +0 -1
- package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
- package/dist/assets/remote-B5qIuUbT.js +0 -1
- package/dist/assets/runtime-config-page-Bf-4JYxQ.js +0 -1
- package/dist/assets/search-config-page-C0qA3j-T.js +0 -1
- package/dist/assets/secrets-config-page-DxfZWpnk.js +0 -3
- package/dist/assets/security-config-CItfIQZ4.js +0 -1
- package/dist/assets/select-CWyjnar7.js +0 -1
- package/dist/assets/service-apps-panel-D3SOkRVv.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
- package/dist/assets/tag-chip-BIuavK2K.js +0 -1
- package/dist/assets/theme-provider-CWUz4yO9.js +0 -1
- package/dist/assets/trash-2-hAbJh9VZ.js +0 -1
- package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
- package/dist/assets/use-viewport-layout-D_9XWGDV.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
- package/dist/assets/x-ChPbNv39.js +0 -1
- package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
- /package/dist/assets/{array-BV9OtnO8.js → array-DstOKG9P.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-0TA8nwgf.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-rfGCG6pM.js} +0 -0
- /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-BfGoD7-o.js} +0 -0
- /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-DdIcNEda.js} +0 -0
- /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-CzXix2iJ.js} +0 -0
- /package/dist/assets/{dist-BVCSkfWY.js → dist-D5dwMwKA.js} +0 -0
- /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-BKOe0eFe.js} +0 -0
- /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-CnSVTaot.js} +0 -0
- /package/dist/assets/{init-BF6GH5oe.js → init-OCFb3zgY.js} +0 -0
- /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-B2uhSxvV.js} +0 -0
- /package/dist/assets/{katex-CsAM73R9.js → katex-dBrYsE7B.js} +0 -0
- /package/dist/assets/{middleware-B--6mAUM.js → middleware-CAXxl-af.js} +0 -0
- /package/dist/assets/{path-C56XkznJ.js → path-T5eoIRSJ.js} +0 -0
- /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
- /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-DmGXmZEB.js} +0 -0
- /package/dist/assets/{xlsx-sds5nUpL.js → xlsx-CoYacou7.js} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
2
|
import type { AppPackageView } from "@nextclaw/client-sdk";
|
|
3
3
|
import { FolderKey, ShieldCheck, Trash2 } from "lucide-react";
|
|
4
4
|
import { useAppDocumentAccessMutation } from "@/features/apps/hooks/use-app-packages";
|
|
5
5
|
import { ServerPathPickerDialog } from "@/shared/components/path-picker/server-path-picker-dialog";
|
|
6
6
|
import { Button } from "@/shared/components/ui/button";
|
|
7
|
+
import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
|
|
7
8
|
import { t } from "@/shared/lib/i18n";
|
|
8
9
|
|
|
9
10
|
type DocumentScope = AppPackageView["documentAccess"][number];
|
|
@@ -20,6 +21,7 @@ export function AppDocumentAccessSection({
|
|
|
20
21
|
scopes: DocumentScope[];
|
|
21
22
|
}) {
|
|
22
23
|
const mutation = useAppDocumentAccessMutation();
|
|
24
|
+
const pickerTriggerRef = useRef<HTMLButtonElement | null>(null);
|
|
23
25
|
const [activeScopeId, setActiveScopeId] = useState<string | null>(null);
|
|
24
26
|
const [modes, setModes] = useState<Record<string, "read" | "read-write">>({});
|
|
25
27
|
const activeScope = scopes.find((scope) => scope.id === activeScopeId);
|
|
@@ -32,7 +34,7 @@ export function AppDocumentAccessSection({
|
|
|
32
34
|
const error = mutation.error instanceof Error ? mutation.error.message : null;
|
|
33
35
|
|
|
34
36
|
return (
|
|
35
|
-
<section className="border-t border-border/60
|
|
37
|
+
<section className="[container-type:inline-size] border-t border-border/60 pt-4">
|
|
36
38
|
<div className="mb-2 flex items-center gap-2">
|
|
37
39
|
<FolderKey className="h-3.5 w-3.5 text-muted-foreground" />
|
|
38
40
|
<h3 className="text-xs font-semibold text-foreground">
|
|
@@ -45,9 +47,9 @@ export function AppDocumentAccessSection({
|
|
|
45
47
|
return (
|
|
46
48
|
<div
|
|
47
49
|
key={scope.id}
|
|
48
|
-
className="rounded-lg
|
|
50
|
+
className="rounded-lg bg-muted/30 px-3 py-3"
|
|
49
51
|
>
|
|
50
|
-
<div className="flex flex-
|
|
52
|
+
<div className="flex flex-col items-stretch gap-3 [@container(min-width:26rem)]:flex-row [@container(min-width:26rem)]:items-start">
|
|
51
53
|
<div className="min-w-0 flex-1">
|
|
52
54
|
<div className="flex items-center gap-1.5 text-xs font-medium text-foreground">
|
|
53
55
|
<ShieldCheck className="h-3.5 w-3.5 text-muted-foreground" />
|
|
@@ -76,7 +78,7 @@ export function AppDocumentAccessSection({
|
|
|
76
78
|
</code>
|
|
77
79
|
) : null}
|
|
78
80
|
</div>
|
|
79
|
-
<div className="flex shrink-0 items-center gap-1.5">
|
|
81
|
+
<div className="flex shrink-0 items-center justify-end gap-1.5">
|
|
80
82
|
<label
|
|
81
83
|
className="sr-only"
|
|
82
84
|
htmlFor={`${appId}-${scope.id}-mode`}
|
|
@@ -109,7 +111,8 @@ export function AppDocumentAccessSection({
|
|
|
109
111
|
size="sm"
|
|
110
112
|
variant="outline"
|
|
111
113
|
disabled={disabled || mutation.isPending}
|
|
112
|
-
onClick={() => {
|
|
114
|
+
onClick={(event) => {
|
|
115
|
+
pickerTriggerRef.current = event.currentTarget;
|
|
113
116
|
mutation.reset();
|
|
114
117
|
setActiveScopeId(scope.id);
|
|
115
118
|
}}
|
|
@@ -119,10 +122,9 @@ export function AppDocumentAccessSection({
|
|
|
119
122
|
: t("appPackagesDocumentAccessChoose")}
|
|
120
123
|
</Button>
|
|
121
124
|
{scope.granted ? (
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
title={t("appPackagesDocumentAccessRevoke")}
|
|
125
|
+
<IconActionButton
|
|
126
|
+
label={t("appPackagesDocumentAccessRevoke")}
|
|
127
|
+
icon={<Trash2 className="h-3.5 w-3.5" />}
|
|
126
128
|
disabled={disabled || mutation.isPending}
|
|
127
129
|
onClick={() =>
|
|
128
130
|
mutation.mutate({
|
|
@@ -131,10 +133,7 @@ export function AppDocumentAccessSection({
|
|
|
131
133
|
scopeId: scope.id,
|
|
132
134
|
})
|
|
133
135
|
}
|
|
134
|
-
|
|
135
|
-
>
|
|
136
|
-
<Trash2 className="h-3.5 w-3.5" />
|
|
137
|
-
</button>
|
|
136
|
+
/>
|
|
138
137
|
) : null}
|
|
139
138
|
</div>
|
|
140
139
|
</div>
|
|
@@ -148,6 +147,10 @@ export function AppDocumentAccessSection({
|
|
|
148
147
|
</p>
|
|
149
148
|
) : null}
|
|
150
149
|
<ServerPathPickerDialog
|
|
150
|
+
onCloseAutoFocus={(event) => {
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
pickerTriggerRef.current?.focus();
|
|
153
|
+
}}
|
|
151
154
|
open={Boolean(activeScope)}
|
|
152
155
|
currentPath={activeScope?.grantedPath}
|
|
153
156
|
isSaving={mutation.isPending}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { useRef, type RefObject } from 'react';
|
|
1
2
|
import type { AppPackageHostTarget, AppPackageOperationView, AppPackageView } from '@nextclaw/client-sdk';
|
|
2
|
-
import { ChevronRight, Search, Sparkles } from 'lucide-react';
|
|
3
|
+
import { ChevronRight, Search, Sparkles, PackagePlus, X } from 'lucide-react';
|
|
3
4
|
import { AppArtwork } from '@/features/apps/components/app-artwork';
|
|
4
5
|
import { AppMarketplaceCover } from '@/features/apps/components/app-marketplace-cover';
|
|
5
6
|
import {
|
|
@@ -17,11 +18,8 @@ import {
|
|
|
17
18
|
resolveAppMarketplaceInstallability,
|
|
18
19
|
} from '@/features/apps/utils/app-marketplace-platform.utils';
|
|
19
20
|
import { pickLocalizedText } from '@/features/marketplace';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
DialogHeader,
|
|
23
|
-
DialogTitle,
|
|
24
|
-
} from '@/shared/components/ui/dialog';
|
|
21
|
+
import { Button } from '@/shared/components/ui/button';
|
|
22
|
+
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
25
23
|
import { Input } from '@/shared/components/ui/input';
|
|
26
24
|
import { Skeleton } from '@/shared/components/ui/skeleton';
|
|
27
25
|
import { getLanguage, t } from '@/shared/lib/i18n';
|
|
@@ -31,10 +29,13 @@ export type MarketplaceFilter = 'all' | 'featured' | 'personal' | 'local';
|
|
|
31
29
|
|
|
32
30
|
export function AppMarketplaceCatalog({
|
|
33
31
|
error,
|
|
32
|
+
onCustomInstall,
|
|
33
|
+
sourceButtonRef,
|
|
34
34
|
filter,
|
|
35
35
|
hostTarget,
|
|
36
36
|
installedById,
|
|
37
37
|
isError,
|
|
38
|
+
onRetry,
|
|
38
39
|
isFetchingNextPage,
|
|
39
40
|
isLoading,
|
|
40
41
|
isStarting,
|
|
@@ -46,16 +47,20 @@ export function AppMarketplaceCatalog({
|
|
|
46
47
|
onSearchChange,
|
|
47
48
|
onSelect,
|
|
48
49
|
onUpdate,
|
|
50
|
+
onManagePackage,
|
|
49
51
|
operations,
|
|
50
52
|
hasNextPage,
|
|
51
53
|
search,
|
|
52
54
|
startingSource,
|
|
53
55
|
}: {
|
|
54
56
|
error: Error | null;
|
|
57
|
+
onCustomInstall?: () => void;
|
|
58
|
+
sourceButtonRef?: RefObject<HTMLButtonElement>;
|
|
55
59
|
filter: MarketplaceFilter;
|
|
56
60
|
hostTarget?: AppPackageHostTarget;
|
|
57
61
|
installedById: Map<string, AppPackageView>;
|
|
58
62
|
isError: boolean;
|
|
63
|
+
onRetry?: () => void;
|
|
59
64
|
isFetchingNextPage: boolean;
|
|
60
65
|
isLoading: boolean;
|
|
61
66
|
isStarting: boolean;
|
|
@@ -67,20 +72,24 @@ export function AppMarketplaceCatalog({
|
|
|
67
72
|
onSearchChange: (value: string) => void;
|
|
68
73
|
onSelect: (slug: string) => void;
|
|
69
74
|
onUpdate: (appId: string) => void;
|
|
75
|
+
onManagePackage?: (appId: string) => void;
|
|
70
76
|
operations: AppPackageOperationView[];
|
|
71
77
|
hasNextPage: boolean;
|
|
72
78
|
search: string;
|
|
73
79
|
startingSource?: string;
|
|
74
80
|
}) {
|
|
81
|
+
const scrollArea = useRef<HTMLDivElement>(null);
|
|
75
82
|
return (
|
|
76
83
|
<>
|
|
77
84
|
<MarketplaceCatalogHeader
|
|
85
|
+
onCustomInstall={onCustomInstall}
|
|
86
|
+
sourceButtonRef={sourceButtonRef}
|
|
78
87
|
filter={filter}
|
|
79
|
-
onFilterChange={onFilterChange}
|
|
80
|
-
onSearchChange={onSearchChange}
|
|
88
|
+
onFilterChange={(value) => { if (scrollArea.current) scrollArea.current.scrollTop = 0; onFilterChange(value); }}
|
|
89
|
+
onSearchChange={(value) => { if (scrollArea.current) scrollArea.current.scrollTop = 0; onSearchChange(value); }}
|
|
81
90
|
search={search}
|
|
82
91
|
/>
|
|
83
|
-
<div className="custom-scrollbar min-h-0 flex-1 overflow-y-auto bg-background px-4 py-
|
|
92
|
+
<div ref={scrollArea} className="custom-scrollbar min-h-0 flex-1 overflow-y-auto bg-background px-4 py-5 [@container(min-width:40rem)]:px-6">
|
|
84
93
|
{error ? (
|
|
85
94
|
<div role="alert" className="mb-2 rounded-xl bg-destructive/8 px-3 py-2.5 text-xs leading-5 text-destructive ring-1 ring-destructive/15">
|
|
86
95
|
{error.message || t('appPackagesActionFailed')}
|
|
@@ -90,6 +99,7 @@ export function AppMarketplaceCatalog({
|
|
|
90
99
|
installedById={installedById}
|
|
91
100
|
hostTarget={hostTarget}
|
|
92
101
|
isError={isError}
|
|
102
|
+
onRetry={onRetry}
|
|
93
103
|
isFetchingNextPage={isFetchingNextPage}
|
|
94
104
|
isLoading={isLoading}
|
|
95
105
|
isStarting={isStarting}
|
|
@@ -99,6 +109,7 @@ export function AppMarketplaceCatalog({
|
|
|
99
109
|
onLoadMore={onLoadMore}
|
|
100
110
|
onSelect={onSelect}
|
|
101
111
|
onUpdate={onUpdate}
|
|
112
|
+
onManagePackage={onManagePackage}
|
|
102
113
|
operations={operations}
|
|
103
114
|
hasNextPage={hasNextPage}
|
|
104
115
|
startingSource={startingSource}
|
|
@@ -109,11 +120,15 @@ export function AppMarketplaceCatalog({
|
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
function MarketplaceCatalogHeader({
|
|
123
|
+
onCustomInstall,
|
|
124
|
+
sourceButtonRef,
|
|
112
125
|
filter,
|
|
113
126
|
onFilterChange,
|
|
114
127
|
onSearchChange,
|
|
115
128
|
search,
|
|
116
129
|
}: {
|
|
130
|
+
onCustomInstall?: () => void;
|
|
131
|
+
sourceButtonRef?: RefObject<HTMLButtonElement>;
|
|
117
132
|
filter: MarketplaceFilter;
|
|
118
133
|
onFilterChange: (value: MarketplaceFilter) => void;
|
|
119
134
|
onSearchChange: (value: string) => void;
|
|
@@ -126,34 +141,35 @@ function MarketplaceCatalogHeader({
|
|
|
126
141
|
{ value: 'local', label: t('appPackagesFilterLocal') },
|
|
127
142
|
];
|
|
128
143
|
return (
|
|
129
|
-
<div className="shrink-0 border-b border-border/60 bg-card px-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
</
|
|
144
|
+
<div className="shrink-0 border-b border-border/60 bg-card px-4 pb-4 pt-5 [@container(min-width:40rem)]:px-6">
|
|
145
|
+
<div className="mx-auto max-w-[872px]">
|
|
146
|
+
<div className="flex items-center justify-between gap-3">
|
|
147
|
+
<h1 className="text-xl font-semibold tracking-tight">{t('appPackagesMarketplaceTitle')}</h1>
|
|
148
|
+
{onCustomInstall ? <IconActionButton ref={sourceButtonRef} icon={<PackagePlus className="h-4 w-4" />} label={t('appPackagesCustomSource')} onClick={onCustomInstall} /> : null}
|
|
149
|
+
</div>
|
|
150
|
+
<p className="mt-1.5 text-sm leading-5 text-muted-foreground">{t('appPackagesMarketplaceDescription')}</p>
|
|
136
151
|
<div className="relative mt-4">
|
|
137
152
|
<Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
|
138
153
|
<Input
|
|
139
|
-
|
|
140
|
-
className="h-10 rounded-xl border-transparent bg-muted/65 pl-9 shadow-none focus-visible:ring-1"
|
|
154
|
+
className="h-10 rounded-xl border-0 bg-muted/65 pl-9 pr-10 ![box-shadow:none]"
|
|
141
155
|
value={search}
|
|
142
156
|
onChange={(event) => onSearchChange(event.target.value)}
|
|
143
157
|
placeholder={t('appPackagesMarketplaceSearch')}
|
|
144
158
|
aria-label={t('appPackagesMarketplaceSearch')}
|
|
145
159
|
/>
|
|
160
|
+
{search ? <div className="absolute right-1 top-1/2 -translate-y-1/2"><IconActionButton icon={<X className="h-3.5 w-3.5" />} label={t('appPackagesClearSearch')} onClick={() => onSearchChange('')} /></div> : null}
|
|
146
161
|
</div>
|
|
147
|
-
<div className="mt-3 flex gap-1 overflow-x-auto" aria-label={t('appPackagesFilterLabel')}>
|
|
162
|
+
<div className="custom-scrollbar mt-3 flex gap-1 overflow-x-auto" aria-label={t('appPackagesFilterLabel')}>
|
|
148
163
|
{filters.map((entry) => (
|
|
149
164
|
<button
|
|
150
165
|
key={entry.value}
|
|
151
166
|
type="button"
|
|
167
|
+
aria-pressed={filter === entry.value}
|
|
152
168
|
onClick={() => onFilterChange(entry.value)}
|
|
153
169
|
className={cn(
|
|
154
170
|
'shrink-0 rounded-full px-3 py-1.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border',
|
|
155
171
|
filter === entry.value
|
|
156
|
-
? 'bg-
|
|
172
|
+
? 'bg-[var(--interaction-selection)] text-foreground'
|
|
157
173
|
: 'text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground',
|
|
158
174
|
)}
|
|
159
175
|
>
|
|
@@ -161,6 +177,7 @@ function MarketplaceCatalogHeader({
|
|
|
161
177
|
</button>
|
|
162
178
|
))}
|
|
163
179
|
</div>
|
|
180
|
+
</div>
|
|
164
181
|
</div>
|
|
165
182
|
);
|
|
166
183
|
}
|
|
@@ -169,6 +186,7 @@ function MarketplaceCatalogContent({
|
|
|
169
186
|
installedById,
|
|
170
187
|
hostTarget,
|
|
171
188
|
isError,
|
|
189
|
+
onRetry,
|
|
172
190
|
isFetchingNextPage,
|
|
173
191
|
isLoading,
|
|
174
192
|
isStarting,
|
|
@@ -178,6 +196,7 @@ function MarketplaceCatalogContent({
|
|
|
178
196
|
onLoadMore,
|
|
179
197
|
onSelect,
|
|
180
198
|
onUpdate,
|
|
199
|
+
onManagePackage,
|
|
181
200
|
operations,
|
|
182
201
|
hasNextPage,
|
|
183
202
|
startingSource,
|
|
@@ -185,6 +204,7 @@ function MarketplaceCatalogContent({
|
|
|
185
204
|
installedById: Map<string, AppPackageView>;
|
|
186
205
|
hostTarget?: AppPackageHostTarget;
|
|
187
206
|
isError: boolean;
|
|
207
|
+
onRetry?: () => void;
|
|
188
208
|
isFetchingNextPage: boolean;
|
|
189
209
|
isLoading: boolean;
|
|
190
210
|
isStarting: boolean;
|
|
@@ -194,16 +214,17 @@ function MarketplaceCatalogContent({
|
|
|
194
214
|
onLoadMore: () => void;
|
|
195
215
|
onSelect: (slug: string) => void;
|
|
196
216
|
onUpdate: (appId: string) => void;
|
|
217
|
+
onManagePackage?: (appId: string) => void;
|
|
197
218
|
operations: AppPackageOperationView[];
|
|
198
219
|
hasNextPage: boolean;
|
|
199
220
|
startingSource?: string;
|
|
200
221
|
}) {
|
|
201
222
|
if (isLoading) {
|
|
202
223
|
return (
|
|
203
|
-
<div className="grid gap-
|
|
224
|
+
<div className="mx-auto grid max-w-[872px] gap-4 [@container(min-width:36rem)]:grid-cols-2 [@container(min-width:52rem)]:grid-cols-3" aria-label={t('appPackagesMarketplaceLoading')}>
|
|
204
225
|
<Skeleton className="aspect-[16/9] w-full rounded-2xl" />
|
|
205
226
|
<Skeleton className="aspect-[16/9] w-full rounded-2xl" />
|
|
206
|
-
<Skeleton className="hidden aspect-[16/9] w-full rounded-2xl min-
|
|
227
|
+
<Skeleton className="hidden aspect-[16/9] w-full rounded-2xl [@container(min-width:52rem)]:block" />
|
|
207
228
|
</div>
|
|
208
229
|
);
|
|
209
230
|
}
|
|
@@ -211,6 +232,7 @@ function MarketplaceCatalogContent({
|
|
|
211
232
|
return (
|
|
212
233
|
<div role="alert" className="rounded-xl border border-destructive/20 bg-destructive/5 px-4 py-5 text-sm text-destructive">
|
|
213
234
|
{t('appPackagesMarketplaceFailed')}
|
|
235
|
+
{onRetry ? <Button className="mt-3 block" variant="outline" size="sm" onClick={onRetry}>{t('appPackagesRefresh')}</Button> : null}
|
|
214
236
|
</div>
|
|
215
237
|
);
|
|
216
238
|
}
|
|
@@ -226,8 +248,8 @@ function MarketplaceCatalogContent({
|
|
|
226
248
|
);
|
|
227
249
|
}
|
|
228
250
|
return (
|
|
229
|
-
<div>
|
|
230
|
-
<div className="grid gap-
|
|
251
|
+
<div className="mx-auto w-full max-w-[872px]">
|
|
252
|
+
<div className="grid gap-1 [@container(min-width:36rem)]:gap-4 [@container(min-width:36rem)]:grid-cols-2 [@container(min-width:52rem)]:grid-cols-3">
|
|
231
253
|
{items.map((item) => (
|
|
232
254
|
<MarketplaceCatalogCard
|
|
233
255
|
key={item.id}
|
|
@@ -239,6 +261,7 @@ function MarketplaceCatalogContent({
|
|
|
239
261
|
onInstall={onInstall}
|
|
240
262
|
onSelect={onSelect}
|
|
241
263
|
onUpdate={onUpdate}
|
|
264
|
+
onManagePackage={onManagePackage}
|
|
242
265
|
operation={findLatestAppPackageOperation(operations, item.appId, item.install.spec)}
|
|
243
266
|
/>
|
|
244
267
|
))}
|
|
@@ -268,6 +291,7 @@ function MarketplaceCatalogCard({
|
|
|
268
291
|
onInstall,
|
|
269
292
|
onSelect,
|
|
270
293
|
onUpdate,
|
|
294
|
+
onManagePackage,
|
|
271
295
|
operation,
|
|
272
296
|
}: {
|
|
273
297
|
installedPackage?: AppPackageView;
|
|
@@ -278,6 +302,7 @@ function MarketplaceCatalogCard({
|
|
|
278
302
|
onInstall: (source: string, registryUrl: string) => void;
|
|
279
303
|
onSelect: (slug: string) => void;
|
|
280
304
|
onUpdate: (appId: string) => void;
|
|
305
|
+
onManagePackage?: (appId: string) => void;
|
|
281
306
|
operation?: AppPackageOperationView;
|
|
282
307
|
}) {
|
|
283
308
|
const displayName = installedPackage
|
|
@@ -298,16 +323,17 @@ function MarketplaceCatalogCard({
|
|
|
298
323
|
);
|
|
299
324
|
const blockAction = Boolean(compatibility && (!installedPackage || canUpdate));
|
|
300
325
|
return (
|
|
301
|
-
<article className="group relative overflow-hidden rounded-
|
|
326
|
+
<article className="group relative overflow-hidden rounded-lg bg-card transition-colors duration-150 hover:bg-[var(--interaction-hover)] [@container(min-width:36rem)]:rounded-2xl [@container(min-width:36rem)]:border [@container(min-width:36rem)]:border-border/60 [@container(min-width:36rem)]:shadow-sm">
|
|
302
327
|
<button
|
|
303
328
|
type="button"
|
|
304
329
|
onClick={() => onSelect(item.slug)}
|
|
305
|
-
|
|
330
|
+
aria-label={displayName}
|
|
331
|
+
className="hidden w-full text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring [@container(min-width:36rem)]:block"
|
|
306
332
|
>
|
|
307
|
-
<AppMarketplaceCover accentColor={item.accentColor} coverPreview={item.coverPreview} coverUrl={item.coverUrl} name={displayName} className="aspect-[16/9] rounded-none ring-0" />
|
|
333
|
+
<AppMarketplaceCover icon={item.iconUrl ?? installedPackage?.icon} accentColor={item.accentColor} coverPreview={item.coverPreview} coverUrl={item.coverUrl} name={displayName} className="aspect-[16/9] rounded-none ring-0" />
|
|
308
334
|
</button>
|
|
309
|
-
<div className="p-3.5">
|
|
310
|
-
<div className="flex items-start gap-
|
|
335
|
+
<div className="grid grid-cols-[minmax(0,1fr)_auto] items-end gap-2 px-2 py-3 [@container(min-width:36rem)]:block [@container(min-width:36rem)]:p-3.5">
|
|
336
|
+
<div className="flex min-w-0 items-start gap-2.5">
|
|
311
337
|
<AppArtwork icon={item.iconUrl ?? installedPackage?.icon} name={displayName} className="h-11 w-11 rounded-[13px]" />
|
|
312
338
|
<button
|
|
313
339
|
type="button"
|
|
@@ -319,24 +345,25 @@ function MarketplaceCatalogCard({
|
|
|
319
345
|
{item.featured ? <Sparkles className="h-3.5 w-3.5 shrink-0 text-amber-500" aria-label={t('appPackagesMarketplaceFeatured')} /> : null}
|
|
320
346
|
</span>
|
|
321
347
|
<MarketplaceCompatibilityBadge presentation={compatibility} />
|
|
322
|
-
<span className="mt-1
|
|
323
|
-
<span className="mt-
|
|
324
|
-
<span>{item.publisher.name}</span>
|
|
325
|
-
<span aria-hidden="true">·</span>
|
|
326
|
-
<span>v{item.latestVersion}</span>
|
|
327
|
-
<span aria-hidden="true">·</span>
|
|
328
|
-
<span>{supportedPlatforms}</span>
|
|
348
|
+
<span className="mt-1 block truncate text-xs leading-5 text-muted-foreground [@container(min-width:36rem)]:line-clamp-2 [@container(min-width:36rem)]:min-h-10 [@container(min-width:36rem)]:whitespace-normal">{summary}</span>
|
|
349
|
+
<span className="mt-1 flex items-center gap-1.5 overflow-hidden text-[11px] text-muted-foreground [@container(min-width:36rem)]:mt-2 [@container(min-width:36rem)]:flex-wrap">
|
|
350
|
+
<span className="truncate">{item.publisher.name}</span>
|
|
351
|
+
<span aria-hidden="true" className="hidden [@container(min-width:36rem)]:inline">·</span>
|
|
352
|
+
<span className="hidden [@container(min-width:36rem)]:inline">v{item.latestVersion}</span>
|
|
353
|
+
<span aria-hidden="true" className="hidden [@container(min-width:36rem)]:inline">·</span>
|
|
354
|
+
<span className="hidden [@container(min-width:36rem)]:inline">{supportedPlatforms}</span>
|
|
329
355
|
<ChevronRight className="ml-0.5 h-3 w-3 opacity-0 transition-opacity group-hover:opacity-60" />
|
|
330
356
|
</span>
|
|
331
357
|
</button>
|
|
332
358
|
</div>
|
|
333
|
-
<div className="
|
|
359
|
+
<div className="flex shrink-0 items-center justify-end gap-2 [@container(min-width:36rem)]:mt-3 [@container(min-width:36rem)]:border-t [@container(min-width:36rem)]:border-border/50 [@container(min-width:36rem)]:pt-3">
|
|
334
360
|
<MarketplaceCompatibilityStatus
|
|
335
361
|
blocked={blockAction}
|
|
336
362
|
presentation={compatibility}
|
|
337
|
-
className="min-w-0 text-[11px] font-medium text-muted-foreground"
|
|
363
|
+
className="hidden min-w-0 text-[11px] font-medium text-muted-foreground [@container(min-width:36rem)]:block"
|
|
338
364
|
/>
|
|
339
365
|
<MarketplaceInstallButton
|
|
366
|
+
onInstalled={onManagePackage ? () => onManagePackage(item.appId) : undefined}
|
|
340
367
|
active={active}
|
|
341
368
|
canUpdate={canUpdate}
|
|
342
369
|
installed={Boolean(installedPackage)}
|
|
@@ -350,7 +377,7 @@ function MarketplaceCatalogCard({
|
|
|
350
377
|
/>
|
|
351
378
|
</div>
|
|
352
379
|
</div>
|
|
353
|
-
{operation && !blockAction && active ? <div className="px-4 pb-4"><OperationProgress operation={operation} /></div> : null}
|
|
380
|
+
{operation && !blockAction && (active || operation.status === 'failed' || operation.status === 'interrupted') ? <div className="px-4 pb-4"><OperationProgress operation={operation} /></div> : null}
|
|
354
381
|
</article>
|
|
355
382
|
);
|
|
356
383
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, type CSSProperties } from 'react';
|
|
2
2
|
import { cn } from '@/shared/lib/utils';
|
|
3
|
+
import { AppArtwork } from './app-artwork';
|
|
3
4
|
|
|
4
5
|
const COVER_PREVIEW_LABEL = import.meta.env.VITE_APP_MARKETPLACE_PREVIEW_LABEL;
|
|
5
6
|
|
|
@@ -9,12 +10,14 @@ export function AppMarketplaceCover({
|
|
|
9
10
|
coverPreview,
|
|
10
11
|
coverUrl,
|
|
11
12
|
name,
|
|
13
|
+
icon,
|
|
12
14
|
}: {
|
|
13
15
|
accentColor?: string;
|
|
14
16
|
className?: string;
|
|
15
17
|
coverPreview?: boolean;
|
|
16
18
|
coverUrl?: string;
|
|
17
19
|
name: string;
|
|
20
|
+
icon?: string;
|
|
18
21
|
}) {
|
|
19
22
|
const [failedUrl, setFailedUrl] = useState<string>();
|
|
20
23
|
const visibleCover = coverUrl && failedUrl !== coverUrl ? coverUrl : undefined;
|
|
@@ -46,9 +49,9 @@ export function AppMarketplaceCover({
|
|
|
46
49
|
aria-label={`${name} 暂无封面`}
|
|
47
50
|
className="flex h-full w-full items-center justify-center bg-[radial-gradient(circle_at_30%_25%,color-mix(in_srgb,var(--app-accent)_28%,transparent),transparent_50%),linear-gradient(145deg,var(--muted),var(--background))]"
|
|
48
51
|
>
|
|
49
|
-
<span className="flex h-14 w-14 items-center justify-center rounded-2xl bg-background/65 text-xl font-semibold text-foreground/65 shadow-sm ring-1 ring-black/[0.05] backdrop-blur-sm">
|
|
52
|
+
{icon ? <AppArtwork icon={icon} name={name} className="h-16 w-16 rounded-2xl" /> : <span className="flex h-14 w-14 items-center justify-center rounded-2xl bg-background/65 text-xl font-semibold text-foreground/65 shadow-sm ring-1 ring-black/[0.05] backdrop-blur-sm">
|
|
50
53
|
{readCoverMonogram(name)}
|
|
51
|
-
</span>
|
|
54
|
+
</span>}
|
|
52
55
|
</span>
|
|
53
56
|
)}
|
|
54
57
|
</span>
|
|
@@ -29,6 +29,7 @@ export function MarketplaceDetail({
|
|
|
29
29
|
localeFallbacks,
|
|
30
30
|
onInstall,
|
|
31
31
|
onUpdate,
|
|
32
|
+
onManagePackage,
|
|
32
33
|
operation,
|
|
33
34
|
}: {
|
|
34
35
|
detail?: AppMarketplaceDetailView;
|
|
@@ -40,6 +41,7 @@ export function MarketplaceDetail({
|
|
|
40
41
|
localeFallbacks: string[];
|
|
41
42
|
onInstall: (source: string, registryUrl: string) => void;
|
|
42
43
|
onUpdate: (appId: string) => void;
|
|
44
|
+
onManagePackage?: (appId: string) => void;
|
|
43
45
|
operation?: AppPackageOperationView;
|
|
44
46
|
}) {
|
|
45
47
|
if (isLoading) {
|
|
@@ -69,9 +71,9 @@ export function MarketplaceDetail({
|
|
|
69
71
|
);
|
|
70
72
|
const blockAction = Boolean(compatibility && (!installedPackage || canUpdate));
|
|
71
73
|
return (
|
|
72
|
-
<div className="mx-auto w-full max-w-3xl px-5 py-5
|
|
73
|
-
<div className="grid items-stretch gap-5
|
|
74
|
-
<AppMarketplaceCover accentColor={detail.accentColor} coverPreview={detail.coverPreview} coverUrl={detail.coverUrl} name={detail.name} className="aspect-[16/9] rounded-2xl" />
|
|
74
|
+
<div className="mx-auto w-full max-w-3xl px-5 py-5 [@container(min-width:40rem)]:px-7 [@container(min-width:40rem)]:py-6">
|
|
75
|
+
<div className="grid items-stretch gap-5 [@container(min-width:40rem)]:grid-cols-[minmax(0,1.18fr)_minmax(240px,0.82fr)]">
|
|
76
|
+
<AppMarketplaceCover icon={detail.iconUrl ?? installedPackage?.icon} accentColor={detail.accentColor} coverPreview={detail.coverPreview} coverUrl={detail.coverUrl} name={detail.name} className="aspect-[16/9] rounded-2xl" />
|
|
75
77
|
<div className="flex min-w-0 flex-col rounded-2xl border border-border/60 bg-card p-4">
|
|
76
78
|
<div className="flex items-start gap-3">
|
|
77
79
|
<AppArtwork icon={detail.iconUrl ?? installedPackage?.icon} name={detail.name} className="h-14 w-14 rounded-2xl" />
|
|
@@ -92,6 +94,7 @@ export function MarketplaceDetail({
|
|
|
92
94
|
className="mb-2 text-xs font-medium text-muted-foreground"
|
|
93
95
|
/>
|
|
94
96
|
<MarketplaceInstallButton
|
|
97
|
+
onInstalled={onManagePackage ? () => onManagePackage(detail.appId) : undefined}
|
|
95
98
|
active={active}
|
|
96
99
|
canUpdate={canUpdate}
|
|
97
100
|
installed={Boolean(installedPackage)}
|
|
@@ -106,14 +109,14 @@ export function MarketplaceDetail({
|
|
|
106
109
|
</div>
|
|
107
110
|
</div>
|
|
108
111
|
</div>
|
|
109
|
-
{operation && !blockAction && active ? <OperationProgress operation={operation} /> : null}
|
|
112
|
+
{operation && !blockAction && (active || operation.status === 'failed' || operation.status === 'interrupted') ? <OperationProgress operation={operation} /> : null}
|
|
110
113
|
|
|
111
114
|
<section className="mt-7">
|
|
112
115
|
<h3 className="text-sm font-semibold text-foreground">{t('appPackagesAboutApp')}</h3>
|
|
113
116
|
<p className="mt-2 text-sm leading-6 text-muted-foreground">{description}</p>
|
|
114
117
|
</section>
|
|
115
118
|
|
|
116
|
-
<div className="mt-6 grid gap-3
|
|
119
|
+
<div className="mt-6 grid gap-3 [@container(min-width:40rem)]:grid-cols-2">
|
|
117
120
|
<DetailFact
|
|
118
121
|
icon={Monitor}
|
|
119
122
|
label={t('appPackagesPlatformsLabel')}
|
|
@@ -155,7 +158,7 @@ export function MarketplaceDetail({
|
|
|
155
158
|
href={detail.webUrl}
|
|
156
159
|
target="_blank"
|
|
157
160
|
rel="noreferrer"
|
|
158
|
-
className="mt-6 inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground underline-offset-4 hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
161
|
+
className="mt-6 inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground underline underline-offset-4 hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
159
162
|
>
|
|
160
163
|
{t('appPackagesOpenPublicDetails')}
|
|
161
164
|
<ExternalLink className="h-3.5 w-3.5" />
|
|
@@ -70,6 +70,7 @@ export function MarketplaceInstallButton({
|
|
|
70
70
|
installed,
|
|
71
71
|
isStarting,
|
|
72
72
|
onAction,
|
|
73
|
+
onInstalled,
|
|
73
74
|
operation,
|
|
74
75
|
unavailableLabel,
|
|
75
76
|
unavailableReason,
|
|
@@ -79,21 +80,22 @@ export function MarketplaceInstallButton({
|
|
|
79
80
|
installed: boolean;
|
|
80
81
|
isStarting: boolean;
|
|
81
82
|
onAction: () => void;
|
|
83
|
+
onInstalled?: () => void;
|
|
82
84
|
operation?: AppPackageOperationView;
|
|
83
85
|
unavailableLabel?: string;
|
|
84
86
|
unavailableReason?: string;
|
|
85
87
|
}) {
|
|
86
|
-
const disabled = Boolean(unavailableReason) || installed && !canUpdate || active || isStarting;
|
|
88
|
+
const disabled = Boolean(unavailableReason) || installed && !canUpdate && !onInstalled || active || isStarting;
|
|
87
89
|
const button = (
|
|
88
90
|
<Button
|
|
89
91
|
type="button"
|
|
90
92
|
size="sm"
|
|
91
93
|
variant={installed && !canUpdate || active ? 'secondary' : 'default'}
|
|
92
94
|
disabled={disabled}
|
|
93
|
-
onClick={onAction}
|
|
95
|
+
onClick={installed && !canUpdate && onInstalled ? onInstalled : onAction}
|
|
94
96
|
className="shrink-0 rounded-full px-4"
|
|
95
97
|
>
|
|
96
|
-
{renderInstallButtonContent({
|
|
98
|
+
{installed && !canUpdate && onInstalled && !active && !isStarting ? t('appPackagesViewInstalled') : renderInstallButtonContent({
|
|
97
99
|
active,
|
|
98
100
|
canUpdate,
|
|
99
101
|
installed,
|
|
@@ -153,6 +155,9 @@ function renderInstallButtonContent({
|
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
export function OperationProgress({ operation }: { operation: AppPackageOperationView }) {
|
|
158
|
+
if (operation.status === 'failed' || operation.status === 'interrupted') {
|
|
159
|
+
return <p role="alert" className="mt-2 text-xs leading-5 text-destructive">{operation.error || t('appPackagesActionFailed')}</p>;
|
|
160
|
+
}
|
|
156
161
|
const progress = Math.max(4, Math.round((operation.completedSteps / operation.totalSteps) * 100));
|
|
157
162
|
return (
|
|
158
163
|
<div className="mt-2" role="status" aria-live="polite">
|