@nextclaw/ui 0.26.4 → 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 +63 -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-CmRdT3N1.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-CdRBL1E0.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-HOgt3gIJ.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-DKKbdJ6Q.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-DE0sB9Nu.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-B9-B9k1A.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-ClLgMbxd.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-CKqS1Ksj.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-CCoxz33Q.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-OGmF0Ws_.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-D8rosOVh.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-BT3GV3Sb.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-DC-Pku0Y.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-BG8VfcdA.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-DPEegUU2.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-CPlctBjT.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-CrGx9_De.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-Cb8ewlUr.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-BM5jC65L.js → use-config-D3cNzk2k.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-ezKJwKqg.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 +5 -5
- package/src/app/configs/__tests__/app-navigation.config.test.ts +4 -2
- package/src/app/configs/app-navigation.config.ts +7 -2
- 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/components/chat-message-list.container.tsx +0 -2
- package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +4 -6
- package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
- package/src/features/chat/features/message/utils/chat-message-process-summary.utils.ts +2 -10
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +2 -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 +2 -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 +5 -9
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +6 -4
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +1 -1
- 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 +16 -5
- package/src/features/inbox/pages/inbox-page.tsx +37 -29
- 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/projects/pages/project-home-page.tsx +4 -2
- 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/platforms/mobile/components/__tests__/mobile-app-shell.test.tsx +9 -0
- package/src/platforms/mobile/components/mobile-app-shell.tsx +4 -2
- package/src/platforms/mobile/components/mobile-topbar.tsx +2 -2
- 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 +5 -5
- 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 +5 -2
- package/src/shared/lib/i18n/locales/en-US/chat.json +14 -9
- 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 +14 -9
- 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-DVi_jhkG.js +0 -1
- package/dist/assets/api-BZvNpFOS.js +0 -20
- package/dist/assets/app-presenter-provider-BcYL-VNe.js +0 -124
- package/dist/assets/appearance-settings-page-AZNBzLmT.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-eZN74FN3.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-BA3V6b3Q.js +0 -1
- package/dist/assets/confirm-dialog-8vqYZ0wy.js +0 -1
- package/dist/assets/context-menu-DHVVdHzN.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
- package/dist/assets/desktop-update-config-Cfr3IRUe.js +0 -1
- package/dist/assets/dialog-BUfWO8hr.js +0 -5
- package/dist/assets/doc-browser-w8q1j0jL.js +0 -1
- package/dist/assets/es2015-BiB05Sav.js +0 -41
- package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
- package/dist/assets/extensions-vPD4dGqt.js +0 -1
- package/dist/assets/eye-bKzylu3p.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-Clq1Gtb1.js +0 -1
- package/dist/assets/login-page-DKId3By8.js +0 -1
- package/dist/assets/main-bEWCGDHr.js +0 -2
- package/dist/assets/main-i18n-catalog.config-Bpu5GcwF.js +0 -1
- package/dist/assets/main-kqMRTwOs.css +0 -1
- package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +0 -1
- package/dist/assets/model-config-page-D21a-BO0.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-D44qmtfk.js +0 -1
- package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
- package/dist/assets/panelStandalone-CX8X2hjh.js +0 -2
- package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
- package/dist/assets/privacy-settings-page-e0LFHZJm.js +0 -1
- package/dist/assets/projects-Rki7Fmth.js +0 -1
- package/dist/assets/provider-models-DFQgF4hS.js +0 -1
- package/dist/assets/provider-scoped-model-input-DaONL0j_.js +0 -1
- package/dist/assets/providers-config-page-CEOhQlMe.js +0 -1
- package/dist/assets/puzzle-D_TiFXOv.js +0 -1
- package/dist/assets/pwa-C9ac_1dg.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-DkSx5x4R.js +0 -1
- package/dist/assets/runtime-config-page-DDT1dVLt.js +0 -1
- package/dist/assets/search-config-page-CDwmd6eX.js +0 -1
- package/dist/assets/secrets-config-page-1OvgmwPv.js +0 -3
- package/dist/assets/security-config-Pv4CM-kw.js +0 -1
- package/dist/assets/select-Y9IEbx9x.js +0 -1
- package/dist/assets/service-apps-panel-DPrLeF3N.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-D-6aPuuh.js +0 -1
- package/dist/assets/theme-provider-BjF1Eowc.js +0 -1
- package/dist/assets/trash-2-DER2EJKK.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-vmbQUNT6.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
- package/dist/assets/x-DSz9cGhy.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
|
@@ -4,7 +4,8 @@ import { useRef, useState } from "react";
|
|
|
4
4
|
import { ChevronLeft, ChevronRight, Inbox } from "lucide-react";
|
|
5
5
|
import { useNavigate } from "react-router-dom";
|
|
6
6
|
import { useAppPresenter } from "@/app/components/app-presenter-provider";
|
|
7
|
-
import {
|
|
7
|
+
import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
|
|
8
|
+
import { buildSessionPath, CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
8
9
|
import { InboxDeliveryContent } from "@/features/inbox/components/inbox-delivery-content";
|
|
9
10
|
import { useInboxDeliveries } from "@/features/inbox/hooks/use-inbox-deliveries";
|
|
10
11
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
Dialog,
|
|
14
15
|
DialogContent,
|
|
15
16
|
DialogDescription,
|
|
17
|
+
DialogHeader,
|
|
16
18
|
DialogTitle,
|
|
17
19
|
} from "@/shared/components/ui/dialog";
|
|
18
20
|
import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
|
|
@@ -28,7 +30,8 @@ function formatPosition(current: number, total: number): string {
|
|
|
28
30
|
export function InboxReaderDialog() {
|
|
29
31
|
const titleRef = useRef<HTMLHeadingElement>(null);
|
|
30
32
|
const navigate = useNavigate();
|
|
31
|
-
const {
|
|
33
|
+
const { chatComposerIntentManager, docBrowserManager, inboxManager } = useAppPresenter();
|
|
34
|
+
const { isMobile } = useViewportLayout();
|
|
32
35
|
const { data } = useInboxDeliveries();
|
|
33
36
|
const { activeDeliveryId, readerOpen } = useInboxStore((state) => state.snapshot);
|
|
34
37
|
const [pendingAction, setPendingAction] = useState<string | null>(null);
|
|
@@ -77,9 +80,10 @@ export function InboxReaderDialog() {
|
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
79
82
|
void runAction("continue", async () => {
|
|
80
|
-
const { reference } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const { reference, targetSessionKey } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
84
|
+
chatComposerIntentManager.requestSystemObjectReference({ targetSessionKey, reference });
|
|
85
|
+
if (isMobile) docBrowserManager.close();
|
|
86
|
+
navigate(targetSessionKey ? buildSessionPath(targetSessionKey) : CHAT_DRAFT_SESSION_PATH);
|
|
83
87
|
});
|
|
84
88
|
};
|
|
85
89
|
|
|
@@ -96,15 +100,18 @@ export function InboxReaderDialog() {
|
|
|
96
100
|
const positionControls = unreadDeliveries.length > 1 ? (
|
|
97
101
|
<div className="flex shrink-0 items-center gap-1 pr-1">
|
|
98
102
|
<span className="mr-1 text-[11px] tabular-nums text-muted-foreground">
|
|
99
|
-
{formatPosition(activeIndex + 1, unreadDeliveries.length)}
|
|
103
|
+
<span className="hidden md:inline">{formatPosition(activeIndex + 1, unreadDeliveries.length)}</span>
|
|
104
|
+
<span className="md:hidden" aria-label={formatPosition(activeIndex + 1, unreadDeliveries.length)}>{activeIndex + 1}/{unreadDeliveries.length}</span>
|
|
100
105
|
</span>
|
|
101
106
|
<IconActionButton
|
|
107
|
+
size="sm"
|
|
102
108
|
icon={<ChevronLeft className="h-4 w-4" />}
|
|
103
109
|
label={t("inboxPrevious")}
|
|
104
110
|
disabled={activeIndex <= 0 || pendingAction === "select"}
|
|
105
111
|
onClick={() => selectAt(activeIndex - 1)}
|
|
106
112
|
/>
|
|
107
113
|
<IconActionButton
|
|
114
|
+
size="sm"
|
|
108
115
|
icon={<ChevronRight className="h-4 w-4" />}
|
|
109
116
|
label={t("inboxNext")}
|
|
110
117
|
disabled={activeIndex >= unreadDeliveries.length - 1 || pendingAction === "select"}
|
|
@@ -123,7 +130,7 @@ export function InboxReaderDialog() {
|
|
|
123
130
|
}}
|
|
124
131
|
>
|
|
125
132
|
<DialogContent
|
|
126
|
-
className="flex h-[min(82vh,760px)] w-[calc(100vw-2rem)] max-w-[820px] flex-col gap-0 overflow-hidden rounded-[24px] border-border/70 bg-background p-0 shadow-[0_20px_55px_-22px_rgba(15,23,42,0.32)] max-
|
|
133
|
+
className="flex h-[min(82vh,760px)] w-[calc(100vw-2rem)] max-w-[820px] flex-col gap-0 overflow-hidden rounded-[24px] border-border/70 bg-background p-0 shadow-[0_20px_55px_-22px_rgba(15,23,42,0.32)] max-md:h-[100dvh] max-md:max-h-[100dvh] max-md:w-screen max-md:max-w-none max-md:rounded-none max-md:border-0 max-md:pt-[env(safe-area-inset-top,0px)] max-md:pb-[env(safe-area-inset-bottom,0px)]"
|
|
127
134
|
onOpenAutoFocus={(event) => {
|
|
128
135
|
event.preventDefault();
|
|
129
136
|
titleRef.current?.focus();
|
|
@@ -131,10 +138,15 @@ export function InboxReaderDialog() {
|
|
|
131
138
|
>
|
|
132
139
|
{activeDelivery ? (
|
|
133
140
|
<>
|
|
134
|
-
<
|
|
135
|
-
|
|
141
|
+
<DialogHeader
|
|
142
|
+
className="items-center gap-1 border-b border-border/50 px-3 py-2 md:gap-3 md:px-6 md:py-3"
|
|
143
|
+
actions={<>
|
|
144
|
+
{positionControls}
|
|
145
|
+
<PageResourceActionsMenu page={pageResourceFromSystemObject("inbox-delivery", activeDelivery.id, activeDelivery.title)} />
|
|
146
|
+
</>}
|
|
147
|
+
>
|
|
136
148
|
<div className="flex min-w-0 items-center gap-2">
|
|
137
|
-
<span className="
|
|
149
|
+
<span className="hidden h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-muted/70 text-muted-foreground md:flex">
|
|
138
150
|
<Inbox className="h-3.5 w-3.5" />
|
|
139
151
|
</span>
|
|
140
152
|
<DialogTitle
|
|
@@ -145,29 +157,24 @@ export function InboxReaderDialog() {
|
|
|
145
157
|
>
|
|
146
158
|
{activeDelivery.title}
|
|
147
159
|
</DialogTitle>
|
|
148
|
-
<span className="hidden shrink-0 text-muted-foreground
|
|
160
|
+
<span className="hidden shrink-0 text-muted-foreground md:inline" aria-hidden="true">·</span>
|
|
149
161
|
<time
|
|
150
|
-
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground
|
|
162
|
+
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground md:block"
|
|
151
163
|
dateTime={activeDelivery.createdAt}
|
|
152
164
|
>
|
|
153
165
|
{formatDateTime(activeDelivery.createdAt)}
|
|
154
166
|
</time>
|
|
155
167
|
</div>
|
|
156
|
-
<div className="flex shrink-0 items-center gap-1">
|
|
157
|
-
{positionControls}
|
|
158
|
-
<PageResourceActionsMenu page={pageResourceFromSystemObject("inbox-delivery", activeDelivery.id, activeDelivery.title)} />
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
168
|
<DialogDescription className="sr-only">
|
|
162
169
|
{activeDelivery.summary ?? t("inboxNoSummary")}
|
|
163
170
|
</DialogDescription>
|
|
164
|
-
</
|
|
171
|
+
</DialogHeader>
|
|
165
172
|
|
|
166
173
|
<div className={cn(
|
|
167
174
|
"min-h-0 flex-1",
|
|
168
175
|
isHtml
|
|
169
|
-
? "p-
|
|
170
|
-
: "custom-scrollbar overflow-y-auto px-
|
|
176
|
+
? "p-0 md:p-4"
|
|
177
|
+
: "custom-scrollbar overflow-y-auto overscroll-contain px-4 py-3 md:px-8 md:py-6",
|
|
171
178
|
)}>
|
|
172
179
|
<InboxDeliveryContent
|
|
173
180
|
className={isHtml ? "h-full" : undefined}
|
|
@@ -178,24 +185,26 @@ export function InboxReaderDialog() {
|
|
|
178
185
|
/>
|
|
179
186
|
</div>
|
|
180
187
|
|
|
181
|
-
<footer className="shrink-0 border-t border-border/50 bg-background px-
|
|
188
|
+
<footer className="shrink-0 border-t border-border/50 bg-background px-3 py-2 md:px-6 md:py-3">
|
|
182
189
|
{error ? (
|
|
183
190
|
<p role="alert" className="mb-3 text-sm text-destructive">{error}</p>
|
|
184
191
|
) : null}
|
|
185
|
-
<div className="flex
|
|
186
|
-
<div className="flex
|
|
187
|
-
<Button size="sm" variant="ghost" onClick={inboxManager.closeReader}>
|
|
192
|
+
<div className="flex items-center justify-between gap-2 [--control-touch-size:2rem]">
|
|
193
|
+
<div className="flex items-center gap-1">
|
|
194
|
+
<Button size="sm" className="px-2 md:px-3" variant="ghost" onClick={inboxManager.closeReader}>
|
|
188
195
|
{t("inboxReadLater")}
|
|
189
196
|
</Button>
|
|
190
|
-
<Button size="sm" variant="outline" disabled={pendingAction !== null} onClick={markRead}>
|
|
197
|
+
<Button size="sm" className="px-2 md:px-3" variant="outline" disabled={pendingAction !== null} onClick={markRead}>
|
|
191
198
|
{t("inboxMarkRead")}
|
|
192
199
|
</Button>
|
|
193
|
-
<Button size="sm" variant="ghost" disabled={pendingAction !== null} onClick={openInbox}>
|
|
194
|
-
{t("
|
|
200
|
+
<Button size="sm" className="px-2 md:px-3" variant="ghost" aria-label={t("inboxOpenInbox")} disabled={pendingAction !== null} onClick={openInbox}>
|
|
201
|
+
<span className="md:hidden">{t("inboxTitle")}</span>
|
|
202
|
+
<span className="hidden md:inline">{t("inboxOpenInbox")}</span>
|
|
195
203
|
</Button>
|
|
196
204
|
</div>
|
|
197
|
-
<Button size="sm" disabled={pendingAction !== null} onClick={continueInChat}>
|
|
198
|
-
{t("
|
|
205
|
+
<Button size="sm" className="px-2 md:px-3" aria-label={t("inboxContinueChat")} disabled={pendingAction !== null} onClick={continueInChat}>
|
|
206
|
+
<span className="md:hidden">{t("inboxContinueChatCompact")}</span>
|
|
207
|
+
<span className="hidden md:inline">{t("inboxContinueChat")}</span>
|
|
199
208
|
</Button>
|
|
200
209
|
</div>
|
|
201
210
|
</footer>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { QueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import type { InboxDelivery } from "@nextclaw/shared";
|
|
4
|
+
import { NextClawClientError } from "@nextclaw/client-sdk";
|
|
4
5
|
import { InboxManager } from "@/features/inbox/managers/inbox.manager";
|
|
5
6
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
6
7
|
|
|
7
8
|
const mocks = vi.hoisted(() => ({
|
|
9
|
+
getDelivery: vi.fn(),
|
|
10
|
+
getSession: vi.fn(),
|
|
8
11
|
delete: vi.fn(),
|
|
9
12
|
resolveReference: vi.fn(),
|
|
10
13
|
list: vi.fn(),
|
|
@@ -16,6 +19,7 @@ vi.mock("@/shared/lib/api", () => ({
|
|
|
16
19
|
nextclawClient: {
|
|
17
20
|
eventBus: { on: mocks.on },
|
|
18
21
|
inboxDeliveries: {
|
|
22
|
+
get: mocks.getDelivery,
|
|
19
23
|
delete: mocks.delete,
|
|
20
24
|
list: mocks.list,
|
|
21
25
|
updateState: mocks.updateState,
|
|
@@ -23,6 +27,7 @@ vi.mock("@/shared/lib/api", () => ({
|
|
|
23
27
|
systemObjectReferences: {
|
|
24
28
|
resolve: mocks.resolveReference,
|
|
25
29
|
},
|
|
30
|
+
sessions: { get: mocks.getSession },
|
|
26
31
|
},
|
|
27
32
|
}));
|
|
28
33
|
|
|
@@ -43,6 +48,8 @@ const delivery: InboxDelivery = {
|
|
|
43
48
|
describe("InboxManager", () => {
|
|
44
49
|
beforeEach(() => {
|
|
45
50
|
vi.clearAllMocks();
|
|
51
|
+
mocks.getDelivery.mockResolvedValue(delivery);
|
|
52
|
+
mocks.getSession.mockResolvedValue({ sessionId: "source-session" });
|
|
46
53
|
Object.defineProperty(document, "visibilityState", { configurable: true, value: "visible" });
|
|
47
54
|
useInboxStore.setState({
|
|
48
55
|
snapshot: { readerOpen: false, activeDeliveryId: null },
|
|
@@ -107,5 +114,26 @@ describe("InboxManager", () => {
|
|
|
107
114
|
);
|
|
108
115
|
expect(mocks.updateState).toHaveBeenCalledWith(delivery.id, "read");
|
|
109
116
|
expect(result.reference.assetUri).toBe("asset://store/report");
|
|
117
|
+
expect(result.targetSessionKey).toBeNull();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("targets the original report session", async () => {
|
|
121
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "source-session" } });
|
|
122
|
+
const result = await new InboxManager(new QueryClient()).prepareChatReference(delivery.id);
|
|
123
|
+
expect(mocks.getSession).toHaveBeenCalledWith("source-session");
|
|
124
|
+
expect(result.targetSessionKey).toBe("source-session");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("falls back to a draft only when the source session was deleted", async () => {
|
|
128
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "deleted" } });
|
|
129
|
+
mocks.getSession.mockRejectedValueOnce(new NextClawClientError({ message: "Missing", status: 404 }));
|
|
130
|
+
expect((await new InboxManager(new QueryClient()).prepareChatReference(delivery.id)).targetSessionKey).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("keeps the report unread when the source session lookup fails", async () => {
|
|
134
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "source-session" } });
|
|
135
|
+
mocks.getSession.mockRejectedValueOnce(new NextClawClientError({ message: "Offline", status: 503 }));
|
|
136
|
+
await expect(new InboxManager(new QueryClient()).prepareChatReference(delivery.id)).rejects.toThrow("Offline");
|
|
137
|
+
expect(mocks.updateState).not.toHaveBeenCalled();
|
|
110
138
|
});
|
|
111
139
|
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { appQueryClient } from "@/app-query-client";
|
|
14
14
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
15
15
|
import { nextclawClient } from "@/shared/lib/api";
|
|
16
|
+
import { NextClawClientError } from "@nextclaw/client-sdk";
|
|
16
17
|
|
|
17
18
|
export const INBOX_DELIVERIES_QUERY_KEY = ["inbox-deliveries"] as const;
|
|
18
19
|
|
|
@@ -112,13 +113,26 @@ export class InboxManager {
|
|
|
112
113
|
prepareChatReference = async (deliveryId: string): Promise<{
|
|
113
114
|
delivery: InboxDelivery;
|
|
114
115
|
reference: SystemObjectResolvedReference;
|
|
116
|
+
targetSessionKey: string | null;
|
|
115
117
|
}> => {
|
|
116
|
-
const reference = await
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
const [reference, sourceDelivery] = await Promise.all([
|
|
119
|
+
nextclawClient.systemObjectReferences.resolve(
|
|
120
|
+
createSystemObjectReferenceUri(SYSTEM_OBJECT_TYPE_INBOX_DELIVERY, deliveryId),
|
|
121
|
+
),
|
|
122
|
+
nextclawClient.inboxDeliveries.get(deliveryId),
|
|
123
|
+
]);
|
|
124
|
+
let targetSessionKey = sourceDelivery.source.sessionId?.trim() || null;
|
|
125
|
+
if (targetSessionKey) {
|
|
126
|
+
try {
|
|
127
|
+
await nextclawClient.sessions.get(targetSessionKey);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (!(error instanceof NextClawClientError) || error.status !== 404) throw error;
|
|
130
|
+
targetSessionKey = null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
119
133
|
const delivery = await this.updateState(deliveryId, "read");
|
|
120
134
|
this.closeReader();
|
|
121
|
-
return { delivery, reference };
|
|
135
|
+
return { delivery, reference, targetSessionKey };
|
|
122
136
|
};
|
|
123
137
|
|
|
124
138
|
private updateState = async (
|
|
@@ -7,13 +7,15 @@ import { InboxPage, resolveInboxFilter } from "@/features/inbox/pages/inbox-page
|
|
|
7
7
|
import { t } from "@/shared/lib/i18n";
|
|
8
8
|
|
|
9
9
|
const mocks = vi.hoisted(() => ({
|
|
10
|
+
isMobile: false,
|
|
10
11
|
prepareChatReference: vi.fn(),
|
|
11
12
|
requestSystemObjectReference: vi.fn(),
|
|
12
13
|
}));
|
|
13
14
|
|
|
14
15
|
vi.mock("@/app/components/app-presenter-provider", () => ({
|
|
15
16
|
useAppPresenter: () => ({
|
|
16
|
-
|
|
17
|
+
docBrowserManager: { close: vi.fn() },
|
|
18
|
+
chatComposerIntentManager: {
|
|
17
19
|
requestSystemObjectReference: mocks.requestSystemObjectReference,
|
|
18
20
|
},
|
|
19
21
|
inboxManager: {
|
|
@@ -28,7 +30,7 @@ vi.mock("@/app/components/app-presenter-provider", () => ({
|
|
|
28
30
|
}));
|
|
29
31
|
|
|
30
32
|
vi.mock("@/app/hooks/use-viewport-layout", () => ({
|
|
31
|
-
useViewportLayout: () => ({ isMobile:
|
|
33
|
+
useViewportLayout: () => ({ isMobile: mocks.isMobile }),
|
|
32
34
|
}));
|
|
33
35
|
|
|
34
36
|
vi.mock("@/features/inbox/hooks/use-inbox-deliveries", () => ({
|
|
@@ -101,7 +103,9 @@ describe("resolveInboxFilter", () => {
|
|
|
101
103
|
describe("InboxPage", () => {
|
|
102
104
|
beforeEach(() => {
|
|
103
105
|
vi.clearAllMocks();
|
|
106
|
+
mocks.isMobile = false;
|
|
104
107
|
mocks.prepareChatReference.mockResolvedValue({
|
|
108
|
+
targetSessionKey: null,
|
|
105
109
|
reference: {
|
|
106
110
|
uri: "nextclaw://objects/inbox-delivery/delivery-1",
|
|
107
111
|
label: "A considered report",
|
|
@@ -109,7 +113,8 @@ describe("InboxPage", () => {
|
|
|
109
113
|
});
|
|
110
114
|
});
|
|
111
115
|
|
|
112
|
-
it("opens a draft with the same
|
|
116
|
+
it.each([false, true])("opens a draft with the same system object intent (mobile=%s)", async (isMobile) => {
|
|
117
|
+
mocks.isMobile = isMobile;
|
|
113
118
|
render(
|
|
114
119
|
createElement(
|
|
115
120
|
MemoryRouter,
|
|
@@ -134,14 +139,20 @@ describe("InboxPage", () => {
|
|
|
134
139
|
),
|
|
135
140
|
);
|
|
136
141
|
|
|
137
|
-
|
|
142
|
+
const continueButton = screen.getByRole("button", { name: t("inboxContinueChat") });
|
|
143
|
+
if (isMobile) {
|
|
144
|
+
const moreButton = screen.getByRole("button", { name: t("more") });
|
|
145
|
+
expect(continueButton.compareDocumentPosition(moreButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
|
146
|
+
expect(screen.getByRole("button", { name: t("inboxTitle") })).toBeTruthy();
|
|
147
|
+
}
|
|
148
|
+
fireEvent.click(continueButton);
|
|
138
149
|
|
|
139
150
|
await waitFor(() => {
|
|
140
151
|
expect(screen.getByTestId("current-path").textContent).toBe(CHAT_DRAFT_SESSION_PATH);
|
|
141
152
|
});
|
|
142
153
|
expect(mocks.prepareChatReference).toHaveBeenCalledWith("delivery-1");
|
|
143
154
|
expect(mocks.requestSystemObjectReference).toHaveBeenCalledWith(
|
|
144
|
-
expect.objectContaining({ uri: "nextclaw://objects/inbox-delivery/delivery-1" }),
|
|
155
|
+
{ targetSessionKey: null, reference: expect.objectContaining({ uri: "nextclaw://objects/inbox-delivery/delivery-1" }) },
|
|
145
156
|
);
|
|
146
157
|
});
|
|
147
158
|
});
|
|
@@ -2,14 +2,14 @@ import { PageResourceActionsMenu } from '@/features/right-panel-resources';
|
|
|
2
2
|
import { pageResourceFromSystemObject } from '@/features/right-panel-resources';
|
|
3
3
|
import { useEffect, useMemo, useState } from "react";
|
|
4
4
|
import type { InboxDelivery } from "@nextclaw/shared";
|
|
5
|
-
import { Archive, Inbox, MessageCircle, MoreVertical, RotateCcw, Trash2 } from "lucide-react";
|
|
5
|
+
import { Archive, ArrowLeft, Inbox, MessageCircle, MoreVertical, RotateCcw, Trash2 } from "lucide-react";
|
|
6
6
|
import { ContextMenu, ContextMenuTrigger } from '@/shared/components/ui/context-menu/context-menu';
|
|
7
7
|
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
8
8
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
|
9
9
|
import { useAppPresenter } from "@/app/components/app-presenter-provider";
|
|
10
10
|
import { PageHeader } from "@/app/components/layout/page-layout";
|
|
11
11
|
import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
|
|
12
|
-
import { CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
12
|
+
import { buildSessionPath, CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
13
13
|
import { InboxDeliveryContent } from "@/features/inbox/components/inbox-delivery-content";
|
|
14
14
|
import { useInboxDeliveries } from "@/features/inbox/hooks/use-inbox-deliveries";
|
|
15
15
|
import { Button } from "@/shared/components/ui/button";
|
|
@@ -167,6 +167,7 @@ function InboxListPane({
|
|
|
167
167
|
|
|
168
168
|
function InboxDetailPane({
|
|
169
169
|
delivery,
|
|
170
|
+
isMobile,
|
|
170
171
|
error,
|
|
171
172
|
pending,
|
|
172
173
|
onArchiveToggle,
|
|
@@ -175,6 +176,7 @@ function InboxDetailPane({
|
|
|
175
176
|
onReadToggle,
|
|
176
177
|
}: {
|
|
177
178
|
delivery: InboxDelivery | null;
|
|
179
|
+
isMobile: boolean;
|
|
178
180
|
error: string | null;
|
|
179
181
|
pending: boolean;
|
|
180
182
|
onArchiveToggle: () => void;
|
|
@@ -182,38 +184,52 @@ function InboxDetailPane({
|
|
|
182
184
|
onDelete: () => void;
|
|
183
185
|
onReadToggle: () => void;
|
|
184
186
|
}) {
|
|
187
|
+
const navigate = useNavigate();
|
|
188
|
+
const backButton = <IconActionButton size="sm" icon={<ArrowLeft className="h-4 w-4" />} label={t("inboxTitle")} onClick={() => navigate('/inbox')} />;
|
|
185
189
|
const scrollRestoration = useScrollRestoration<HTMLDivElement>({
|
|
186
190
|
restorationKey: delivery ? `inbox:delivery:${delivery.id}` : null,
|
|
187
191
|
});
|
|
188
192
|
const { onScroll, scrollRef } = scrollRestoration;
|
|
189
193
|
if (!delivery) {
|
|
190
|
-
return <main className="flex min-h-0 flex-col"><InboxEmptyState selection /></main>;
|
|
194
|
+
return <main className="flex min-h-0 flex-col"><div className="md:hidden">{backButton}</div><InboxEmptyState selection /></main>;
|
|
191
195
|
}
|
|
192
196
|
const isHtml = delivery.contentType === "html";
|
|
193
197
|
return (
|
|
194
|
-
<main className="flex min-h-0 flex-col">
|
|
195
|
-
<div className="shrink-0
|
|
196
|
-
<div className="flex min-h-7 min-w-0 items-center gap-
|
|
198
|
+
<main className="flex min-h-0 min-w-0 flex-col max-md:pt-[env(safe-area-inset-top,0px)] max-md:pb-[env(safe-area-inset-bottom,0px)]">
|
|
199
|
+
<div className="shrink-0 border-b border-border/50 px-2 py-2 md:px-6 md:py-3">
|
|
200
|
+
<div className="flex min-h-7 min-w-0 items-center gap-1">
|
|
201
|
+
<div className="md:hidden">{backButton}</div>
|
|
197
202
|
<h2
|
|
198
203
|
title={delivery.title}
|
|
199
|
-
className="min-w-0 truncate text-sm font-medium text-foreground"
|
|
204
|
+
className="min-w-0 flex-1 truncate text-sm font-medium text-foreground md:flex-none"
|
|
200
205
|
>
|
|
201
206
|
{delivery.title}
|
|
202
207
|
</h2>
|
|
203
|
-
<span className="hidden shrink-0 text-muted-foreground
|
|
208
|
+
<span className="hidden shrink-0 text-muted-foreground md:inline" aria-hidden="true">·</span>
|
|
204
209
|
<time
|
|
205
|
-
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground
|
|
210
|
+
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground md:block"
|
|
206
211
|
dateTime={delivery.createdAt}
|
|
207
212
|
>
|
|
208
213
|
{formatDateTime(delivery.createdAt)}
|
|
209
214
|
</time>
|
|
215
|
+
{isMobile ? <div className="flex shrink-0 items-center">
|
|
216
|
+
<IconActionButton size="sm" icon={<MessageCircle className="h-4 w-4" />} label={t('inboxContinueChat')} disabled={pending} onClick={onContinue} />
|
|
217
|
+
<ContextMenu label={t('inboxTitle')} groups={[{ key: 'delivery', items: [
|
|
218
|
+
{ key: 'read', label: delivery.readAt ? t('inboxMarkUnread') : t('inboxMarkRead'), disabled: pending, onSelect: onReadToggle },
|
|
219
|
+
{ key: 'archive', label: delivery.archivedAt ? t('inboxRestore') : t('inboxArchive'), icon: <Archive className="h-4 w-4" />, disabled: pending, onSelect: onArchiveToggle },
|
|
220
|
+
{ key: 'delete', label: t('inboxDelete'), icon: <Trash2 className="h-4 w-4" />, destructive: true, disabled: pending, onSelect: onDelete },
|
|
221
|
+
] }]}>
|
|
222
|
+
<div><ContextMenuTrigger><IconActionButton size="sm" icon={<MoreVertical className="h-4 w-4" />} label={t('more')} /></ContextMenuTrigger></div>
|
|
223
|
+
</ContextMenu>
|
|
224
|
+
</div> : null}
|
|
210
225
|
</div>
|
|
211
226
|
</div>
|
|
227
|
+
{error ? <p role="alert" className="shrink-0 px-4 py-2 text-sm text-destructive">{error}</p> : null}
|
|
212
228
|
<div className={cn(
|
|
213
229
|
"min-h-0 flex-1",
|
|
214
230
|
isHtml
|
|
215
231
|
? "p-0 md:p-4"
|
|
216
|
-
: "custom-scrollbar overflow-y-auto px-
|
|
232
|
+
: "custom-scrollbar overflow-y-auto overscroll-contain px-4 py-4 sm:px-6 sm:py-6",
|
|
217
233
|
)}
|
|
218
234
|
ref={scrollRef}
|
|
219
235
|
onScroll={onScroll}
|
|
@@ -228,8 +244,7 @@ function InboxDetailPane({
|
|
|
228
244
|
/>
|
|
229
245
|
</div>
|
|
230
246
|
</div>
|
|
231
|
-
<div className="shrink-0 border-t border-border/50 px-
|
|
232
|
-
{error ? <p role="alert" className="mb-2 text-sm text-destructive">{error}</p> : null}
|
|
247
|
+
{!isMobile ? <div className="shrink-0 border-t border-border/50 px-6 py-3">
|
|
233
248
|
<div className="flex items-center justify-between gap-2">
|
|
234
249
|
<div className="hidden md:flex flex-wrap items-center gap-1">
|
|
235
250
|
<Button size="sm" variant="outline" disabled={pending} onClick={onReadToggle}>
|
|
@@ -246,21 +261,12 @@ function InboxDetailPane({
|
|
|
246
261
|
{t("inboxDelete")}
|
|
247
262
|
</Button>
|
|
248
263
|
</div>
|
|
249
|
-
<div className="md:hidden">
|
|
250
|
-
<ContextMenu label={t('inboxTitle')} groups={[{ key: 'delivery', items: [
|
|
251
|
-
{ key: 'read', label: delivery.readAt ? t('inboxMarkUnread') : t('inboxMarkRead'), disabled: pending, onSelect: onReadToggle },
|
|
252
|
-
{ key: 'archive', label: delivery.archivedAt ? t('inboxRestore') : t('inboxArchive'), icon: <Archive className="h-4 w-4" />, disabled: pending, onSelect: onArchiveToggle },
|
|
253
|
-
{ key: 'delete', label: t('inboxDelete'), icon: <Trash2 className="h-4 w-4" />, destructive: true, disabled: pending, onSelect: onDelete },
|
|
254
|
-
] }]}>
|
|
255
|
-
<div><ContextMenuTrigger><IconActionButton icon={<MoreVertical className="h-4 w-4" />} label={t('more')} /></ContextMenuTrigger></div>
|
|
256
|
-
</ContextMenu>
|
|
257
|
-
</div>
|
|
258
264
|
<Button size="sm" disabled={pending} onClick={onContinue}>
|
|
259
265
|
<MessageCircle className="mr-2 h-4 w-4" />
|
|
260
266
|
{t("inboxContinueChat")}
|
|
261
267
|
</Button>
|
|
262
268
|
</div>
|
|
263
|
-
</div>
|
|
269
|
+
</div> : null}
|
|
264
270
|
</main>
|
|
265
271
|
);
|
|
266
272
|
}
|
|
@@ -269,7 +275,7 @@ export function InboxPage() {
|
|
|
269
275
|
const navigate = useNavigate();
|
|
270
276
|
const { deliveryId } = useParams<{ deliveryId?: string }>();
|
|
271
277
|
const { isMobile } = useViewportLayout();
|
|
272
|
-
const {
|
|
278
|
+
const { chatComposerIntentManager, docBrowserManager, inboxManager } = useAppPresenter();
|
|
273
279
|
const deliveriesQuery = useInboxDeliveries();
|
|
274
280
|
const { confirm, ConfirmDialog } = useConfirmDialog();
|
|
275
281
|
const [selectedFilter, setSelectedFilter] = useState<InboxFilter | null>(null);
|
|
@@ -310,9 +316,10 @@ export function InboxPage() {
|
|
|
310
316
|
return;
|
|
311
317
|
}
|
|
312
318
|
void runAction("continue", async () => {
|
|
313
|
-
const { reference } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
314
|
-
|
|
315
|
-
|
|
319
|
+
const { reference, targetSessionKey } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
320
|
+
chatComposerIntentManager.requestSystemObjectReference({ targetSessionKey, reference });
|
|
321
|
+
if (isMobile) docBrowserManager.close();
|
|
322
|
+
navigate(targetSessionKey ? buildSessionPath(targetSessionKey) : CHAT_DRAFT_SESSION_PATH);
|
|
316
323
|
});
|
|
317
324
|
};
|
|
318
325
|
|
|
@@ -359,8 +366,8 @@ export function InboxPage() {
|
|
|
359
366
|
});
|
|
360
367
|
};
|
|
361
368
|
|
|
362
|
-
const showList = !isMobile || !
|
|
363
|
-
const showDetail = !isMobile || Boolean(
|
|
369
|
+
const showList = !isMobile || !deliveryId;
|
|
370
|
+
const showDetail = !isMobile || Boolean(deliveryId);
|
|
364
371
|
|
|
365
372
|
return (
|
|
366
373
|
<div className="flex h-full min-h-0 flex-col md:gap-6">
|
|
@@ -372,7 +379,7 @@ export function InboxPage() {
|
|
|
372
379
|
|
|
373
380
|
<div className="min-h-0 flex-1 overflow-hidden bg-background md:rounded-2xl md:border md:border-border/60">
|
|
374
381
|
{deliveriesQuery.isError ? (
|
|
375
|
-
<div role="alert" className="
|
|
382
|
+
<div className="p-4">{isMobile && deliveryId ? <IconActionButton icon={<ArrowLeft className="h-4 w-4" />} label={t("inboxTitle")} onClick={() => navigate('/inbox')} /> : null}<p role="alert" className="text-sm text-destructive">{t("inboxLoadError")}</p></div>
|
|
376
383
|
) : (
|
|
377
384
|
<div className="grid h-full min-h-0 grid-cols-1 md:grid-cols-[300px_minmax(0,1fr)]">
|
|
378
385
|
{showList ? <InboxListPane
|
|
@@ -383,6 +390,7 @@ export function InboxPage() {
|
|
|
383
390
|
/> : null}
|
|
384
391
|
{showDetail ? <InboxDetailPane
|
|
385
392
|
delivery={activeDelivery}
|
|
393
|
+
isMobile={isMobile}
|
|
386
394
|
error={error}
|
|
387
395
|
pending={pendingAction !== null}
|
|
388
396
|
onArchiveToggle={toggleArchive}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
|
|
1
2
|
import { useState, type MouseEvent } from 'react';
|
|
2
3
|
import { MoreVertical, Star, Trash2, type LucideIcon } from 'lucide-react';
|
|
3
4
|
import type { PanelAppEntryView } from '@/shared/lib/api';
|
|
@@ -127,13 +128,13 @@ function PanelAppMenuItem({
|
|
|
127
128
|
<button
|
|
128
129
|
type="button"
|
|
129
130
|
className={cn(
|
|
130
|
-
|
|
131
|
-
destructive ?
|
|
131
|
+
ACTION_MENU_ITEM_CLASS,
|
|
132
|
+
destructive ? ACTION_FEEDBACK.destructive : `text-foreground ${ACTION_FEEDBACK.item}`,
|
|
132
133
|
)}
|
|
133
134
|
disabled={disabled}
|
|
134
135
|
onClick={onClick}
|
|
135
136
|
>
|
|
136
|
-
<Icon className="h-4 w-4 shrink-0" />
|
|
137
|
+
<Icon className={cn("h-4 w-4 shrink-0", !destructive && "text-muted-foreground")} />
|
|
137
138
|
<span>{label}</span>
|
|
138
139
|
</button>
|
|
139
140
|
);
|
package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx
CHANGED
|
@@ -26,8 +26,8 @@ export function PanelAppServiceActionAuthorizationDialog() {
|
|
|
26
26
|
}
|
|
27
27
|
}}
|
|
28
28
|
>
|
|
29
|
-
<DialogContent
|
|
30
|
-
<DialogHeader>
|
|
29
|
+
<DialogContent>
|
|
30
|
+
<DialogHeader showClose={false}>
|
|
31
31
|
<DialogTitle className="flex items-center gap-2">
|
|
32
32
|
<ShieldAlert className="h-4 w-4 text-amber-600" />
|
|
33
33
|
{t('serviceActionAuthorizationTitle')}
|
|
@@ -2,16 +2,15 @@ import { AppWindow, Boxes } from 'lucide-react';
|
|
|
2
2
|
import type { DocBrowserContextValue } from '@/shared/components/doc-browser/doc-browser-context';
|
|
3
3
|
import type { DocBrowserCustomTabRenderers } from '@/shared/components/doc-browser/doc-browser-renderer.types';
|
|
4
4
|
import { getPresenter } from '@/app/presenters/app.presenter';
|
|
5
|
-
import { AppsPanel
|
|
5
|
+
import { AppsPanel } from '@/features/apps';
|
|
6
6
|
import { PanelAppDocBrowserToolbar } from '@/features/panel-apps/components/panel-app-toolbar';
|
|
7
7
|
import {
|
|
8
8
|
createPanelAppRightPanelResourceTarget,
|
|
9
9
|
RIGHT_PANEL_APPS_TAB_KIND,
|
|
10
|
-
|
|
10
|
+
createRightPanelAppsUrl,
|
|
11
|
+
getRightPanelAppsTabFromUrl,
|
|
11
12
|
RIGHT_PANEL_HOME_TAB_KIND,
|
|
12
13
|
RIGHT_PANEL_PANEL_APP_TAB_KIND,
|
|
13
|
-
RIGHT_PANEL_PANEL_APPS_URL,
|
|
14
|
-
RIGHT_PANEL_SERVICE_APPS_URL,
|
|
15
14
|
RightPanelResourceHomePage,
|
|
16
15
|
} from '@/features/right-panel-resources';
|
|
17
16
|
import { t } from '@/shared/lib/i18n';
|
|
@@ -19,26 +18,8 @@ import { PANEL_APP_IFRAME_SANDBOX, focusPanelAppIframe } from './panel-app-ifram
|
|
|
19
18
|
|
|
20
19
|
export const APPS_TAB_KIND = RIGHT_PANEL_APPS_TAB_KIND;
|
|
21
20
|
export const PANEL_APP_TAB_KIND = RIGHT_PANEL_PANEL_APP_TAB_KIND;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
function isAppsPanelTab(value: unknown): value is AppsPanelTab {
|
|
25
|
-
return value === 'apps' || value === 'panel-apps' || value === 'service-apps';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function createAppsPanelUrl(tab: AppsPanelTab = DEFAULT_APPS_PANEL_TAB): string {
|
|
29
|
-
if (tab === 'panel-apps') return RIGHT_PANEL_PANEL_APPS_URL;
|
|
30
|
-
if (tab === 'service-apps') return RIGHT_PANEL_SERVICE_APPS_URL;
|
|
31
|
-
return RIGHT_PANEL_APPS_URL;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function getAppsPanelTabFromUrl(url: string): AppsPanelTab {
|
|
35
|
-
try {
|
|
36
|
-
const tab = new URL(url).searchParams.get('tab');
|
|
37
|
-
return isAppsPanelTab(tab) ? tab : DEFAULT_APPS_PANEL_TAB;
|
|
38
|
-
} catch {
|
|
39
|
-
return DEFAULT_APPS_PANEL_TAB;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
21
|
+
export const createAppsPanelUrl = createRightPanelAppsUrl;
|
|
22
|
+
export const getAppsPanelTabFromUrl = getRightPanelAppsTabFromUrl;
|
|
42
23
|
|
|
43
24
|
export function openApps(docBrowser: Pick<DocBrowserContextValue, 'open'>): void {
|
|
44
25
|
docBrowser.open(createAppsPanelUrl(), {
|
|
@@ -255,7 +255,7 @@ function ProjectWorkStateGroup({
|
|
|
255
255
|
<div
|
|
256
256
|
className={
|
|
257
257
|
view === "board"
|
|
258
|
-
? "min-h-0 flex-1 space-y-2 overflow-y-auto
|
|
258
|
+
? "min-h-0 flex-1 space-y-2 overflow-y-auto px-1 pb-3"
|
|
259
259
|
: "space-y-2 px-1 pb-3"
|
|
260
260
|
}
|
|
261
261
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { useNavigate, useParams } from "react-router-dom";
|
|
2
|
+
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
|
3
3
|
import { useProjects } from "@/shared/hooks/use-projects";
|
|
4
4
|
import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
|
|
5
5
|
import { t } from "@/shared/lib/i18n";
|
|
@@ -43,6 +43,7 @@ export function ProjectsPage() {
|
|
|
43
43
|
tab?: string;
|
|
44
44
|
}>();
|
|
45
45
|
const navigate = useNavigate();
|
|
46
|
+
const { state } = useLocation();
|
|
46
47
|
const presenter = usePresenter();
|
|
47
48
|
const { isMobile } = useViewportLayout();
|
|
48
49
|
const projects = useProjects();
|
|
@@ -86,7 +87,7 @@ export function ProjectsPage() {
|
|
|
86
87
|
<select
|
|
87
88
|
id="project-home-selection"
|
|
88
89
|
value=""
|
|
89
|
-
onChange={(event) => navigate(`/projects/${encodeURIComponent(event.target.value)}/overview
|
|
90
|
+
onChange={(event) => navigate(`/projects/${encodeURIComponent(event.target.value)}/overview`, { state })}
|
|
90
91
|
className="min-h-11 w-full rounded-xl border border-border bg-card px-3 text-base text-foreground"
|
|
91
92
|
>
|
|
92
93
|
<option value="" disabled>{t("projectsChoose")}</option>
|
|
@@ -117,6 +118,7 @@ export function ProjectsPage() {
|
|
|
117
118
|
onValueChange={(value) =>
|
|
118
119
|
navigate(
|
|
119
120
|
`/projects/${encodeURIComponent(selectedProject.id)}/${value}`,
|
|
121
|
+
{ state },
|
|
120
122
|
)
|
|
121
123
|
}
|
|
122
124
|
>
|