@openhands/agent-canvas 1.2.1 → 1.3.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/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{Trans-De9RwQhA.js → Trans-DY6toRDu.js} +1 -1
- package/build/assets/{acp-providers-D_D8VUpP.js → acp-providers-Djl6vNn-.js} +1 -1
- package/build/assets/active-backend-context-B3umL5R-.js +1 -0
- package/build/assets/{add-backend-modal-DIEyAkA4.js → add-backend-modal-DljoP9lc.js} +1 -1
- package/build/assets/{agent-profiles-settings-BovdV4N8.js → agent-profiles-settings-BJMmTZgv.js} +1 -1
- package/build/assets/{agent-server-conversation-service.api-BP73yONA.js → agent-server-conversation-service.api-D_ZvtJjG.js} +3 -3
- package/build/assets/agent-settings-BVVFzBWS.js +1 -0
- package/build/assets/{agent-settings-Ofbh6UTD.js → agent-settings-lUknCeaF.js} +1 -1
- package/build/assets/{alert-banner-BW0wRYw6.js → alert-banner-Bpf2NQJq.js} +1 -1
- package/build/assets/{api-key-entry-screen-CZIdRmUJ.js → api-key-entry-screen-CWEHcPJA.js} +1 -1
- package/build/assets/{app-settings-BHJ9nKti.js → app-settings-Dj90qosy.js} +1 -1
- package/build/assets/automation-detail-CXJU0_gF.js +2 -0
- package/build/assets/automation-export-FWY9LPsG.js +2 -0
- package/build/assets/automations-list-DDGBkWLC.js +1 -0
- package/build/assets/{back-nav-button-BYmxFxGt.js → back-nav-button-CUS2mi-U.js} +1 -1
- package/build/assets/{backend-form-modal-BiaOB2C4.js → backend-form-modal-DSbrafX2.js} +1 -1
- package/build/assets/{backend-synced-settings-badge-Bs3FSXsS.js → backend-synced-settings-badge-CanzmG12.js} +1 -1
- package/build/assets/{base-modal-CC5Pp8CF.js → base-modal-BuF2f0YL.js} +1 -1
- package/build/assets/{brand-button-DKPMEKcW.js → brand-button-vMVuyDXu.js} +1 -1
- package/build/assets/{browser-B39N74jU.js → browser-BifzWIBd.js} +1 -1
- package/build/assets/{browser-tab-aiDg7aEn.js → browser-tab-CkkqJnqw.js} +1 -1
- package/build/assets/{chat-send-button-DxuZIoW8.js → chat-send-button-B_jc5z5C.js} +1 -1
- package/build/assets/{circle-plus-check-toggle-T3eAIuPQ.js → circle-plus-check-toggle-C5YxjxvI.js} +1 -1
- package/build/assets/{combobox-caret-CLGvOs32.js → combobox-caret-DoObzqf4.js} +1 -1
- package/build/assets/{command-menu-DKrLCRla.js → command-menu-D-JV3Wqm.js} +1 -1
- package/build/assets/{condenser-settings-D_5vY4m3.js → condenser-settings-30cX9SK6.js} +1 -1
- package/build/assets/{confirmation-modal-BK1F0A68.js → confirmation-modal-BGLu6XJN.js} +1 -1
- package/build/assets/{context-menu-list-item-DBFzplWW.js → context-menu-list-item-BD5_EaKN.js} +1 -1
- package/build/assets/conversation-BltULtFA.js +89 -0
- package/build/assets/conversation-e0a0_X4S.js +1 -0
- package/build/assets/conversation-panel-Cr9_ZGI-.js +1 -0
- package/build/assets/{conversation-service.api-CqZcHr1c.js → conversation-service.api-DQaKzIRj.js} +1 -1
- package/build/assets/{conversation-tab-empty-state-m8IUkfMj.js → conversation-tab-empty-state-B2dDYEwf.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-Aj9wFmt2.js → copy-to-clipboard-button-CaR52OnA.js} +1 -1
- package/build/assets/declaration-gq8V5eTU.js +1 -0
- package/build/assets/{device-verify-B5YCrvSu.js → device-verify-BsznkV-a.js} +1 -1
- package/build/assets/{dropdown-classes-CgQ45JmQ.js → dropdown-classes-DJSXeLqc.js} +1 -1
- package/build/assets/{ellipsis-button-1BV9Sga8.js → ellipsis-button-C5Z-tPFp.js} +1 -1
- package/build/assets/{entry.client-Dy--3GeA.js → entry.client-JixNvFrr.js} +2 -2
- package/build/assets/{enum-filter-dropdown-DCITiYVi.js → enum-filter-dropdown-DXbVwiNZ.js} +1 -1
- package/build/assets/{environment-switch-overlay-DUnKILNH.js → environment-switch-overlay-DZQfRGTx.js} +1 -1
- package/build/assets/{extensions-hub-CksKNpP9.js → extensions-hub-DfvgqzTc.js} +1 -1
- package/build/assets/{extensions-navigation-Di9rJ-b5.js → extensions-navigation-D9i0DL62.js} +1 -1
- package/build/assets/files-tab-DDtEJcGE.js +1 -0
- package/build/assets/{form-control-classes-9rkU4usZ.js → form-control-classes-ChpNBe9n.js} +1 -1
- package/build/assets/{git-provider-icon-aQRcUVI-.js → git-provider-icon-BjkecAuV.js} +1 -1
- package/build/assets/home-BCKWpKpf.js +1 -0
- package/build/assets/{install-server-modal-BRab9inF.js → install-server-modal-BIugLhVB.js} +1 -1
- package/build/assets/{launch-1TJRKkkX.js → launch-BgIlZLSX.js} +1 -1
- package/build/assets/lesson-plan-DgpP80mJ.js +4 -0
- package/build/assets/{llm-not-configured-banner-BrU5uHto.js → llm-not-configured-banner-BlX8NifC.js} +4 -4
- package/build/assets/llm-settings-DJmbryaE.js +1 -0
- package/build/assets/{llm-settings-BpdU51Jo.js → llm-settings-kU5v0H1Z.js} +1 -1
- package/build/assets/{loading-spinner-DHAIPZkP.js → loading-spinner-BLdswi6q.js} +1 -1
- package/build/assets/{manage-backends-modal-BREySP-J.js → manage-backends-modal-C8FJQIZR.js} +1 -1
- package/build/assets/manifest-56d40d7c.js +1 -0
- package/build/assets/{markdown-renderer-D8mayGjI.js → markdown-renderer-DMT7Zkpd.js} +1 -1
- package/build/assets/{mcp-XXf8k6mb.js → mcp-CHkklDMv.js} +1 -1
- package/build/assets/{messages-D2oZb47Z.js → messages-B3RugH7P.js} +11 -11
- package/build/assets/{modal-body-Dcu5McCa.js → modal-body-DouOE5KH.js} +1 -1
- package/build/assets/{modal-classes-DPqxSyuP.js → modal-classes-Cf-4tbHz.js} +1 -1
- package/build/assets/{modal-close-button-CTCX4nCH.js → modal-close-button-B6CfxxJj.js} +1 -1
- package/build/assets/{model-selector-VDHBytb6.js → model-selector-BOj1wBlq.js} +1 -1
- package/build/assets/onboarding-DYhDxmI9.js +1 -0
- package/build/assets/{onboarding-modal-C084vkv7.js → onboarding-modal-CP_WxDC9.js} +1 -1
- package/build/assets/{option-service.api-Cl5VLGyw.js → option-service.api-C0tYT4-r.js} +1 -1
- package/build/assets/{path-utils-BeOmjIcE.js → path-utils-DWcgCGen.js} +1 -1
- package/build/assets/{plan-components-j9X4AxYM.js → plan-components-CcCBmCzW.js} +1 -1
- package/build/assets/{planner-tab-AZMjJx31.js → planner-tab-CCqdXxkL.js} +1 -1
- package/build/assets/providers-BxCuC9bZ.js +1 -0
- package/build/assets/{recommended-automations-launcher-Bk8tQ-Cn.js → recommended-automations-launcher-CVEF_1pc.js} +1 -1
- package/build/assets/root-V8fkplMy.css +1 -0
- package/build/assets/root-layout-CttG_lQi.js +2 -0
- package/build/assets/{root-tuEPDx-i.js → root-uJ2t9rCQ.js} +2 -2
- package/build/assets/{runtime-waiting-state-DkzLgvMn.js → runtime-waiting-state-BsXLElvN.js} +1 -1
- package/build/assets/{schema-field-nvq_Juo2.js → schema-field-xUr6rDd6.js} +1 -1
- package/build/assets/{sdk-section-page-CgT70FaZ.js → sdk-section-page-CbLrVUa3.js} +1 -1
- package/build/assets/{sdk-settings-schema-BjBkMHzZ.js → sdk-settings-schema-Cv7M9eSe.js} +1 -1
- package/build/assets/{secrets-settings-BCxk9p9s.js → secrets-settings-DxTx9HgU.js} +1 -1
- package/build/assets/{segmented-toggle-Cen5AMUc.js → segmented-toggle-DyQqPhoD.js} +1 -1
- package/build/assets/{settings-CedTdtb5.js → settings-DnlfS09K.js} +1 -1
- package/build/assets/{settings-dropdown-input-xzoZwgUe.js → settings-dropdown-input-BjunGXJb.js} +1 -1
- package/build/assets/{settings-index-Cct3PJSP.js → settings-index-BjeuYFFa.js} +1 -1
- package/build/assets/{settings-input-DYs7t3oK.js → settings-input-bD6npsDm.js} +1 -1
- package/build/assets/{settings-list-classes-DvQr5jVS.js → settings-list-classes-Dp_OgzN0.js} +1 -1
- package/build/assets/{settings-modal-DwLybV_O.js → settings-modal-DfTcL-mV.js} +1 -1
- package/build/assets/settings-service.api-K4ncGlBv.js +1 -0
- package/build/assets/{settings-switch-C2N2xqEb.js → settings-switch-5cuxl8Dc.js} +1 -1
- package/build/assets/{shared-conversation-DnDwfLgg.js → shared-conversation-DWtBkJv7.js} +1 -1
- package/build/assets/{sidebar-layout-BtpUSN3j.js → sidebar-layout-DuzJMMw-.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-B8k3qu84.js → sidebar-mobile-menu-toggle-CMmAYkh8.js} +1 -1
- package/build/assets/{sidebar-nav-link-CIB3NBRW.js → sidebar-nav-link-5AlTT5-j.js} +1 -1
- package/build/assets/{skill-card-pill-row-D2bUe2kB.js → skill-card-pill-row-eTIkE4nz.js} +1 -1
- package/build/assets/{skills-plugins-B68ay6Pu.js → skills-plugins-BJ040luO.js} +1 -1
- package/build/assets/{skills-settings-A6sUy0T7.js → skills-settings-BYn4-AQQ.js} +1 -1
- package/build/assets/{styled-tooltip-DsKsFjuq.js → styled-tooltip-CgX2oRaK.js} +1 -1
- package/build/assets/{task-list-tab-BAThr9Ex.js → task-list-tab-0k9PhuqO.js} +1 -1
- package/build/assets/{terminal-BmT0_gIH.js → terminal-BsGcSpRS.js} +1 -1
- package/build/assets/{toggle-switch-DBlOOzBr.js → toggle-switch-2j5wwR85.js} +1 -1
- package/build/assets/{typography-YGPBGzOG.js → typography-D8mHDeNG.js} +1 -1
- package/build/assets/{use-acp-credential-form-Bs6s0DTU.js → use-acp-credential-form-EtnbtYt0.js} +1 -1
- package/build/assets/{use-activate-agent-profile-CKtTToSx.js → use-activate-agent-profile-WaAZYz4E.js} +1 -1
- package/build/assets/{use-active-agent-profile-CWLPpOtK.js → use-active-agent-profile-CYY3vGar.js} +1 -1
- package/build/assets/{use-active-conversation-DI5S5M1w.js → use-active-conversation-D-r929nx.js} +1 -1
- package/build/assets/{use-agent-profiles-DPcaYLpm.js → use-agent-profiles-DEAMFp-W.js} +1 -1
- package/build/assets/{use-agent-state-Buh3bQDh.js → use-agent-state-DijdVAQ0.js} +1 -1
- package/build/assets/{use-backends-health-CxkvJy2N.js → use-backends-health-DkC7tKkC.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-DeX2Mfje.js → use-can-manage-org-profiles-BEo0peGn.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-D_PQGfmT.js → use-cloud-current-user-id-Dm99wXp2.js} +1 -1
- package/build/assets/{use-config-ur0RbjCP.js → use-config-CHzNIHpv.js} +1 -1
- package/build/assets/{use-create-conversation-D9OWYcte.js → use-create-conversation-CTsvZ96U.js} +1 -1
- package/build/assets/{use-create-secret-CVFSlhlR.js → use-create-secret-D5O5qdWC.js} +1 -1
- package/build/assets/{use-event-store-YSOxy9FC.js → use-event-store-DjgU4wfO.js} +1 -1
- package/build/assets/{use-handle-plan-click-Dug8egQl.js → use-handle-plan-click-Mn_SNTCh.js} +1 -1
- package/build/assets/{use-llm-profiles-DjackuP1.js → use-llm-profiles-BMhPDlwQ.js} +1 -1
- package/build/assets/use-runtime-is-ready-CC-KrLKe.js +1 -0
- package/build/assets/{use-save-agent-profile-aKKLqDJM.js → use-save-agent-profile-CLMmbx_X.js} +1 -1
- package/build/assets/{use-save-settings-CChDyjOB.js → use-save-settings-D1HoCDbn.js} +1 -1
- package/build/assets/{use-settings-dX4fKUPF.js → use-settings-BReAMxCG.js} +1 -1
- package/build/assets/{use-settings-nav-items-D6pHnvxg.js → use-settings-nav-items-xe1YgLnE.js} +1 -1
- package/build/assets/{use-task-list-CmWGElgb.js → use-task-list-AVBLbbcR.js} +1 -1
- package/build/assets/{use-tracking-GtXCHmTv.js → use-tracking-2ZwQwpg_.js} +1 -1
- package/build/assets/{use-user-conversation-6uOXFP95.js → use-user-conversation-OAfenBRG.js} +1 -1
- package/build/assets/{useTranslation-Cgy4JA_g.js → useTranslation-CDRCKC9-.js} +1 -1
- package/build/assets/{utils-CE0lDWtb.js → utils-D3U3rlqr.js} +1 -1
- package/build/assets/{verification-settings-D_zsNB_c.js → verification-settings-DnXS6VWv.js} +1 -1
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +24 -0
- package/build/locales/ca/openhands.json +24 -0
- package/build/locales/de/openhands.json +24 -0
- package/build/locales/en/openhands.json +24 -0
- package/build/locales/es/openhands.json +24 -0
- package/build/locales/fr/openhands.json +24 -0
- package/build/locales/it/openhands.json +24 -0
- package/build/locales/ja/openhands.json +24 -0
- package/build/locales/ko-KR/openhands.json +24 -0
- package/build/locales/no/openhands.json +24 -0
- package/build/locales/pt/openhands.json +24 -0
- package/build/locales/tr/openhands.json +24 -0
- package/build/locales/uk/openhands.json +24 -0
- package/build/locales/zh-CN/openhands.json +24 -0
- package/build/locales/zh-TW/openhands.json +24 -0
- package/config/defaults.json +4 -4
- package/dist/api/automation-service/automation-service.api.d.ts +2 -1
- package/dist/api/event-service/event-service.api.cjs +1 -1
- package/dist/api/event-service/event-service.api.cjs.map +1 -1
- package/dist/api/event-service/event-service.api.js +1 -1
- package/dist/api/event-service/event-service.api.js.map +1 -1
- package/dist/api/event-service/event-service.types.d.ts +6 -0
- package/dist/api/git-service/agent-server-git-service.api.cjs +1 -1
- package/dist/api/git-service/agent-server-git-service.api.cjs.map +1 -1
- package/dist/api/git-service/agent-server-git-service.api.js +2 -2
- package/dist/api/git-service/agent-server-git-service.api.js.map +1 -1
- package/dist/api/git-service/git-service.api.cjs +1 -1
- package/dist/api/git-service/git-service.api.cjs.map +1 -1
- package/dist/api/git-service/git-service.api.js +2 -2
- package/dist/api/git-service/git-service.api.js.map +1 -1
- package/dist/components/conversation-events/chat/event-thought-helpers.cjs +1 -1
- package/dist/components/conversation-events/chat/event-thought-helpers.js +1 -1
- package/dist/components/features/automations/automation-card.d.ts +2 -1
- package/dist/components/features/automations/automation-group.d.ts +2 -1
- package/dist/components/features/automations/automation-list-row.d.ts +2 -1
- package/dist/components/features/automations/build-automation-menu-items.d.ts +2 -1
- package/dist/components/features/automations/detail/detail-header.d.ts +3 -1
- package/dist/components/features/automations/import-automation-modal.d.ts +10 -0
- package/dist/components/features/conversation/conversation-name-context-menu.cjs +1 -1
- package/dist/components/features/conversation/conversation-name-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-name-context-menu.d.ts +2 -1
- package/dist/components/features/conversation/conversation-name-context-menu.js +74 -63
- package/dist/components/features/conversation/conversation-name-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-name.cjs +1 -1
- package/dist/components/features/conversation/conversation-name.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-name.js +73 -61
- package/dist/components/features/conversation/conversation-name.js.map +1 -1
- package/dist/components/features/conversation/transcript-export-modal.cjs +2 -0
- package/dist/components/features/conversation/transcript-export-modal.cjs.map +1 -0
- package/dist/components/features/conversation/transcript-export-modal.d.ts +10 -0
- package/dist/components/features/conversation/transcript-export-modal.js +140 -0
- package/dist/components/features/conversation/transcript-export-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
- package/dist/components/features/home/shared/dropdown-item.cjs +1 -1
- package/dist/components/features/home/shared/dropdown-item.cjs.map +1 -1
- package/dist/components/features/home/shared/dropdown-item.d.ts +7 -1
- package/dist/components/features/home/shared/dropdown-item.js +2 -1
- package/dist/components/features/home/shared/dropdown-item.js.map +1 -1
- package/dist/components/features/home/shared/generic-dropdown-menu.cjs +1 -1
- package/dist/components/features/home/shared/generic-dropdown-menu.cjs.map +1 -1
- package/dist/components/features/home/shared/generic-dropdown-menu.d.ts +8 -1
- package/dist/components/features/home/shared/generic-dropdown-menu.js +18 -10
- package/dist/components/features/home/shared/generic-dropdown-menu.js.map +1 -1
- package/dist/components/features/home/workspace-dropdown/workspace-dropdown.d.ts +11 -2
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +4 -4
- package/dist/config/defaults.js.map +1 -1
- package/dist/hooks/query/use-automations.d.ts +2 -1
- package/dist/hooks/query/use-resolved-workspaces.cjs +1 -1
- package/dist/hooks/query/use-resolved-workspaces.cjs.map +1 -1
- package/dist/hooks/query/use-resolved-workspaces.d.ts +9 -1
- package/dist/hooks/query/use-resolved-workspaces.js +1 -0
- package/dist/hooks/query/use-resolved-workspaces.js.map +1 -1
- package/dist/hooks/query/use-workspace-file-content.cjs +1 -1
- package/dist/hooks/query/use-workspace-file-content.cjs.map +1 -1
- package/dist/hooks/query/use-workspace-file-content.js +61 -55
- package/dist/hooks/query/use-workspace-file-content.js.map +1 -1
- package/dist/hooks/query/use-workspace-files.cjs +1 -1
- package/dist/hooks/query/use-workspace-files.cjs.map +1 -1
- package/dist/hooks/query/use-workspace-files.d.ts +11 -4
- package/dist/hooks/query/use-workspace-files.js +39 -18
- package/dist/hooks/query/use-workspace-files.js.map +1 -1
- package/dist/hooks/use-auto-refresh-files-on-edit.cjs +1 -1
- package/dist/hooks/use-auto-refresh-files-on-edit.cjs.map +1 -1
- package/dist/hooks/use-auto-refresh-files-on-edit.d.ts +9 -0
- package/dist/hooks/use-auto-refresh-files-on-edit.js +15 -11
- package/dist/hooks/use-auto-refresh-files-on-edit.js.map +1 -1
- package/dist/hooks/use-tracking.cjs +1 -1
- package/dist/hooks/use-tracking.cjs.map +1 -1
- package/dist/hooks/use-tracking.d.ts +7 -0
- package/dist/hooks/use-tracking.js +9 -0
- package/dist/hooks/use-tracking.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +24 -0
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +1 -1
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +408 -0
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +24 -0
- package/dist/locales/ca/openhands.json +24 -0
- package/dist/locales/de/openhands.json +24 -0
- package/dist/locales/en/openhands.json +24 -0
- package/dist/locales/es/openhands.json +24 -0
- package/dist/locales/fr/openhands.json +24 -0
- package/dist/locales/it/openhands.json +24 -0
- package/dist/locales/ja/openhands.json +24 -0
- package/dist/locales/ko-KR/openhands.json +24 -0
- package/dist/locales/no/openhands.json +24 -0
- package/dist/locales/pt/openhands.json +24 -0
- package/dist/locales/tr/openhands.json +24 -0
- package/dist/locales/uk/openhands.json +24 -0
- package/dist/locales/zh-CN/openhands.json +24 -0
- package/dist/locales/zh-TW/openhands.json +24 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/routes/files-tab.cjs +1 -1
- package/dist/routes/files-tab.js +10 -10
- package/dist/types/automation.d.ts +8 -0
- package/dist/utils/custom-toast-handlers.cjs.map +1 -1
- package/dist/utils/custom-toast-handlers.d.ts +1 -0
- package/dist/utils/custom-toast-handlers.js.map +1 -1
- package/dist/utils/mcp-server-name.cjs +1 -1
- package/dist/utils/mcp-server-name.cjs.map +1 -1
- package/dist/utils/mcp-server-name.js +2 -2
- package/dist/utils/mcp-server-name.js.map +1 -1
- package/dist/utils/transcript-export/index.cjs +72 -0
- package/dist/utils/transcript-export/index.cjs.map +1 -0
- package/dist/utils/transcript-export/index.d.ts +10 -0
- package/dist/utils/transcript-export/index.js +302 -0
- package/dist/utils/transcript-export/index.js.map +1 -0
- package/dist/utils/transcript-export/load-complete-events.cjs +2 -0
- package/dist/utils/transcript-export/load-complete-events.cjs.map +1 -0
- package/dist/utils/transcript-export/load-complete-events.d.ts +22 -0
- package/dist/utils/transcript-export/load-complete-events.js +39 -0
- package/dist/utils/transcript-export/load-complete-events.js.map +1 -0
- package/package.json +1 -1
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/dev-safe.mjs +2 -2
- package/build/assets/active-backend-context-u2tdYRgH.js +0 -1
- package/build/assets/agent-settings-FGL3Yvkp.js +0 -1
- package/build/assets/automation-detail-DwYGzLkp.js +0 -2
- package/build/assets/automations-list-CuAfJmMW.js +0 -1
- package/build/assets/conversation-DnVC6vRV.js +0 -1
- package/build/assets/conversation-panel-ZEz-z3az.js +0 -1
- package/build/assets/conversation-xkBS3AHC.js +0 -19
- package/build/assets/declaration-B9kpCaYl.js +0 -1
- package/build/assets/edit-automation-modal-B6U96gVV.js +0 -1
- package/build/assets/files-tab-61Vaihc6.js +0 -1
- package/build/assets/home-5gOtUe-n.js +0 -1
- package/build/assets/lesson-plan-BtrZUCuj.js +0 -4
- package/build/assets/llm-settings-DsInf6yD.js +0 -1
- package/build/assets/manifest-a5bb7568.js +0 -1
- package/build/assets/onboarding-D32kiGME.js +0 -1
- package/build/assets/providers-vX9jk9Vy.js +0 -1
- package/build/assets/root-CxWZUXTQ.css +0 -1
- package/build/assets/root-layout-CoWw4kpz.js +0 -2
- package/build/assets/settings-service.api-DldkFI1x.js +0 -1
- package/build/assets/use-runtime-is-ready-Diiq65Q-.js +0 -1
|
@@ -4,19 +4,19 @@ import { ExternalLink as n } from "../../../node_modules/lucide-react/dist/esm/i
|
|
|
4
4
|
import { Share2 as r } from "../../../node_modules/lucide-react/dist/esm/icons/share-2.js";
|
|
5
5
|
import { cn as i } from "../../../utils/utils.js";
|
|
6
6
|
import { useActiveBackend as a } from "../../../contexts/active-backend-context.js";
|
|
7
|
-
import { useActiveConversation as
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import { ContextMenu as
|
|
11
|
-
import { ContextMenuListItem as
|
|
12
|
-
import { useClickOutsideElement as
|
|
7
|
+
import { useActiveConversation as ee } from "../../../hooks/query/use-active-conversation.js";
|
|
8
|
+
import o from "../../../icons/copy.js";
|
|
9
|
+
import s from "../../../icons/u-close.js";
|
|
10
|
+
import { ContextMenu as c } from "../../../ui/context-menu.js";
|
|
11
|
+
import { ContextMenuListItem as l } from "../context-menu/context-menu-list-item.js";
|
|
12
|
+
import { useClickOutsideElement as u } from "../../../hooks/use-click-outside-element.js";
|
|
13
13
|
import { Divider as d } from "../../../ui/divider.js";
|
|
14
14
|
import f from "../../../icons/skills.js";
|
|
15
15
|
import p from "../../../icons/fishing-hook.js";
|
|
16
|
-
import
|
|
17
|
-
import { ArchivedDisabledTooltip as
|
|
18
|
-
import { useIsArchivedConversation as
|
|
19
|
-
import { useBreakpoint as
|
|
16
|
+
import te from "../../../icons/u-tools.js";
|
|
17
|
+
import { ArchivedDisabledTooltip as m } from "../context-menu/archived-disabled-tooltip.js";
|
|
18
|
+
import { useIsArchivedConversation as ne } from "../../../hooks/use-is-archived-conversation.js";
|
|
19
|
+
import { useBreakpoint as h } from "../../../hooks/use-breakpoint.js";
|
|
20
20
|
import g from "../../../icons/u-edit.js";
|
|
21
21
|
import _ from "../../../icons/u-download.js";
|
|
22
22
|
import v from "../../../icons/u-credit-card.js";
|
|
@@ -43,31 +43,31 @@ function T({ isPublic: e, onToggle: t, ariaLabel: n }) {
|
|
|
43
43
|
})]
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
-
function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A, onShowAgentTools: j, onShowSkills: M, onShowHooks: N, onTogglePublic: P, onCopyShareLink: F,
|
|
47
|
-
let
|
|
46
|
+
function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A, onShowAgentTools: j, onShowSkills: M, onShowHooks: N, onTogglePublic: P, onCopyShareLink: F, onExportTranscript: I, onDownloadConversation: L, shareUrl: R, position: z = "bottom", anchorRef: B }) {
|
|
47
|
+
let V = h(), { t: H } = e("openhands"), { backend: U } = a(), { data: W } = ee(), G = ne(), K = u(E), q = B?.current ?? null, [J, Y] = x.useState();
|
|
48
48
|
x.useLayoutEffect(() => {
|
|
49
|
-
if (!
|
|
49
|
+
if (!q) return;
|
|
50
50
|
let e = () => {
|
|
51
|
-
let e =
|
|
51
|
+
let e = q.getBoundingClientRect();
|
|
52
52
|
if (!e) return;
|
|
53
53
|
let t = {
|
|
54
54
|
position: "fixed",
|
|
55
55
|
zIndex: 9999
|
|
56
56
|
};
|
|
57
|
-
|
|
57
|
+
z === "top" ? t.bottom = window.innerHeight - e.top + 8 : t.top = e.bottom + 8, t.left = e.left, Y(t);
|
|
58
58
|
};
|
|
59
59
|
return e(), window.addEventListener("resize", e), window.addEventListener("scroll", e, !0), () => {
|
|
60
60
|
window.removeEventListener("resize", e), window.removeEventListener("scroll", e, !0);
|
|
61
61
|
};
|
|
62
|
-
}, [
|
|
63
|
-
let
|
|
64
|
-
ref:
|
|
62
|
+
}, [q, z]);
|
|
63
|
+
let X = !!(j || M || N), re = !!A, ie = !!(k || O), ae = U.kind === "cloud" ? t.COMMON$CLOSE_CONVERSATION_STOP_RUNTIME : t.COMMON$STOP_CONVERSATION, oe = U.kind === "cloud" && !!P, Z = W?.public || !1, Q = !!q, $ = /* @__PURE__ */ C(c, {
|
|
64
|
+
ref: K,
|
|
65
65
|
testId: "conversation-name-context-menu",
|
|
66
|
-
position:
|
|
66
|
+
position: z,
|
|
67
67
|
alignment: "left",
|
|
68
|
-
className: i(
|
|
68
|
+
className: i(V ? "right-0 translate-x-[34%] left-auto" : "", Q ? "!static !top-auto !bottom-auto !left-auto !right-auto !mt-0" : ""),
|
|
69
69
|
children: [
|
|
70
|
-
D && /* @__PURE__ */ S(
|
|
70
|
+
D && /* @__PURE__ */ S(l, {
|
|
71
71
|
testId: "rename-button",
|
|
72
72
|
onClick: D,
|
|
73
73
|
children: /* @__PURE__ */ S(b, {
|
|
@@ -75,19 +75,19 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
75
75
|
width: 16,
|
|
76
76
|
height: 16
|
|
77
77
|
}),
|
|
78
|
-
text:
|
|
78
|
+
text: H(t.BUTTON$RENAME)
|
|
79
79
|
})
|
|
80
80
|
}),
|
|
81
|
-
|
|
81
|
+
X && /* @__PURE__ */ S(d, {
|
|
82
82
|
testId: "separator-tools",
|
|
83
83
|
inset: "menu"
|
|
84
84
|
}),
|
|
85
|
-
M && /* @__PURE__ */ S(
|
|
86
|
-
isDisabled:
|
|
87
|
-
children: /* @__PURE__ */ S(
|
|
85
|
+
M && /* @__PURE__ */ S(m, {
|
|
86
|
+
isDisabled: G,
|
|
87
|
+
children: /* @__PURE__ */ S(l, {
|
|
88
88
|
testId: "show-skills-button",
|
|
89
89
|
onClick: M,
|
|
90
|
-
isDisabled:
|
|
90
|
+
isDisabled: G,
|
|
91
91
|
children: /* @__PURE__ */ S(b, {
|
|
92
92
|
icon: /* @__PURE__ */ S(f, {
|
|
93
93
|
width: 16,
|
|
@@ -95,57 +95,68 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
95
95
|
className: "stroke-[1.75]",
|
|
96
96
|
"aria-hidden": !0
|
|
97
97
|
}),
|
|
98
|
-
text:
|
|
98
|
+
text: H(t.CONVERSATION$SHOW_SKILLS)
|
|
99
99
|
})
|
|
100
100
|
})
|
|
101
101
|
}),
|
|
102
|
-
N && /* @__PURE__ */ S(
|
|
103
|
-
isDisabled:
|
|
104
|
-
children: /* @__PURE__ */ S(
|
|
102
|
+
N && /* @__PURE__ */ S(m, {
|
|
103
|
+
isDisabled: G,
|
|
104
|
+
children: /* @__PURE__ */ S(l, {
|
|
105
105
|
testId: "show-hooks-button",
|
|
106
106
|
onClick: N,
|
|
107
|
-
isDisabled:
|
|
107
|
+
isDisabled: G,
|
|
108
108
|
children: /* @__PURE__ */ S(b, {
|
|
109
109
|
icon: /* @__PURE__ */ S(p, {
|
|
110
110
|
width: 16,
|
|
111
111
|
height: 16,
|
|
112
112
|
"aria-hidden": !0
|
|
113
113
|
}),
|
|
114
|
-
text:
|
|
114
|
+
text: H(t.CONVERSATION$SHOW_HOOKS)
|
|
115
115
|
})
|
|
116
116
|
})
|
|
117
117
|
}),
|
|
118
|
-
j && /* @__PURE__ */ S(
|
|
119
|
-
isDisabled:
|
|
120
|
-
children: /* @__PURE__ */ S(
|
|
118
|
+
j && /* @__PURE__ */ S(m, {
|
|
119
|
+
isDisabled: G,
|
|
120
|
+
children: /* @__PURE__ */ S(l, {
|
|
121
121
|
testId: "show-agent-tools-button",
|
|
122
122
|
onClick: j,
|
|
123
|
-
isDisabled:
|
|
123
|
+
isDisabled: G,
|
|
124
124
|
children: /* @__PURE__ */ S(b, {
|
|
125
|
-
icon: /* @__PURE__ */ S(
|
|
125
|
+
icon: /* @__PURE__ */ S(te, {
|
|
126
126
|
width: 16,
|
|
127
127
|
height: 16
|
|
128
128
|
}),
|
|
129
|
-
text:
|
|
129
|
+
text: H(t.BUTTON$SHOW_AGENT_TOOLS_AND_METADATA)
|
|
130
130
|
})
|
|
131
131
|
})
|
|
132
132
|
}),
|
|
133
|
-
I && /* @__PURE__ */ S(
|
|
134
|
-
testId: "
|
|
133
|
+
I && /* @__PURE__ */ S(l, {
|
|
134
|
+
testId: "export-transcript-button",
|
|
135
135
|
onClick: I,
|
|
136
136
|
children: /* @__PURE__ */ S(b, {
|
|
137
137
|
icon: /* @__PURE__ */ S(_, {
|
|
138
138
|
width: 16,
|
|
139
139
|
height: 16
|
|
140
140
|
}),
|
|
141
|
-
text:
|
|
141
|
+
text: H(t.BUTTON$EXPORT_TRANSCRIPT)
|
|
142
|
+
})
|
|
143
|
+
}),
|
|
144
|
+
L && /* @__PURE__ */ S(l, {
|
|
145
|
+
testId: "download-trajectory-button",
|
|
146
|
+
onClick: L,
|
|
147
|
+
children: /* @__PURE__ */ S(b, {
|
|
148
|
+
icon: /* @__PURE__ */ S(_, {
|
|
149
|
+
width: 16,
|
|
150
|
+
height: 16
|
|
151
|
+
}),
|
|
152
|
+
text: H(t.BUTTON$DOWNLOAD_CONVERSATION_DATA)
|
|
142
153
|
})
|
|
143
154
|
}),
|
|
144
|
-
(
|
|
155
|
+
(re || ie) && /* @__PURE__ */ S(d, {
|
|
145
156
|
testId: "separator-info-control",
|
|
146
157
|
inset: "menu"
|
|
147
158
|
}),
|
|
148
|
-
A && /* @__PURE__ */ S(
|
|
159
|
+
A && /* @__PURE__ */ S(l, {
|
|
149
160
|
testId: "display-cost-button",
|
|
150
161
|
onClick: A,
|
|
151
162
|
children: /* @__PURE__ */ S(b, {
|
|
@@ -153,10 +164,10 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
153
164
|
width: 16,
|
|
154
165
|
height: 16
|
|
155
166
|
}),
|
|
156
|
-
text:
|
|
167
|
+
text: H(t.BUTTON$DISPLAY_COST)
|
|
157
168
|
})
|
|
158
169
|
}),
|
|
159
|
-
|
|
170
|
+
oe && P && /* @__PURE__ */ C("li", {
|
|
160
171
|
className: "flex w-full items-center gap-2 rounded px-2 py-2 hover:bg-[var(--oh-interactive-hover)]",
|
|
161
172
|
children: [
|
|
162
173
|
/* @__PURE__ */ S("span", {
|
|
@@ -166,30 +177,30 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
166
177
|
}),
|
|
167
178
|
/* @__PURE__ */ S("span", {
|
|
168
179
|
className: "min-w-0 flex-1 truncate text-sm",
|
|
169
|
-
children:
|
|
180
|
+
children: H(t.CONVERSATION$SHARE_PUBLICLY)
|
|
170
181
|
}),
|
|
171
182
|
/* @__PURE__ */ C("div", {
|
|
172
183
|
className: "flex shrink-0 items-center",
|
|
173
|
-
children: [Z &&
|
|
184
|
+
children: [Z && R && F && /* @__PURE__ */ C("div", {
|
|
174
185
|
className: "mr-2 flex items-center gap-0.5",
|
|
175
186
|
children: [/* @__PURE__ */ S("button", {
|
|
176
187
|
type: "button",
|
|
177
188
|
"data-testid": "copy-share-link-button",
|
|
178
189
|
onClick: F,
|
|
179
190
|
className: "rounded p-0.5 text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current",
|
|
180
|
-
title:
|
|
181
|
-
children: /* @__PURE__ */ S(
|
|
191
|
+
title: H(t.BUTTON$COPY_TO_CLIPBOARD),
|
|
192
|
+
children: /* @__PURE__ */ S(o, {
|
|
182
193
|
width: 14,
|
|
183
194
|
height: 14
|
|
184
195
|
})
|
|
185
196
|
}), /* @__PURE__ */ S("a", {
|
|
186
197
|
"data-testid": "open-share-link-button",
|
|
187
|
-
href:
|
|
198
|
+
href: R,
|
|
188
199
|
target: "_blank",
|
|
189
200
|
rel: "noopener noreferrer",
|
|
190
201
|
onClick: (e) => e.stopPropagation(),
|
|
191
202
|
className: "rounded p-0.5 text-[var(--oh-muted)] no-underline visited:text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current",
|
|
192
|
-
title:
|
|
203
|
+
title: H(t.BUTTON$OPEN_IN_NEW_TAB),
|
|
193
204
|
children: /* @__PURE__ */ S(n, {
|
|
194
205
|
size: 14,
|
|
195
206
|
"aria-hidden": !0
|
|
@@ -198,27 +209,27 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
198
209
|
}), /* @__PURE__ */ S(T, {
|
|
199
210
|
isPublic: Z,
|
|
200
211
|
onToggle: P,
|
|
201
|
-
ariaLabel:
|
|
212
|
+
ariaLabel: H(t.CONVERSATION$SHARE_PUBLICLY)
|
|
202
213
|
})]
|
|
203
214
|
})
|
|
204
215
|
]
|
|
205
216
|
}),
|
|
206
|
-
k && /* @__PURE__ */ S(
|
|
207
|
-
isDisabled:
|
|
208
|
-
children: /* @__PURE__ */ S(
|
|
217
|
+
k && /* @__PURE__ */ S(m, {
|
|
218
|
+
isDisabled: G,
|
|
219
|
+
children: /* @__PURE__ */ S(l, {
|
|
209
220
|
testId: "stop-button",
|
|
210
221
|
onClick: k,
|
|
211
|
-
isDisabled:
|
|
222
|
+
isDisabled: G,
|
|
212
223
|
children: /* @__PURE__ */ S(b, {
|
|
213
|
-
icon: /* @__PURE__ */ S(
|
|
224
|
+
icon: /* @__PURE__ */ S(s, {
|
|
214
225
|
width: 16,
|
|
215
226
|
height: 16
|
|
216
227
|
}),
|
|
217
|
-
text:
|
|
228
|
+
text: H(ae)
|
|
218
229
|
})
|
|
219
230
|
})
|
|
220
231
|
}),
|
|
221
|
-
O && /* @__PURE__ */ S(
|
|
232
|
+
O && /* @__PURE__ */ S(l, {
|
|
222
233
|
testId: "delete-button",
|
|
223
234
|
onClick: O,
|
|
224
235
|
children: /* @__PURE__ */ S(b, {
|
|
@@ -226,13 +237,13 @@ function E({ onClose: E, onRename: D, onDelete: O, onStop: k, onDisplayCost: A,
|
|
|
226
237
|
width: 16,
|
|
227
238
|
height: 16
|
|
228
239
|
}),
|
|
229
|
-
text:
|
|
240
|
+
text: H(t.COMMON$DELETE_CONVERSATION)
|
|
230
241
|
})
|
|
231
242
|
})
|
|
232
243
|
]
|
|
233
244
|
});
|
|
234
|
-
return Q ? typeof document > "u" || !
|
|
235
|
-
style:
|
|
245
|
+
return Q ? typeof document > "u" || !J ? null : w.createPortal(/* @__PURE__ */ S("div", {
|
|
246
|
+
style: J,
|
|
236
247
|
children: $
|
|
237
248
|
}), document.body) : $;
|
|
238
249
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-name-context-menu.js","names":[],"sources":["../../../../src/components/features/conversation/conversation-name-context-menu.tsx"],"sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { ExternalLink, Share2 } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { useBreakpoint } from \"#/hooks/use-breakpoint\";\nimport { cn } from \"#/utils/utils\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"../context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\nimport EditIcon from \"#/icons/u-edit.svg?react\";\nimport SkillsIcon from \"#/icons/skills.svg?react\";\nimport FishingHookIcon from \"#/icons/fishing-hook.svg?react\";\nimport ToolsIcon from \"#/icons/u-tools.svg?react\";\nimport DownloadIcon from \"#/icons/u-download.svg?react\";\nimport CreditCardIcon from \"#/icons/u-credit-card.svg?react\";\nimport CloseIcon from \"#/icons/u-close.svg?react\";\nimport DeleteIcon from \"#/icons/u-delete.svg?react\";\nimport CopyIcon from \"#/icons/copy.svg?react\";\nimport { ConversationNameContextMenuIconText } from \"./conversation-name-context-menu-icon-text\";\nimport { ArchivedDisabledTooltip } from \"../context-menu/archived-disabled-tooltip\";\nimport { useIsArchivedConversation } from \"#/hooks/use-is-archived-conversation\";\n\ninterface ConversationNameContextMenuProps {\n onClose: () => void;\n onRename?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDelete?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onStop?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDisplayCost?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowAgentTools?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowSkills?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowHooks?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onTogglePublic?: (nextIsPublic: boolean) => void;\n onCopyShareLink?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDownloadConversation?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n shareUrl?: string;\n position?: \"top\" | \"bottom\";\n /**\n * Element the menu should anchor against. When provided, the menu renders\n * into a portal at the document body using fixed positioning so it cannot be\n * clipped by ancestors with `overflow: hidden` (e.g. the chat panel that\n * sits next to the right-side tabs panel).\n */\n anchorRef?: React.RefObject<HTMLElement | null>;\n}\n\nfunction PublicShareToggle({\n isPublic,\n onToggle,\n ariaLabel,\n}: {\n isPublic: boolean;\n onToggle: (nextIsPublic: boolean) => void;\n ariaLabel: string;\n}) {\n return (\n <label className=\"relative inline-flex shrink-0 cursor-pointer items-center\">\n <input\n hidden\n type=\"checkbox\"\n data-testid=\"share-publicly-button\"\n checked={isPublic}\n aria-label={ariaLabel}\n onChange={(event) => onToggle(event.target.checked)}\n />\n <span\n aria-hidden\n className={cn(\n \"inline-flex h-3.5 w-7 items-center rounded-full px-0.5 py-px transition-colors duration-200 ease-in-out\",\n isPublic ? \"bg-white\" : \"bg-base-secondary\",\n )}\n >\n <span\n className={cn(\n \"block h-2 w-2 shrink-0 rounded-full transition-transform duration-200 ease-in-out\",\n isPublic\n ? \"translate-x-[calc(1rem-1px)] bg-base-secondary\"\n : \"translate-x-px bg-tertiary-light\",\n )}\n />\n </span>\n </label>\n );\n}\n\nexport function ConversationNameContextMenu({\n onClose,\n onRename,\n onDelete,\n onStop,\n onDisplayCost,\n onShowAgentTools,\n onShowSkills,\n onShowHooks,\n onTogglePublic,\n onCopyShareLink,\n onDownloadConversation,\n shareUrl,\n position = \"bottom\",\n anchorRef,\n}: ConversationNameContextMenuProps) {\n const isMobile = useBreakpoint();\n\n const { t } = useTranslation(\"openhands\");\n const { backend } = useActiveBackend();\n const { data: conversation } = useActiveConversation();\n const isArchivedConversation = useIsArchivedConversation();\n const ref = useClickOutsideElement<HTMLUListElement>(onClose);\n\n const anchorElement = anchorRef?.current ?? null;\n const [portalStyle, setPortalStyle] = React.useState<React.CSSProperties>();\n React.useLayoutEffect(() => {\n if (!anchorElement) return undefined;\n\n const updatePosition = () => {\n const rect = anchorElement.getBoundingClientRect();\n if (!rect) return;\n const gap = 8;\n const style: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 9999,\n };\n if (position === \"top\") {\n style.bottom = window.innerHeight - rect.top + gap;\n } else {\n style.top = rect.bottom + gap;\n }\n style.left = rect.left;\n setPortalStyle(style);\n };\n\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n };\n }, [anchorElement, position]);\n const hasTools = Boolean(onShowAgentTools || onShowSkills || onShowHooks);\n const hasInfo = Boolean(onDisplayCost);\n const hasControl = Boolean(onStop || onDelete);\n const stopLabelKey =\n backend.kind === \"cloud\"\n ? I18nKey.COMMON$CLOSE_CONVERSATION_STOP_RUNTIME\n : I18nKey.COMMON$STOP_CONVERSATION;\n const shouldShowPublicSharing =\n backend.kind === \"cloud\" && Boolean(onTogglePublic);\n const isPublic = conversation?.public || false;\n\n const isPortaled = Boolean(anchorElement);\n const portalClassName = isPortaled\n ? \"!static !top-auto !bottom-auto !left-auto !right-auto !mt-0\"\n : \"\";\n\n const menu = (\n <ContextMenu\n ref={ref}\n testId=\"conversation-name-context-menu\"\n position={position}\n alignment=\"left\"\n className={cn(\n isMobile ? \"right-0 translate-x-[34%] left-auto\" : \"\",\n portalClassName,\n )}\n >\n {onRename && (\n <ContextMenuListItem testId=\"rename-button\" onClick={onRename}>\n <ConversationNameContextMenuIconText\n icon={<EditIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$RENAME)}\n />\n </ContextMenuListItem>\n )}\n\n {hasTools && <Divider testId=\"separator-tools\" inset=\"menu\" />}\n\n {onShowSkills && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-skills-button\"\n onClick={onShowSkills}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={\n <SkillsIcon\n width={16}\n height={16}\n className=\"stroke-[1.75]\"\n aria-hidden\n />\n }\n text={t(I18nKey.CONVERSATION$SHOW_SKILLS)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onShowHooks && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-hooks-button\"\n onClick={onShowHooks}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<FishingHookIcon width={16} height={16} aria-hidden />}\n text={t(I18nKey.CONVERSATION$SHOW_HOOKS)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onShowAgentTools && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-agent-tools-button\"\n onClick={onShowAgentTools}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<ToolsIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$SHOW_AGENT_TOOLS_AND_METADATA)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onDownloadConversation && (\n <ContextMenuListItem\n testId=\"download-trajectory-button\"\n onClick={onDownloadConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<DownloadIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$EXPORT_CONVERSATION)}\n />\n </ContextMenuListItem>\n )}\n\n {(hasInfo || hasControl) && (\n <Divider testId=\"separator-info-control\" inset=\"menu\" />\n )}\n\n {onDisplayCost && (\n <ContextMenuListItem\n testId=\"display-cost-button\"\n onClick={onDisplayCost}\n >\n <ConversationNameContextMenuIconText\n icon={<CreditCardIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$DISPLAY_COST)}\n />\n </ContextMenuListItem>\n )}\n\n {shouldShowPublicSharing && onTogglePublic && (\n <li className=\"flex w-full items-center gap-2 rounded px-2 py-2 hover:bg-[var(--oh-interactive-hover)]\">\n <span\n className=\"flex shrink-0 items-center text-[var(--oh-muted)]\"\n aria-hidden\n >\n <Share2 size={16} />\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm\">\n {t(I18nKey.CONVERSATION$SHARE_PUBLICLY)}\n </span>\n <div className=\"flex shrink-0 items-center\">\n {isPublic && shareUrl && onCopyShareLink && (\n <div className=\"mr-2 flex items-center gap-0.5\">\n <button\n type=\"button\"\n data-testid=\"copy-share-link-button\"\n onClick={onCopyShareLink}\n className=\"rounded p-0.5 text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current\"\n title={t(I18nKey.BUTTON$COPY_TO_CLIPBOARD)}\n >\n <CopyIcon width={14} height={14} />\n </button>\n <a\n data-testid=\"open-share-link-button\"\n href={shareUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(event) => event.stopPropagation()}\n className=\"rounded p-0.5 text-[var(--oh-muted)] no-underline visited:text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current\"\n title={t(I18nKey.BUTTON$OPEN_IN_NEW_TAB)}\n >\n <ExternalLink size={14} aria-hidden />\n </a>\n </div>\n )}\n <PublicShareToggle\n isPublic={isPublic}\n onToggle={onTogglePublic}\n ariaLabel={t(I18nKey.CONVERSATION$SHARE_PUBLICLY)}\n />\n </div>\n </li>\n )}\n\n {onStop && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"stop-button\"\n onClick={onStop}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<CloseIcon width={16} height={16} />}\n text={t(stopLabelKey)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onDelete && (\n <ContextMenuListItem testId=\"delete-button\" onClick={onDelete}>\n <ConversationNameContextMenuIconText\n icon={<DeleteIcon width={16} height={16} />}\n text={t(I18nKey.COMMON$DELETE_CONVERSATION)}\n />\n </ContextMenuListItem>\n )}\n </ContextMenu>\n );\n\n if (isPortaled) {\n if (typeof document === \"undefined\" || !portalStyle) {\n return null;\n }\n return ReactDOM.createPortal(\n <div style={portalStyle}>{menu}</div>,\n document.body,\n );\n }\n\n return menu;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversation-name-context-menu.js","names":[],"sources":["../../../../src/components/features/conversation/conversation-name-context-menu.tsx"],"sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { ExternalLink, Share2 } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { useBreakpoint } from \"#/hooks/use-breakpoint\";\nimport { cn } from \"#/utils/utils\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"../context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\nimport EditIcon from \"#/icons/u-edit.svg?react\";\nimport SkillsIcon from \"#/icons/skills.svg?react\";\nimport FishingHookIcon from \"#/icons/fishing-hook.svg?react\";\nimport ToolsIcon from \"#/icons/u-tools.svg?react\";\nimport DownloadIcon from \"#/icons/u-download.svg?react\";\nimport CreditCardIcon from \"#/icons/u-credit-card.svg?react\";\nimport CloseIcon from \"#/icons/u-close.svg?react\";\nimport DeleteIcon from \"#/icons/u-delete.svg?react\";\nimport CopyIcon from \"#/icons/copy.svg?react\";\nimport { ConversationNameContextMenuIconText } from \"./conversation-name-context-menu-icon-text\";\nimport { ArchivedDisabledTooltip } from \"../context-menu/archived-disabled-tooltip\";\nimport { useIsArchivedConversation } from \"#/hooks/use-is-archived-conversation\";\n\ninterface ConversationNameContextMenuProps {\n onClose: () => void;\n onRename?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDelete?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onStop?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDisplayCost?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowAgentTools?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowSkills?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onShowHooks?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onTogglePublic?: (nextIsPublic: boolean) => void;\n onCopyShareLink?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onExportTranscript?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n onDownloadConversation?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n shareUrl?: string;\n position?: \"top\" | \"bottom\";\n /**\n * Element the menu should anchor against. When provided, the menu renders\n * into a portal at the document body using fixed positioning so it cannot be\n * clipped by ancestors with `overflow: hidden` (e.g. the chat panel that\n * sits next to the right-side tabs panel).\n */\n anchorRef?: React.RefObject<HTMLElement | null>;\n}\n\nfunction PublicShareToggle({\n isPublic,\n onToggle,\n ariaLabel,\n}: {\n isPublic: boolean;\n onToggle: (nextIsPublic: boolean) => void;\n ariaLabel: string;\n}) {\n return (\n <label className=\"relative inline-flex shrink-0 cursor-pointer items-center\">\n <input\n hidden\n type=\"checkbox\"\n data-testid=\"share-publicly-button\"\n checked={isPublic}\n aria-label={ariaLabel}\n onChange={(event) => onToggle(event.target.checked)}\n />\n <span\n aria-hidden\n className={cn(\n \"inline-flex h-3.5 w-7 items-center rounded-full px-0.5 py-px transition-colors duration-200 ease-in-out\",\n isPublic ? \"bg-white\" : \"bg-base-secondary\",\n )}\n >\n <span\n className={cn(\n \"block h-2 w-2 shrink-0 rounded-full transition-transform duration-200 ease-in-out\",\n isPublic\n ? \"translate-x-[calc(1rem-1px)] bg-base-secondary\"\n : \"translate-x-px bg-tertiary-light\",\n )}\n />\n </span>\n </label>\n );\n}\n\nexport function ConversationNameContextMenu({\n onClose,\n onRename,\n onDelete,\n onStop,\n onDisplayCost,\n onShowAgentTools,\n onShowSkills,\n onShowHooks,\n onTogglePublic,\n onCopyShareLink,\n onExportTranscript,\n onDownloadConversation,\n shareUrl,\n position = \"bottom\",\n anchorRef,\n}: ConversationNameContextMenuProps) {\n const isMobile = useBreakpoint();\n\n const { t } = useTranslation(\"openhands\");\n const { backend } = useActiveBackend();\n const { data: conversation } = useActiveConversation();\n const isArchivedConversation = useIsArchivedConversation();\n const ref = useClickOutsideElement<HTMLUListElement>(onClose);\n\n const anchorElement = anchorRef?.current ?? null;\n const [portalStyle, setPortalStyle] = React.useState<React.CSSProperties>();\n React.useLayoutEffect(() => {\n if (!anchorElement) return undefined;\n\n const updatePosition = () => {\n const rect = anchorElement.getBoundingClientRect();\n if (!rect) return;\n const gap = 8;\n const style: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 9999,\n };\n if (position === \"top\") {\n style.bottom = window.innerHeight - rect.top + gap;\n } else {\n style.top = rect.bottom + gap;\n }\n style.left = rect.left;\n setPortalStyle(style);\n };\n\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n };\n }, [anchorElement, position]);\n const hasTools = Boolean(onShowAgentTools || onShowSkills || onShowHooks);\n const hasInfo = Boolean(onDisplayCost);\n const hasControl = Boolean(onStop || onDelete);\n const stopLabelKey =\n backend.kind === \"cloud\"\n ? I18nKey.COMMON$CLOSE_CONVERSATION_STOP_RUNTIME\n : I18nKey.COMMON$STOP_CONVERSATION;\n const shouldShowPublicSharing =\n backend.kind === \"cloud\" && Boolean(onTogglePublic);\n const isPublic = conversation?.public || false;\n\n const isPortaled = Boolean(anchorElement);\n const portalClassName = isPortaled\n ? \"!static !top-auto !bottom-auto !left-auto !right-auto !mt-0\"\n : \"\";\n\n const menu = (\n <ContextMenu\n ref={ref}\n testId=\"conversation-name-context-menu\"\n position={position}\n alignment=\"left\"\n className={cn(\n isMobile ? \"right-0 translate-x-[34%] left-auto\" : \"\",\n portalClassName,\n )}\n >\n {onRename && (\n <ContextMenuListItem testId=\"rename-button\" onClick={onRename}>\n <ConversationNameContextMenuIconText\n icon={<EditIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$RENAME)}\n />\n </ContextMenuListItem>\n )}\n\n {hasTools && <Divider testId=\"separator-tools\" inset=\"menu\" />}\n\n {onShowSkills && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-skills-button\"\n onClick={onShowSkills}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={\n <SkillsIcon\n width={16}\n height={16}\n className=\"stroke-[1.75]\"\n aria-hidden\n />\n }\n text={t(I18nKey.CONVERSATION$SHOW_SKILLS)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onShowHooks && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-hooks-button\"\n onClick={onShowHooks}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<FishingHookIcon width={16} height={16} aria-hidden />}\n text={t(I18nKey.CONVERSATION$SHOW_HOOKS)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onShowAgentTools && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"show-agent-tools-button\"\n onClick={onShowAgentTools}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<ToolsIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$SHOW_AGENT_TOOLS_AND_METADATA)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onExportTranscript && (\n <ContextMenuListItem\n testId=\"export-transcript-button\"\n onClick={onExportTranscript}\n >\n <ConversationNameContextMenuIconText\n icon={<DownloadIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$EXPORT_TRANSCRIPT)}\n />\n </ContextMenuListItem>\n )}\n\n {onDownloadConversation && (\n <ContextMenuListItem\n testId=\"download-trajectory-button\"\n onClick={onDownloadConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<DownloadIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$DOWNLOAD_CONVERSATION_DATA)}\n />\n </ContextMenuListItem>\n )}\n\n {(hasInfo || hasControl) && (\n <Divider testId=\"separator-info-control\" inset=\"menu\" />\n )}\n\n {onDisplayCost && (\n <ContextMenuListItem\n testId=\"display-cost-button\"\n onClick={onDisplayCost}\n >\n <ConversationNameContextMenuIconText\n icon={<CreditCardIcon width={16} height={16} />}\n text={t(I18nKey.BUTTON$DISPLAY_COST)}\n />\n </ContextMenuListItem>\n )}\n\n {shouldShowPublicSharing && onTogglePublic && (\n <li className=\"flex w-full items-center gap-2 rounded px-2 py-2 hover:bg-[var(--oh-interactive-hover)]\">\n <span\n className=\"flex shrink-0 items-center text-[var(--oh-muted)]\"\n aria-hidden\n >\n <Share2 size={16} />\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm\">\n {t(I18nKey.CONVERSATION$SHARE_PUBLICLY)}\n </span>\n <div className=\"flex shrink-0 items-center\">\n {isPublic && shareUrl && onCopyShareLink && (\n <div className=\"mr-2 flex items-center gap-0.5\">\n <button\n type=\"button\"\n data-testid=\"copy-share-link-button\"\n onClick={onCopyShareLink}\n className=\"rounded p-0.5 text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current\"\n title={t(I18nKey.BUTTON$COPY_TO_CLIPBOARD)}\n >\n <CopyIcon width={14} height={14} />\n </button>\n <a\n data-testid=\"open-share-link-button\"\n href={shareUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(event) => event.stopPropagation()}\n className=\"rounded p-0.5 text-[var(--oh-muted)] no-underline visited:text-[var(--oh-muted)] hover:bg-[var(--oh-interactive-selected)] hover:text-[var(--oh-foreground)] cursor-pointer [&_svg]:text-current\"\n title={t(I18nKey.BUTTON$OPEN_IN_NEW_TAB)}\n >\n <ExternalLink size={14} aria-hidden />\n </a>\n </div>\n )}\n <PublicShareToggle\n isPublic={isPublic}\n onToggle={onTogglePublic}\n ariaLabel={t(I18nKey.CONVERSATION$SHARE_PUBLICLY)}\n />\n </div>\n </li>\n )}\n\n {onStop && (\n <ArchivedDisabledTooltip isDisabled={isArchivedConversation}>\n <ContextMenuListItem\n testId=\"stop-button\"\n onClick={onStop}\n isDisabled={isArchivedConversation}\n >\n <ConversationNameContextMenuIconText\n icon={<CloseIcon width={16} height={16} />}\n text={t(stopLabelKey)}\n />\n </ContextMenuListItem>\n </ArchivedDisabledTooltip>\n )}\n\n {onDelete && (\n <ContextMenuListItem testId=\"delete-button\" onClick={onDelete}>\n <ConversationNameContextMenuIconText\n icon={<DeleteIcon width={16} height={16} />}\n text={t(I18nKey.COMMON$DELETE_CONVERSATION)}\n />\n </ContextMenuListItem>\n )}\n </ContextMenu>\n );\n\n if (isPortaled) {\n if (typeof document === \"undefined\" || !portalStyle) {\n return null;\n }\n return ReactDOM.createPortal(\n <div style={portalStyle}>{menu}</div>,\n document.body,\n );\n }\n\n return menu;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../hooks/use-conversation-id.cjs`),i=require(`../../../utils/custom-toast-handlers.cjs`),a=require(`../../../hooks/query/use-active-conversation.cjs`),o=require(`../../../hooks/use-conversation-name-context-menu.cjs`),s=require(`../conversation-panel/system-message-modal.cjs`),c=require(`../conversation-panel/skills-modal.cjs`),l=require(`../conversation-panel/hooks-modal.cjs`),u=require(`../../../hooks/mutation/use-update-conversation.cjs`),d=require(`../conversation-panel/ellipsis-button.cjs`),f=require(`./conversation-name-context-menu.cjs`),p=require(`../conversation-panel/confirm-delete-modal.cjs`),m=require(`../conversation-panel/confirm-stop-modal.cjs`),h=require(`./metrics-modal/metrics-modal.cjs`);let
|
|
1
|
+
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../hooks/use-conversation-id.cjs`),i=require(`../../../utils/custom-toast-handlers.cjs`),a=require(`../../../hooks/query/use-active-conversation.cjs`),o=require(`../../../hooks/use-conversation-name-context-menu.cjs`),s=require(`../conversation-panel/system-message-modal.cjs`),c=require(`../conversation-panel/skills-modal.cjs`),l=require(`../conversation-panel/hooks-modal.cjs`),u=require(`../../../hooks/mutation/use-update-conversation.cjs`),d=require(`../conversation-panel/ellipsis-button.cjs`),f=require(`./conversation-name-context-menu.cjs`),p=require(`../conversation-panel/confirm-delete-modal.cjs`),m=require(`../conversation-panel/confirm-stop-modal.cjs`),h=require(`./metrics-modal/metrics-modal.cjs`),g=require(`./transcript-export-modal.cjs`);let _=require(`react`);_=e.__toESM(_,1);let v=require(`react/jsx-runtime`);function y(){let{t:e}=t.useTranslation(`openhands`),{conversationId:y}=r.useConversationId(),{data:b}=a.useActiveConversation(),{mutate:x}=u.useUpdateConversation(),[S,C]=_.default.useState(`view`),[w,T]=_.default.useState(!1),[E,D]=_.default.useState(!1),O=_.default.useRef(null),k=_.default.useRef(null),{handleDelete:A,handleStop:j,handleDownloadConversation:M,handleDisplayCost:N,handleShowAgentTools:ee,handleShowSkills:P,handleShowHooks:F,handleTogglePublic:I,handleCopyShareLink:L,shareUrl:R,handleConfirmDelete:z,handleConfirmStop:B,metricsModalVisible:V,setMetricsModalVisible:H,systemModalVisible:U,setSystemModalVisible:W,skillsModalVisible:G,setSkillsModalVisible:K,hooksModalVisible:q,setHooksModalVisible:J,confirmDeleteModalVisible:Y,setConfirmDeleteModalVisible:X,confirmStopModalVisible:Z,setConfirmStopModalVisible:Q,systemMessage:$,shouldShowStop:te,shouldShowDownloadConversation:ne,shouldShowDisplayCost:re,shouldShowAgentTools:ie,shouldShowSkills:ae,shouldShowHooks:oe}=o.useConversationNameContextMenu({conversationId:y,executionStatus:b?.execution_status,showOptions:!0,onContextMenuToggle:T});return _.default.useEffect(()=>{S===`edit`&&O.current?.focus()},[S]),b?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2 h-[22px] text-base font-normal text-left pl-0 lg:pl-1 min-w-0`,"data-testid":`conversation-name`,children:[S===`edit`?(0,v.jsx)(`input`,{ref:O,"data-testid":`conversation-name-input`,onClick:e=>{S===`edit`&&(e.preventDefault(),e.stopPropagation())},onBlur:()=>{if(O.current?.value&&y){let t=O.current.value.trim();t!==b?.title&&x({conversationId:y,newTitle:t},{onSuccess:()=>{i.displaySuccessToast(e(n.I18nKey.CONVERSATION$TITLE_UPDATED))}})}else O.current&&(O.current.value=b?.title??``);C(`view`)},onKeyUp:e=>{e.nativeEvent.isComposing||e.key===`Enter`&&e.currentTarget.blur()},type:`text`,defaultValue:b.title||``,className:`text-white leading-5 bg-transparent border-none outline-none text-base font-normal w-fit max-w-fit field-sizing-content`}):(0,v.jsx)(`div`,{className:`text-white leading-5 truncate`,"data-testid":`conversation-name-title`,onDoubleClick:()=>{C(`edit`)},title:b.title||``,children:b.title}),S!==`edit`&&(0,v.jsxs)(`div`,{ref:k,className:`relative flex items-center shrink-0`,children:[(0,v.jsx)(d.EllipsisButton,{onClick:e=>{e.preventDefault(),e.stopPropagation(),T(!w)}}),w&&(0,v.jsx)(f.ConversationNameContextMenu,{onClose:()=>T(!1),onRename:e=>{e.preventDefault(),e.stopPropagation(),C(`edit`),T(!1)},onDelete:A,onStop:te?j:void 0,onDisplayCost:re?N:void 0,onShowAgentTools:ie?ee:void 0,onShowSkills:ae?P:void 0,onShowHooks:oe?F:void 0,onTogglePublic:I,onCopyShareLink:L,shareUrl:R,onExportTranscript:e=>{e.preventDefault(),e.stopPropagation(),D(!0),T(!1)},onDownloadConversation:ne?M:void 0,position:`bottom`,anchorRef:k})]})]}),(0,v.jsx)(h.MetricsModal,{isOpen:V,onOpenChange:H}),E&&y&&(0,v.jsx)(g.TranscriptExportModal,{conversationId:y,conversationUrl:b.conversation_url,sessionApiKey:b.session_api_key,conversationTitle:b.title,model:b.llm_model,onClose:()=>D(!1)}),(0,v.jsx)(s.SystemMessageModal,{isOpen:U,onClose:()=>W(!1),systemMessage:$||null}),G&&(0,v.jsx)(c.SkillsModal,{onClose:()=>K(!1)}),q&&(0,v.jsx)(l.HooksModal,{onClose:()=>J(!1)}),Y&&(0,v.jsx)(p.ConfirmDeleteModal,{onConfirm:z,onCancel:()=>X(!1),conversationTitle:b?.title||``}),Z&&(0,v.jsx)(m.ConfirmStopModal,{onConfirm:B,onCancel:()=>Q(!1)})]}):null}exports.ConversationName=y;
|
|
2
2
|
//# sourceMappingURL=conversation-name.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-name.cjs","names":[],"sources":["../../../../src/components/features/conversation/conversation-name.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationNameContextMenu } from \"#/hooks/use-conversation-name-context-menu\";\nimport { displaySuccessToast } from \"#/utils/custom-toast-handlers\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { EllipsisButton } from \"../conversation-panel/ellipsis-button\";\nimport { ConversationNameContextMenu } from \"./conversation-name-context-menu\";\nimport { SystemMessageModal } from \"../conversation-panel/system-message-modal\";\nimport { SkillsModal } from \"../conversation-panel/skills-modal\";\nimport { HooksModal } from \"../conversation-panel/hooks-modal\";\nimport { ConfirmDeleteModal } from \"../conversation-panel/confirm-delete-modal\";\nimport { ConfirmStopModal } from \"../conversation-panel/confirm-stop-modal\";\nimport { MetricsModal } from \"./metrics-modal/metrics-modal\";\n\nexport function ConversationName() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useConversationId();\n const { data: conversation } = useActiveConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n const [titleMode, setTitleMode] = React.useState<\"view\" | \"edit\">(\"view\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const ellipsisAnchorRef = React.useRef<HTMLDivElement>(null);\n\n // Use the custom hook for context menu handlers\n const {\n handleDelete,\n handleStop,\n handleDownloadConversation,\n handleDisplayCost,\n handleShowAgentTools,\n handleShowSkills,\n handleShowHooks,\n handleTogglePublic,\n handleCopyShareLink,\n shareUrl,\n handleConfirmDelete,\n handleConfirmStop,\n metricsModalVisible,\n setMetricsModalVisible,\n systemModalVisible,\n setSystemModalVisible,\n skillsModalVisible,\n setSkillsModalVisible,\n hooksModalVisible,\n setHooksModalVisible,\n confirmDeleteModalVisible,\n setConfirmDeleteModalVisible,\n confirmStopModalVisible,\n setConfirmStopModalVisible,\n systemMessage,\n shouldShowStop,\n shouldShowDownloadConversation,\n shouldShowDisplayCost,\n shouldShowAgentTools,\n shouldShowSkills,\n shouldShowHooks,\n } = useConversationNameContextMenu({\n conversationId,\n executionStatus: conversation?.execution_status,\n showOptions: true,\n onContextMenuToggle: setContextMenuOpen,\n });\n\n const handleDoubleClick = () => {\n setTitleMode(\"edit\");\n };\n\n const handleBlur = () => {\n if (inputRef.current?.value && conversationId) {\n const trimmed = inputRef.current.value.trim();\n if (trimmed !== conversation?.title) {\n updateConversation(\n { conversationId, newTitle: trimmed },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n }\n } else if (inputRef.current) {\n // reset the value if it's empty\n inputRef.current.value = conversation?.title ?? \"\";\n }\n\n setTitleMode(\"view\");\n };\n\n const handleKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Ignore Enter key during IME composition (e.g., Chinese, Japanese, Korean input)\n if (event.nativeEvent.isComposing) {\n return;\n }\n if (event.key === \"Enter\") {\n event.currentTarget.blur();\n }\n };\n\n const handleInputClick = (event: React.MouseEvent<HTMLInputElement>) => {\n if (titleMode === \"edit\") {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n const handleEllipsisClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen(!contextMenuOpen);\n };\n\n const handleRename = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setTitleMode(\"edit\");\n setContextMenuOpen(false);\n };\n\n React.useEffect(() => {\n if (titleMode === \"edit\") {\n inputRef.current?.focus();\n }\n }, [titleMode]);\n\n if (!conversation) {\n return null;\n }\n\n return (\n <>\n <div\n className=\"flex items-center gap-2 h-[22px] text-base font-normal text-left pl-0 lg:pl-1 min-w-0\"\n data-testid=\"conversation-name\"\n >\n {titleMode === \"edit\" ? (\n <input\n ref={inputRef}\n data-testid=\"conversation-name-input\"\n onClick={handleInputClick}\n onBlur={handleBlur}\n onKeyUp={handleKeyUp}\n type=\"text\"\n defaultValue={conversation.title || \"\"}\n className=\"text-white leading-5 bg-transparent border-none outline-none text-base font-normal w-fit max-w-fit field-sizing-content\"\n />\n ) : (\n <div\n className=\"text-white leading-5 truncate\"\n data-testid=\"conversation-name-title\"\n onDoubleClick={handleDoubleClick}\n title={conversation.title || \"\"}\n >\n {conversation.title}\n </div>\n )}\n\n {titleMode !== \"edit\" && (\n <div\n ref={ellipsisAnchorRef}\n className=\"relative flex items-center shrink-0\"\n >\n <EllipsisButton onClick={handleEllipsisClick} />\n {contextMenuOpen && (\n <ConversationNameContextMenu\n onClose={() => setContextMenuOpen(false)}\n onRename={handleRename}\n onDelete={handleDelete}\n onStop={shouldShowStop ? handleStop : undefined}\n onDisplayCost={\n shouldShowDisplayCost ? handleDisplayCost : undefined\n }\n onShowAgentTools={\n shouldShowAgentTools ? handleShowAgentTools : undefined\n }\n onShowSkills={shouldShowSkills ? handleShowSkills : undefined}\n onShowHooks={shouldShowHooks ? handleShowHooks : undefined}\n onTogglePublic={handleTogglePublic}\n onCopyShareLink={handleCopyShareLink}\n shareUrl={shareUrl}\n onDownloadConversation={\n shouldShowDownloadConversation\n ? handleDownloadConversation\n : undefined\n }\n position=\"bottom\"\n anchorRef={ellipsisAnchorRef}\n />\n )}\n </div>\n )}\n </div>\n\n {/* Metrics Modal */}\n <MetricsModal\n isOpen={metricsModalVisible}\n onOpenChange={setMetricsModalVisible}\n />\n\n {/* System Message Modal */}\n <SystemMessageModal\n isOpen={systemModalVisible}\n onClose={() => setSystemModalVisible(false)}\n systemMessage={systemMessage || null}\n />\n\n {/* Skills Modal */}\n {skillsModalVisible && (\n <SkillsModal onClose={() => setSkillsModalVisible(false)} />\n )}\n\n {/* Hooks Modal */}\n {hooksModalVisible && (\n <HooksModal onClose={() => setHooksModalVisible(false)} />\n )}\n\n {/* Confirm Delete Modal */}\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={handleConfirmDelete}\n onCancel={() => setConfirmDeleteModalVisible(false)}\n conversationTitle={conversation?.title || \"\"}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={handleConfirmStop}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversation-name.cjs","names":[],"sources":["../../../../src/components/features/conversation/conversation-name.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationNameContextMenu } from \"#/hooks/use-conversation-name-context-menu\";\nimport { displaySuccessToast } from \"#/utils/custom-toast-handlers\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { EllipsisButton } from \"../conversation-panel/ellipsis-button\";\nimport { ConversationNameContextMenu } from \"./conversation-name-context-menu\";\nimport { SystemMessageModal } from \"../conversation-panel/system-message-modal\";\nimport { SkillsModal } from \"../conversation-panel/skills-modal\";\nimport { HooksModal } from \"../conversation-panel/hooks-modal\";\nimport { ConfirmDeleteModal } from \"../conversation-panel/confirm-delete-modal\";\nimport { ConfirmStopModal } from \"../conversation-panel/confirm-stop-modal\";\nimport { MetricsModal } from \"./metrics-modal/metrics-modal\";\nimport { TranscriptExportModal } from \"./transcript-export-modal\";\n\nexport function ConversationName() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useConversationId();\n const { data: conversation } = useActiveConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n const [titleMode, setTitleMode] = React.useState<\"view\" | \"edit\">(\"view\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n const [transcriptExportModalVisible, setTranscriptExportModalVisible] =\n React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const ellipsisAnchorRef = React.useRef<HTMLDivElement>(null);\n\n // Use the custom hook for context menu handlers\n const {\n handleDelete,\n handleStop,\n handleDownloadConversation,\n handleDisplayCost,\n handleShowAgentTools,\n handleShowSkills,\n handleShowHooks,\n handleTogglePublic,\n handleCopyShareLink,\n shareUrl,\n handleConfirmDelete,\n handleConfirmStop,\n metricsModalVisible,\n setMetricsModalVisible,\n systemModalVisible,\n setSystemModalVisible,\n skillsModalVisible,\n setSkillsModalVisible,\n hooksModalVisible,\n setHooksModalVisible,\n confirmDeleteModalVisible,\n setConfirmDeleteModalVisible,\n confirmStopModalVisible,\n setConfirmStopModalVisible,\n systemMessage,\n shouldShowStop,\n shouldShowDownloadConversation,\n shouldShowDisplayCost,\n shouldShowAgentTools,\n shouldShowSkills,\n shouldShowHooks,\n } = useConversationNameContextMenu({\n conversationId,\n executionStatus: conversation?.execution_status,\n showOptions: true,\n onContextMenuToggle: setContextMenuOpen,\n });\n\n const handleDoubleClick = () => {\n setTitleMode(\"edit\");\n };\n\n const handleBlur = () => {\n if (inputRef.current?.value && conversationId) {\n const trimmed = inputRef.current.value.trim();\n if (trimmed !== conversation?.title) {\n updateConversation(\n { conversationId, newTitle: trimmed },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n }\n } else if (inputRef.current) {\n // reset the value if it's empty\n inputRef.current.value = conversation?.title ?? \"\";\n }\n\n setTitleMode(\"view\");\n };\n\n const handleKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Ignore Enter key during IME composition (e.g., Chinese, Japanese, Korean input)\n if (event.nativeEvent.isComposing) {\n return;\n }\n if (event.key === \"Enter\") {\n event.currentTarget.blur();\n }\n };\n\n const handleInputClick = (event: React.MouseEvent<HTMLInputElement>) => {\n if (titleMode === \"edit\") {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n const handleEllipsisClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen(!contextMenuOpen);\n };\n\n const handleRename = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setTitleMode(\"edit\");\n setContextMenuOpen(false);\n };\n\n const handleExportTranscript = (\n event: React.MouseEvent<HTMLButtonElement>,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n setTranscriptExportModalVisible(true);\n setContextMenuOpen(false);\n };\n\n React.useEffect(() => {\n if (titleMode === \"edit\") {\n inputRef.current?.focus();\n }\n }, [titleMode]);\n\n if (!conversation) {\n return null;\n }\n\n return (\n <>\n <div\n className=\"flex items-center gap-2 h-[22px] text-base font-normal text-left pl-0 lg:pl-1 min-w-0\"\n data-testid=\"conversation-name\"\n >\n {titleMode === \"edit\" ? (\n <input\n ref={inputRef}\n data-testid=\"conversation-name-input\"\n onClick={handleInputClick}\n onBlur={handleBlur}\n onKeyUp={handleKeyUp}\n type=\"text\"\n defaultValue={conversation.title || \"\"}\n className=\"text-white leading-5 bg-transparent border-none outline-none text-base font-normal w-fit max-w-fit field-sizing-content\"\n />\n ) : (\n <div\n className=\"text-white leading-5 truncate\"\n data-testid=\"conversation-name-title\"\n onDoubleClick={handleDoubleClick}\n title={conversation.title || \"\"}\n >\n {conversation.title}\n </div>\n )}\n\n {titleMode !== \"edit\" && (\n <div\n ref={ellipsisAnchorRef}\n className=\"relative flex items-center shrink-0\"\n >\n <EllipsisButton onClick={handleEllipsisClick} />\n {contextMenuOpen && (\n <ConversationNameContextMenu\n onClose={() => setContextMenuOpen(false)}\n onRename={handleRename}\n onDelete={handleDelete}\n onStop={shouldShowStop ? handleStop : undefined}\n onDisplayCost={\n shouldShowDisplayCost ? handleDisplayCost : undefined\n }\n onShowAgentTools={\n shouldShowAgentTools ? handleShowAgentTools : undefined\n }\n onShowSkills={shouldShowSkills ? handleShowSkills : undefined}\n onShowHooks={shouldShowHooks ? handleShowHooks : undefined}\n onTogglePublic={handleTogglePublic}\n onCopyShareLink={handleCopyShareLink}\n shareUrl={shareUrl}\n onExportTranscript={handleExportTranscript}\n onDownloadConversation={\n shouldShowDownloadConversation\n ? handleDownloadConversation\n : undefined\n }\n position=\"bottom\"\n anchorRef={ellipsisAnchorRef}\n />\n )}\n </div>\n )}\n </div>\n\n {/* Metrics Modal */}\n <MetricsModal\n isOpen={metricsModalVisible}\n onOpenChange={setMetricsModalVisible}\n />\n\n {transcriptExportModalVisible && conversationId && (\n <TranscriptExportModal\n conversationId={conversationId}\n conversationUrl={conversation.conversation_url}\n sessionApiKey={conversation.session_api_key}\n conversationTitle={conversation.title}\n model={conversation.llm_model}\n onClose={() => setTranscriptExportModalVisible(false)}\n />\n )}\n\n {/* System Message Modal */}\n <SystemMessageModal\n isOpen={systemModalVisible}\n onClose={() => setSystemModalVisible(false)}\n systemMessage={systemMessage || null}\n />\n\n {/* Skills Modal */}\n {skillsModalVisible && (\n <SkillsModal onClose={() => setSkillsModalVisible(false)} />\n )}\n\n {/* Hooks Modal */}\n {hooksModalVisible && (\n <HooksModal onClose={() => setHooksModalVisible(false)} />\n )}\n\n {/* Confirm Delete Modal */}\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={handleConfirmDelete}\n onCancel={() => setConfirmDeleteModalVisible(false)}\n conversationTitle={conversation?.title || \"\"}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={handleConfirmStop}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n </>\n );\n}\n"],"mappings":"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"}
|