@yancyyu/openhermit 1.6.38 → 1.6.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/dist-renderer/assets/ProjectEditorOverlay-CemDOX-3.js +58 -0
  2. package/dist-renderer/assets/{TeamGraphOverlay-ZEDfZyHb.js → TeamGraphOverlay-hPY770Db.js} +1 -1
  3. package/dist-renderer/assets/{_basePickBy-CIhniz70.js → _basePickBy-BHHrJT1i.js} +1 -1
  4. package/dist-renderer/assets/{_baseUniq-cKAW4Q8I.js → _baseUniq-CWErBtke.js} +1 -1
  5. package/dist-renderer/assets/{arc-YmNsoDXW.js → arc-C_o2_Uv8.js} +1 -1
  6. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DHEls2sX.js → architectureDiagram-VXUJARFQ-DUW0LI3t.js} +1 -1
  7. package/dist-renderer/assets/{blockDiagram-VD42YOAC-Bpwf1Sbg.js → blockDiagram-VD42YOAC-CWbCE9hQ.js} +1 -1
  8. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B0IaQ4w5.js → c4Diagram-YG6GDRKO-BjLadrfV.js} +1 -1
  9. package/dist-renderer/assets/channel-DyP9YlCF.js +1 -0
  10. package/dist-renderer/assets/{chunk-4BX2VUAB-DLk-hcFc.js → chunk-4BX2VUAB-CPnvjZl9.js} +1 -1
  11. package/dist-renderer/assets/{chunk-55IACEB6-1XRmX_Zm.js → chunk-55IACEB6-OlL47yXQ.js} +1 -1
  12. package/dist-renderer/assets/{chunk-B4BG7PRW-1waH1DAD.js → chunk-B4BG7PRW-DTasjbm8.js} +1 -1
  13. package/dist-renderer/assets/{chunk-DI55MBZ5-BqpZBtrN.js → chunk-DI55MBZ5-C5_Xaqkk.js} +1 -1
  14. package/dist-renderer/assets/{chunk-FMBD7UC4-Bly7vVym.js → chunk-FMBD7UC4-NdoM4DMR.js} +1 -1
  15. package/dist-renderer/assets/{chunk-QN33PNHL-Ci2QWBAs.js → chunk-QN33PNHL-C8Fybejy.js} +1 -1
  16. package/dist-renderer/assets/{chunk-QZHKN3VN-YCqFW7d-.js → chunk-QZHKN3VN-E98TYFXJ.js} +1 -1
  17. package/dist-renderer/assets/{chunk-TZMSLE5B-B0xGXInl.js → chunk-TZMSLE5B-h4lFgkIq.js} +1 -1
  18. package/dist-renderer/assets/classDiagram-2ON5EDUG-BqffFTae.js +1 -0
  19. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BqffFTae.js +1 -0
  20. package/dist-renderer/assets/clone-MPcKWs2O.js +1 -0
  21. package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DxcFNQKT.js → cose-bilkent-S5V4N54A-DtQ7fkrs.js} +1 -1
  22. package/dist-renderer/assets/{dagre-6UL2VRFP-DPo_RfZY.js → dagre-6UL2VRFP-CN-nL_z4.js} +1 -1
  23. package/dist-renderer/assets/{diagram-PSM6KHXK-U3hQsFe4.js → diagram-PSM6KHXK-DVJtqmm-.js} +1 -1
  24. package/dist-renderer/assets/{diagram-QEK2KX5R-OrwrAy0V.js → diagram-QEK2KX5R-DlxHxyXh.js} +1 -1
  25. package/dist-renderer/assets/{diagram-S2PKOQOG-CXATPWVw.js → diagram-S2PKOQOG-7dpzO6x6.js} +1 -1
  26. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-B0e8AfMF.js → erDiagram-Q2GNP2WA-GP1TqsHi.js} +1 -1
  27. package/dist-renderer/assets/{flowDiagram-NV44I4VS-CXfzA4jJ.js → flowDiagram-NV44I4VS-C7ZLETuH.js} +1 -1
  28. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CMr08qVl.js → ganttDiagram-JELNMOA3-CvPB68dH.js} +1 -1
  29. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vYFHpPmy.js → gitGraphDiagram-V2S2FVAM-B5yOm3w7.js} +1 -1
  30. package/dist-renderer/assets/{graph-DOe5j8dH.js → graph-smeyY1YZ.js} +1 -1
  31. package/dist-renderer/assets/{index-BySQS7AB.js → index-BJx8XvG1.js} +1 -1
  32. package/dist-renderer/assets/{index-C_okzZXP.js → index-CQaXUAua.js} +1 -1
  33. package/dist-renderer/assets/{index-VJ-MM9xa.js → index-CajRpxO2.js} +1 -1
  34. package/dist-renderer/assets/{index-V7dAKPqd.js → index-ChG4rE-E.js} +587 -705
  35. package/dist-renderer/assets/index-DUd0uw9C.css +32 -0
  36. package/dist-renderer/assets/{index-CzWxVCRL.js → index-IhmXZWqf.js} +1 -1
  37. package/dist-renderer/assets/{index-B2Dy7M2G.js → index-x_JkoDRH.js} +1 -1
  38. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-D_WubR0B.js → infoDiagram-HS3SLOUP-D-hWRQGY.js} +1 -1
  39. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-w9ca-1TI.js → journeyDiagram-XKPGCS4Q-Bb6W8rUG.js} +1 -1
  40. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-Jg9p6_pN.js → kanban-definition-3W4ZIXB7-CnHdUX0q.js} +1 -1
  41. package/dist-renderer/assets/{layout-B-z3y17c.js → layout-pqss_zkI.js} +1 -1
  42. package/dist-renderer/assets/{linear-D-RTX5UW.js → linear-B1mFITNh.js} +1 -1
  43. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CDQmHOYP.js → mindmap-definition-VGOIOE7T-DTD9q7-D.js} +1 -1
  44. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-D_odsQL7.js → pieDiagram-ADFJNKIX-Df3mhrn7.js} +1 -1
  45. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BRsmYWSA.js → quadrantDiagram-AYHSOK5B-B1FZ09vH.js} +1 -1
  46. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-ChNE_BOV.js → requirementDiagram-UZGBJVZJ-aEO78thZ.js} +1 -1
  47. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8FtpwKc.js → sankeyDiagram-TZEHDZUN-6Ui--jp-.js} +1 -1
  48. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DmLCzNcc.js → sequenceDiagram-WL72ISMW-DF4Q1cAM.js} +1 -1
  49. package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
  50. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-WJBm4bhu.js → stateDiagram-FKZM4ZOC-BqA2BI8C.js} +1 -1
  51. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Cs2ZtUD2.js +1 -0
  52. package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BXs_hOJs.js → timeline-definition-IT6M3QCI-DoOkw_A8.js} +1 -1
  53. package/dist-renderer/assets/{treemap-GDKQZRPO-o04MA0G9.js → treemap-GDKQZRPO-DUe26QdD.js} +1 -1
  54. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-Czj69XRd.js → xychartDiagram-PRI3JC2R-BKCnj5Xn.js} +1 -1
  55. package/dist-renderer/index.html +20 -53
  56. package/package.json +25 -18
  57. package/src/main/ipc/extensions.ts +2 -1
  58. package/src/main/server.ts +873 -221
  59. package/src/main/services/extensions/ExtensionFacadeService.ts +2 -5
  60. package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
  61. package/src/main/services/session-intelligence/ConversationTelemetryService.ts +1101 -0
  62. package/src/main/services/session-intelligence/LocalSessionScanner.ts +512 -0
  63. package/src/main/services/session-intelligence/SessionUsageParser.ts +4 -4
  64. package/src/main/services/system-manager/SystemManagerConfigService.ts +122 -0
  65. package/src/main/services/system-manager/SystemManagerPtyService.ts +233 -0
  66. package/src/main/services/system-manager/WorkflowPromptService.ts +75 -0
  67. package/src/main/services/teams-mvp/TaskDispatchService.ts +5 -6
  68. package/src/main/services/teams-mvp/TeamProvisioningService.ts +39 -2
  69. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +22 -4
  70. package/src/main/utils/teamProjectResolution.ts +15 -0
  71. package/src/renderer/App.tsx +8 -4
  72. package/src/renderer/api/httpClient.ts +68 -18
  73. package/src/renderer/api/providers.ts +23 -2
  74. package/src/renderer/assets/participant-avatars/01.svg +3 -0
  75. package/src/renderer/assets/participant-avatars/02.svg +3 -0
  76. package/src/renderer/assets/participant-avatars/03.svg +3 -0
  77. package/src/renderer/assets/participant-avatars/04.svg +3 -0
  78. package/src/renderer/assets/participant-avatars/05.svg +3 -0
  79. package/src/renderer/assets/participant-avatars/06.svg +3 -0
  80. package/src/renderer/assets/participant-avatars/07.svg +3 -0
  81. package/src/renderer/assets/participant-avatars/08.svg +3 -0
  82. package/src/renderer/assets/participant-avatars/09.svg +3 -0
  83. package/src/renderer/assets/participant-avatars/10.svg +3 -0
  84. package/src/renderer/assets/participant-avatars/11.svg +3 -0
  85. package/src/renderer/assets/participant-avatars/12.svg +3 -0
  86. package/src/renderer/assets/participant-avatars/13.svg +3 -0
  87. package/src/renderer/components/chat/ChatHistoryItem.tsx +1 -1
  88. package/src/renderer/components/chat/items/SubagentItem.tsx +2 -2
  89. package/src/renderer/components/chat/viewers/MermaidDiagram.tsx +2 -2
  90. package/src/renderer/components/common/ErrorBoundary.tsx +1 -1
  91. package/src/renderer/components/common/TerminalPane.tsx +213 -0
  92. package/src/renderer/components/dashboard/CliStatusBanner.tsx +7 -7
  93. package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
  94. package/src/renderer/components/extensions/ExtensionStoreView.tsx +7 -126
  95. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
  96. package/src/renderer/components/extensions/common/ExtensionToast.tsx +3 -3
  97. package/src/renderer/components/extensions/common/SourceBadge.tsx +1 -1
  98. package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
  99. package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
  100. package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
  101. package/src/renderer/components/extensions/plugins/CategoryChips.tsx +1 -1
  102. package/src/renderer/components/extensions/plugins/PluginCard.tsx +6 -6
  103. package/src/renderer/components/extensions/plugins/PluginDetailDialog.tsx +2 -2
  104. package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +34 -21
  105. package/src/renderer/components/extensions/skills/SkillEditorDialog.tsx +1 -1
  106. package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
  107. package/src/renderer/components/layout/PaneContent.tsx +8 -1
  108. package/src/renderer/components/layout/PaneResizeHandle.tsx +2 -2
  109. package/src/renderer/components/layout/Sidebar.tsx +13 -56
  110. package/src/renderer/components/layout/SortableTab.tsx +22 -33
  111. package/src/renderer/components/layout/TabBar.tsx +1 -1
  112. package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
  113. package/src/renderer/components/report/sections/CostSection.tsx +2 -2
  114. package/src/renderer/components/report/sections/InsightsSection.tsx +1 -1
  115. package/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx +2 -2
  116. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
  117. package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
  118. package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
  119. package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
  120. package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
  121. package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
  122. package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
  123. package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
  124. package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
  125. package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
  126. package/src/renderer/components/schedules/calendar/index.ts +2 -0
  127. package/src/renderer/components/schedules/calendar/types.ts +44 -0
  128. package/src/renderer/components/search/CommandPalette.tsx +4 -4
  129. package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
  130. package/src/renderer/components/settings/SettingsView.tsx +30 -35
  131. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
  132. package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
  133. package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
  134. package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
  135. package/src/renderer/components/settings/sections/CliStatusSection.tsx +72 -113
  136. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
  137. package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
  138. package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
  139. package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
  140. package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
  141. package/src/renderer/components/settings/sections/index.ts +0 -1
  142. package/src/renderer/components/sidebar/SessionFiltersPopover.tsx +1 -1
  143. package/src/renderer/components/sidebar/SessionItem.tsx +3 -3
  144. package/src/renderer/components/sidebar/SidebarSessions.tsx +184 -6
  145. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
  146. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +40 -5
  147. package/src/renderer/components/splash/splashScene.ts +121 -929
  148. package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
  149. package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
  150. package/src/renderer/components/tasks/TasksView.tsx +112 -134
  151. package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
  152. package/src/renderer/components/team/ClaudeLogsFilterPopover.tsx +1 -1
  153. package/src/renderer/components/team/ClaudeLogsPanel.tsx +1 -1
  154. package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
  155. package/src/renderer/components/team/ProcessesSection.tsx +2 -2
  156. package/src/renderer/components/team/TaskTooltip.tsx +2 -2
  157. package/src/renderer/components/team/TeamDetailView.tsx +319 -123
  158. package/src/renderer/components/team/TeamListFilterPopover.tsx +1 -1
  159. package/src/renderer/components/team/TeamListView.tsx +109 -124
  160. package/src/renderer/components/team/TeamSessionsSection.tsx +6 -6
  161. package/src/renderer/components/team/UnreadCommentsBadge.tsx +1 -1
  162. package/src/renderer/components/team/activity/ActivityItem.tsx +9 -9
  163. package/src/renderer/components/team/activity/ActivityTimeline.tsx +5 -5
  164. package/src/renderer/components/team/activity/LeadThoughtsGroup.tsx +3 -3
  165. package/src/renderer/components/team/activity/ReplyQuoteBlock.tsx +4 -4
  166. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +4 -4
  167. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
  168. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
  169. package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
  170. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +18 -16
  171. package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
  172. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +8 -1
  173. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +5 -5
  174. package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
  175. package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +6 -6
  176. package/src/renderer/components/team/dialogs/SkipPermissionsCheckbox.tsx +6 -6
  177. package/src/renderer/components/team/dialogs/StatusHistoryTimeline.tsx +1 -1
  178. package/src/renderer/components/team/dialogs/TaskAttachments.tsx +1 -1
  179. package/src/renderer/components/team/dialogs/TaskCommentInput.tsx +6 -6
  180. package/src/renderer/components/team/dialogs/TaskCommentsSection.tsx +4 -4
  181. package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +3 -3
  182. package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
  183. package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
  184. package/src/renderer/components/team/editor/EditorFileTree.tsx +4 -4
  185. package/src/renderer/components/team/editor/EditorSearchPanel.tsx +1 -1
  186. package/src/renderer/components/team/editor/MarkdownSplitView.tsx +1 -1
  187. package/src/renderer/components/team/editor/NewFileDialog.tsx +1 -1
  188. package/src/renderer/components/team/editor/ProjectEditorOverlay.tsx +1 -1
  189. package/src/renderer/components/team/editor/SearchInFilesPanel.tsx +1 -1
  190. package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
  191. package/src/renderer/components/team/kanban/KanbanFilterPopover.tsx +4 -4
  192. package/src/renderer/components/team/kanban/KanbanSearchInput.tsx +1 -1
  193. package/src/renderer/components/team/kanban/KanbanSortPopover.tsx +5 -5
  194. package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +4 -4
  195. package/src/renderer/components/team/members/MemberCard.tsx +14 -47
  196. package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
  197. package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
  198. package/src/renderer/components/team/members/MemberDraftRow.tsx +1 -1
  199. package/src/renderer/components/team/members/MemberStatsTab.tsx +2 -2
  200. package/src/renderer/components/team/members/MemberWorkspaceTab.tsx +1 -1
  201. package/src/renderer/components/team/messages/MessageComposer.tsx +10 -112
  202. package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +1 -1
  203. package/src/renderer/components/team/messages/MessagesPanel.tsx +136 -119
  204. package/src/renderer/components/team/review/ChangeReviewDialog.tsx +1 -1
  205. package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +3 -3
  206. package/src/renderer/components/team/sidebar/TeamSidebarRail.tsx +4 -4
  207. package/src/renderer/components/team/tasks/TaskRow.tsx +1 -1
  208. package/src/renderer/components/team/tools/AddMcpInline.tsx +27 -17
  209. package/src/renderer/components/team/tools/McpChip.tsx +6 -3
  210. package/src/renderer/components/team/tools/SkillChip.tsx +3 -3
  211. package/src/renderer/components/team/tools/ToolsSection.tsx +418 -70
  212. package/src/renderer/components/ui/MemberSelect.tsx +2 -2
  213. package/src/renderer/components/ui/MentionSuggestionList.tsx +2 -2
  214. package/src/renderer/components/ui/MentionableTextarea.tsx +3 -3
  215. package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
  216. package/src/renderer/index.css +56 -39
  217. package/src/renderer/index.html +17 -50
  218. package/src/renderer/store/index.ts +2 -1
  219. package/src/renderer/store/slices/scheduleSlice.ts +1 -1
  220. package/src/renderer/store/slices/teamSlice.ts +45 -168
  221. package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
  222. package/src/renderer/utils/memberHelpers.ts +5 -17
  223. package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
  224. package/src/renderer/utils/providerSlashCommands.ts +0 -5
  225. package/src/renderer/utils/scheduleFormatters.ts +3 -1
  226. package/src/renderer/utils/teamMessageFiltering.ts +14 -1
  227. package/src/renderer/utils/teamModelAvailability.ts +18 -2
  228. package/src/shared/types/api.ts +121 -2
  229. package/src/shared/types/ccConnect.ts +2 -0
  230. package/src/shared/types/index.ts +3 -0
  231. package/src/shared/types/systemManager.ts +49 -0
  232. package/src/shared/types/team.ts +29 -0
  233. package/src/shared/types/terminal.ts +4 -2
  234. package/src/shared/utils/extensionNormalizers.ts +15 -8
  235. package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
  236. package/dist-renderer/assets/ProjectEditorOverlay-lJZi-9Hp.js +0 -52
  237. package/dist-renderer/assets/channel-yIlSKy0e.js +0 -1
  238. package/dist-renderer/assets/classDiagram-2ON5EDUG-24fHez0s.js +0 -1
  239. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-24fHez0s.js +0 -1
  240. package/dist-renderer/assets/clone-BTNuUva-.js +0 -1
  241. package/dist-renderer/assets/index-Bi6nrZ4z.css +0 -1
  242. package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
  243. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-_m6iPPUR.js +0 -1
@@ -1,4 +1,4 @@
1
- import { useEffect } from 'react';
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Button } from '@renderer/components/ui/button';
4
4
  import { Checkbox } from '@renderer/components/ui/checkbox';
@@ -10,46 +10,16 @@ import {
10
10
  DialogHeader,
11
11
  DialogTitle,
12
12
  } from '@renderer/components/ui/dialog';
13
- import { AGENT_TYPE_LABELS } from '@renderer/components/team/HarnessCards';
14
- import { HarnessSelect } from '@renderer/components/team/HarnessSelect';
15
- import { Loader2, Trash2 } from 'lucide-react';
13
+ import { Loader2 } from 'lucide-react';
16
14
 
17
- import type { CcAgentType } from '@shared/types/ccConnect';
18
-
19
- import { PERMISSION_MODE_OPTIONS, useTeamEditForm } from './useTeamEditForm';
15
+ import { api } from '@renderer/api';
16
+ import { useStore } from '@renderer/store';
20
17
 
21
18
  interface EditTeamDialogProps {
22
19
  open: boolean;
23
20
  teamName: string;
24
21
  onClose: () => void;
25
- onDeleteTeam?: () => void;
26
- }
27
-
28
- // ── Section wrapper ──────────────────────────────────────────
29
- function FormSection({
30
- title,
31
- description,
32
- variant = 'default',
33
- children,
34
- }: {
35
- title: string;
36
- description?: string;
37
- variant?: 'default' | 'danger';
38
- children: React.ReactNode;
39
- }): React.JSX.Element {
40
- const border = variant === 'danger' ? 'border-red-500/40' : 'border-[var(--color-border)]';
41
- const bg = variant === 'danger' ? 'bg-red-500/5' : '';
42
- const titleColor = variant === 'danger' ? 'text-red-300' : 'text-[var(--color-text)]';
43
-
44
- return (
45
- <div className={`rounded-md border ${border} ${bg} p-3`}>
46
- <h3 className={`text-sm font-medium ${titleColor}`}>{title}</h3>
47
- {description && (
48
- <p className="mt-0.5 text-xs text-[var(--color-text-muted)]">{description}</p>
49
- )}
50
- <div className="mt-3 space-y-3">{children}</div>
51
- </div>
52
- );
22
+ onDeleteTeam?: (() => void) | undefined;
53
23
  }
54
24
 
55
25
  // ── Shared input class ───────────────────────────────────────
@@ -65,346 +35,293 @@ export const EditTeamDialog = ({
65
35
  onClose,
66
36
  onDeleteTeam,
67
37
  }: EditTeamDialogProps): React.JSX.Element => {
68
- const form = useTeamEditForm(teamName, open);
38
+ const { data, fetchTeams, selectTeam } = useStore((s) => ({
39
+ data: s.selectedTeamName === teamName ? s.selectedTeamData : null,
40
+ fetchTeams: s.fetchTeams,
41
+ selectTeam: s.selectTeam,
42
+ }));
43
+
44
+ // ── Derived defaults ─────────────────────────────────────────
45
+ const rawSettings = useMemo(
46
+ () => (data?.settings ?? {}) as Record<string, unknown>,
47
+ [data?.settings]
48
+ );
49
+
50
+ const defaults = useMemo(() => {
51
+ const cfg = data?.config;
52
+ return {
53
+ name: cfg?.name ?? '',
54
+ description: cfg?.description ?? '',
55
+ color: cfg?.color ?? '',
56
+ language:
57
+ cfg?.language ?? (typeof rawSettings.language === 'string' ? rawSettings.language : 'zh'),
58
+ managedSources:
59
+ cfg?.managedSources ??
60
+ (typeof rawSettings.admin_from === 'string' ? rawSettings.admin_from : '*'),
61
+ platformAllowFrom:
62
+ cfg?.platformAllowFrom ??
63
+ (typeof rawSettings.platform_allow_from === 'object' &&
64
+ rawSettings.platform_allow_from !== null &&
65
+ !Array.isArray(rawSettings.platform_allow_from)
66
+ ? (rawSettings.platform_allow_from as Record<string, string>)
67
+ : {}),
68
+ platformAllowChat:
69
+ cfg?.platformAllowChat ??
70
+ (typeof (rawSettings as Record<string, unknown>).platform_allow_chat === 'object' &&
71
+ (rawSettings as Record<string, unknown>).platform_allow_chat !== null &&
72
+ !Array.isArray((rawSettings as Record<string, unknown>).platform_allow_chat)
73
+ ? ((rawSettings as Record<string, unknown>).platform_allow_chat as Record<string, string>)
74
+ : {}),
75
+ showContextIndicator:
76
+ cfg?.showContextIndicator ??
77
+ (typeof rawSettings.show_context_indicator === 'boolean'
78
+ ? rawSettings.show_context_indicator
79
+ : true),
80
+ replyFooter:
81
+ cfg?.replyFooter ??
82
+ (typeof rawSettings.reply_footer === 'boolean' ? rawSettings.reply_footer : true),
83
+ injectSender:
84
+ cfg?.injectSender ??
85
+ (typeof rawSettings.inject_sender === 'boolean' ? rawSettings.inject_sender : false),
86
+ };
87
+ }, [data, rawSettings]);
88
+
89
+ // ── Local form state ─────────────────────────────────────────
90
+ const [name, setName] = useState(defaults.name);
91
+ const [description, setDescription] = useState(defaults.description);
92
+ const [language, setLanguage] = useState(defaults.language);
93
+ const [managedSources, setManagedSources] = useState(defaults.managedSources);
94
+ const [feishuAllowFrom, setFeishuAllowFrom] = useState(defaults.platformAllowFrom.feishu ?? '*');
95
+ const [feishuAllowChat, setFeishuAllowChat] = useState(defaults.platformAllowChat.feishu ?? '*');
96
+ const [showContextIndicator, setShowContextIndicator] = useState(defaults.showContextIndicator);
97
+ const [replyFooter, setReplyFooter] = useState(defaults.replyFooter);
98
+ const [injectSender, setInjectSender] = useState(defaults.injectSender);
99
+ const [savePhase, setSavePhase] = useState<'idle' | 'saving' | 'done'>('idle');
100
+ const [error, setError] = useState<string | null>(null);
101
+ const saving = savePhase === 'saving';
69
102
 
70
- // No auto-close — user closes manually after seeing "保存成功"
103
+ const defaultsRef = useRef(defaults);
104
+ if (defaults.name) defaultsRef.current = defaults;
71
105
 
72
- const toggleProviderRef = (providerName: string): void => {
73
- form.clearError();
74
- const next = form.providerRef === providerName ? '' : providerName;
75
- form.setProviderRef(next);
106
+ const prevOpenRef = useRef(false);
107
+ useEffect(() => {
108
+ if (!open || prevOpenRef.current) {
109
+ prevOpenRef.current = open;
110
+ return;
111
+ }
112
+ prevOpenRef.current = true;
113
+ const d = defaultsRef.current;
114
+ setSavePhase('idle');
115
+ setError(null);
116
+ setName(d.name);
117
+ setDescription(d.description);
118
+ setLanguage(d.language);
119
+ setManagedSources(d.managedSources);
120
+ setFeishuAllowFrom(d.platformAllowFrom.feishu ?? '*');
121
+ setFeishuAllowChat(d.platformAllowChat.feishu ?? '*');
122
+ setShowContextIndicator(d.showContextIndicator);
123
+ setReplyFooter(d.replyFooter);
124
+ setInjectSender(d.injectSender);
125
+ }, [open]);
126
+
127
+ const handleSave = (): void => {
128
+ if (!name.trim()) {
129
+ setError('团队名称不能为空');
130
+ return;
131
+ }
132
+ if (savePhase !== 'idle') return;
133
+ setSavePhase('saving');
134
+ setError(null);
135
+
136
+ const feishu = feishuAllowFrom.trim();
137
+ const feishuChat = feishuAllowChat.trim();
138
+
139
+ void (async () => {
140
+ try {
141
+ await api.teams.updateConfig(teamName, {
142
+ name: name.trim(),
143
+ description: description.trim(),
144
+ color: defaultsRef.current.color,
145
+ language: language.trim() || undefined,
146
+ managedSources: managedSources.trim() || undefined,
147
+ platformAllowFrom: feishu ? { feishu } : {},
148
+ platformAllowChat: feishuChat ? { feishu: feishuChat } : {},
149
+ showContextIndicator,
150
+ replyFooter,
151
+ injectSender,
152
+ });
153
+ await Promise.all([fetchTeams(), selectTeam(teamName)]);
154
+ setSavePhase('done');
155
+ } catch (err) {
156
+ setError(err instanceof Error ? err.message : '保存失败');
157
+ setSavePhase('idle');
158
+ }
159
+ })();
76
160
  };
77
161
 
78
162
  const saveLabel =
79
- form.savePhase === 'done'
80
- ? '保存成功'
81
- : form.savePhase === 'restarting'
82
- ? '重启服务中...'
83
- : form.savePhase === 'saving'
84
- ? '保存中...'
85
- : '保存并重启';
163
+ savePhase === 'done' ? '保存成功' : savePhase === 'saving' ? '保存中...' : '保存';
86
164
 
87
165
  return (
88
166
  <Dialog
89
- open={form.saving ? true : open}
167
+ open={saving ? true : open}
90
168
  onOpenChange={(nextOpen) => {
91
- if (form.saving) return;
169
+ if (saving) return;
92
170
  if (!nextOpen) onClose();
93
171
  }}
94
172
  >
95
- <DialogContent className="max-w-2xl">
173
+ <DialogContent className="max-w-lg">
96
174
  <DialogHeader>
97
175
  <DialogTitle>编辑团队</DialogTitle>
98
- <DialogDescription>修改团队名称、描述和运行参数</DialogDescription>
176
+ <DialogDescription>修改团队信息和消息设置(无需重启)</DialogDescription>
99
177
  </DialogHeader>
100
178
 
101
179
  <div className="space-y-4">
102
- {/* ── Section 1: 基本信息 ─────────────────────────── */}
103
- <FormSection title="基本信息">
104
- <div>
105
- <label htmlFor="edit-team-name" className={labelCls}>
106
- 名称
107
- </label>
108
- <input
109
- id="edit-team-name"
110
- type="text"
111
- value={form.name}
112
- onChange={(e) => {
113
- form.clearError();
114
- form.setName(e.target.value);
115
- }}
116
- onKeyDown={(e) => {
117
- if (e.key === 'Enter' && !form.saving && form.name.trim()) form.handleSave();
118
- }}
119
- className={inputCls}
120
- placeholder="团队名称"
121
- />
122
- </div>
123
- <div>
124
- <label htmlFor="edit-team-description" className={labelCls}>
125
- 描述
126
- </label>
127
- <textarea
128
- id="edit-team-description"
129
- value={form.description}
130
- onChange={(e) => {
131
- form.clearError();
132
- form.setDescription(e.target.value);
133
- }}
134
- rows={2}
135
- className={`${inputCls} resize-none`}
136
- placeholder="团队描述(可选)"
137
- />
138
- </div>
139
- </FormSection>
140
-
141
- {/* ── Section 2: Agent 配置 ───────────────────────── */}
142
- <FormSection
143
- title="Agent 配置"
144
- description="运行参数配置。运行时模型和 Provider 请到 Harness 配置中管理。"
145
- >
146
- <div className="grid gap-3 md:grid-cols-2">
147
- <div>
148
- <label className={labelCls}>Agent 类型</label>
149
- <HarnessSelect
150
- value={form.agentType as CcAgentType}
151
- onChange={(v) => {
152
- form.clearError();
153
- form.setAgentType(v);
154
- }}
155
- className="w-full"
156
- />
157
- </div>
158
- <div>
159
- <label className={labelCls}>权限模式</label>
160
- <select
161
- value={form.permissionMode}
162
- onChange={(e) => {
163
- form.clearError();
164
- form.setPermissionMode(e.target.value);
165
- }}
166
- className={inputCls}
167
- >
168
- {PERMISSION_MODE_OPTIONS.map((opt) => (
169
- <option key={opt.value} value={opt.value}>
170
- {opt.label}
171
- </option>
172
- ))}
173
- </select>
174
- </div>
175
- </div>
176
- <div>
177
- <label className={labelCls}>工作目录</label>
178
- <input
179
- type="text"
180
- value={form.workDir}
181
- onChange={(e) => {
182
- form.clearError();
183
- form.setWorkDir(e.target.value);
184
- }}
185
- className={`${inputCls} font-mono`}
186
- placeholder="/Users/you/code/project"
187
- />
188
- </div>
189
- </FormSection>
190
-
191
- {/* ── Section 3: 通信与平台 ───────────────────────── */}
192
- <FormSection title="通信与平台">
193
- <div className="grid gap-3 md:grid-cols-2">
194
- <div>
195
- <label className={labelCls}>语言</label>
196
- <input
197
- type="text"
198
- value={form.language}
199
- onChange={(e) => {
200
- form.clearError();
201
- form.setLanguage(e.target.value);
202
- }}
203
- className={inputCls}
204
- placeholder="zh"
205
- />
206
- </div>
207
- <div>
208
- <label className={labelCls}>管理来源</label>
209
- <input
210
- type="text"
211
- value={form.managedSources}
212
- onChange={(e) => {
213
- form.clearError();
214
- form.setManagedSources(e.target.value);
215
- }}
216
- className={inputCls}
217
- placeholder="user1,user2 或 *"
218
- />
219
- </div>
220
- </div>
221
- <div>
222
- <label className={labelCls}>平台访问控制(Feishu 允许的用户)</label>
223
- <input
224
- type="text"
225
- value={form.feishuAllowFrom}
226
- onChange={(e) => {
227
- form.clearError();
228
- form.setFeishuAllowFrom(e.target.value);
229
- }}
230
- className={inputCls}
231
- placeholder="*"
232
- />
233
- </div>
234
- </FormSection>
235
-
236
- {/* ── Section 4: 高级开关 ─────────────────────────── */}
237
- <div className="grid gap-2 md:grid-cols-3">
238
- <label
239
- htmlFor="edit-team-show-context-indicator"
240
- className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]"
241
- >
242
- <Checkbox
243
- id="edit-team-show-context-indicator"
244
- checked={form.showContextIndicator}
245
- onCheckedChange={(checked) => {
246
- form.clearError();
247
- form.setShowContextIndicator(checked === true);
248
- }}
249
- />
250
- 上下文指示
180
+ {/* Basic info */}
181
+ <div>
182
+ <label htmlFor="edit-team-name" className={labelCls}>
183
+ 名称
251
184
  </label>
252
- <label
253
- htmlFor="edit-team-reply-footer"
254
- className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]"
255
- >
256
- <Checkbox
257
- id="edit-team-reply-footer"
258
- checked={form.replyFooter}
259
- onCheckedChange={(checked) => {
260
- form.clearError();
261
- form.setReplyFooter(checked === true);
262
- }}
263
- />
264
- 回复尾部信息
265
- </label>
266
- <label
267
- htmlFor="edit-team-inject-sender"
268
- className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]"
269
- >
270
- <Checkbox
271
- id="edit-team-inject-sender"
272
- checked={form.injectSender}
273
- onCheckedChange={(checked) => {
274
- form.clearError();
275
- form.setInjectSender(checked === true);
276
- }}
277
- />
278
- 注入发送者
185
+ <input
186
+ id="edit-team-name"
187
+ type="text"
188
+ value={name}
189
+ onChange={(e) => {
190
+ setError(null);
191
+ setName(e.target.value);
192
+ }}
193
+ onKeyDown={(e) => {
194
+ if (e.key === 'Enter' && !saving && name.trim()) handleSave();
195
+ }}
196
+ className={inputCls}
197
+ placeholder="团队名称"
198
+ />
199
+ </div>
200
+ <div>
201
+ <label htmlFor="edit-team-description" className={labelCls}>
202
+ 描述
279
203
  </label>
204
+ <textarea
205
+ id="edit-team-description"
206
+ value={description}
207
+ onChange={(e) => {
208
+ setError(null);
209
+ setDescription(e.target.value);
210
+ }}
211
+ rows={2}
212
+ className={`${inputCls} resize-none`}
213
+ placeholder="团队描述(可选)"
214
+ />
280
215
  </div>
281
216
 
282
- {/* ── Section 5: Provider 绑定 ────────────────────── */}
283
- <div className="rounded-lg border border-[var(--color-border-subtle)] bg-white/[0.02] p-3">
284
- <div className="flex items-start justify-between gap-3">
285
- <div>
286
- <p className="text-xs font-medium text-[var(--color-text)]">Provider(可选)</p>
287
- <p className="mt-1 text-[11px] leading-relaxed text-[var(--color-text-muted)]">
288
- 留空时使用本机{' '}
289
- {AGENT_TYPE_LABELS[form.agentType as CcAgentType] ?? form.agentType}{' '}
290
- 默认配置和登录状态。只有需要给该团队指定模型供应商时,才绑定下面的全局 Provider。
291
- </p>
217
+ {/* Messaging settings */}
218
+ <div className="rounded-md border border-[var(--color-border)] p-3">
219
+ <h3 className="text-xs font-medium text-[var(--color-text)]">消息设置</h3>
220
+ <div className="mt-3 space-y-3">
221
+ <div className="grid gap-3 md:grid-cols-2">
222
+ <div>
223
+ <label className={labelCls}>语言</label>
224
+ <input
225
+ type="text"
226
+ value={language}
227
+ onChange={(e) => {
228
+ setError(null);
229
+ setLanguage(e.target.value);
230
+ }}
231
+ className={inputCls}
232
+ placeholder="zh"
233
+ />
234
+ </div>
235
+ <div>
236
+ <label className={labelCls}>管理来源</label>
237
+ <input
238
+ type="text"
239
+ value={managedSources}
240
+ onChange={(e) => {
241
+ setError(null);
242
+ setManagedSources(e.target.value);
243
+ }}
244
+ className={inputCls}
245
+ placeholder="user1,user2 或 *"
246
+ />
247
+ </div>
292
248
  </div>
293
- {form.providerRef ? (
294
- <button
295
- type="button"
296
- className="shrink-0 rounded-md border border-[var(--color-border)] px-2 py-1 text-[11px] text-[var(--color-text-muted)] hover:bg-white/5"
297
- onClick={() => form.setProviderRef('')}
298
- >
299
- 使用本机默认
300
- </button>
301
- ) : null}
302
- </div>
303
-
304
- <div className="mt-3 space-y-2">
305
- {form.compatibleProviders.length > 0 ? (
306
- form.compatibleProviders.map((provider) => {
307
- const checked = form.providerRef === provider.name;
308
- const at = form.agentType as CcAgentType;
309
- const endpoint = provider.endpoints?.[at] ?? provider.base_url ?? '默认端点';
310
- const model =
311
- provider.agent_models?.[at] ??
312
- provider.model ??
313
- provider.models?.[0]?.model ??
314
- '未指定模型';
315
- return (
316
- <button
317
- key={provider.name}
318
- type="button"
319
- onClick={() => toggleProviderRef(provider.name)}
320
- className={`w-full rounded-lg border px-3 py-2 text-left transition-colors ${
321
- checked
322
- ? 'border-indigo-400/60 bg-indigo-500/10'
323
- : 'border-[var(--color-border-subtle)] bg-black/10 hover:border-[var(--color-border)] hover:bg-white/[0.04]'
324
- }`}
325
- >
326
- <div className="flex items-center justify-between gap-3">
327
- <div className="min-w-0">
328
- <p className="truncate text-xs font-medium text-[var(--color-text)]">
329
- {provider.name}
330
- </p>
331
- <p className="mt-0.5 truncate text-[11px] text-[var(--color-text-muted)]">
332
- {model} · {endpoint}
333
- </p>
334
- </div>
335
- <span
336
- className={`shrink-0 rounded-full px-2 py-0.5 text-[10px] ${
337
- checked
338
- ? 'bg-indigo-400/20 text-indigo-200'
339
- : 'bg-white/5 text-[var(--color-text-muted)]'
340
- }`}
341
- >
342
- {checked ? '已绑定' : '可绑定'}
343
- </span>
344
- </div>
345
- </button>
346
- );
347
- })
348
- ) : (
349
- <div className="rounded-md border border-dashed border-[var(--color-border)] px-3 py-3 text-xs text-[var(--color-text-muted)]">
350
- 暂无适用于 {AGENT_TYPE_LABELS[form.agentType as CcAgentType] ?? form.agentType}{' '}
351
- 的全局 Provider。可先在「设置 → Harness
352
- 配置」中添加;不添加也会使用本机默认登录态。
249
+ <div className="grid gap-3 md:grid-cols-2">
250
+ <div>
251
+ <label className={labelCls}>飞书私聊权限</label>
252
+ <input
253
+ type="text"
254
+ value={feishuAllowFrom}
255
+ onChange={(e) => {
256
+ setError(null);
257
+ setFeishuAllowFrom(e.target.value);
258
+ }}
259
+ className={inputCls}
260
+ placeholder="ou_xxx 或 *"
261
+ />
262
+ </div>
263
+ <div>
264
+ <label className={labelCls}>飞书群聊权限</label>
265
+ <input
266
+ type="text"
267
+ value={feishuAllowChat}
268
+ onChange={(e) => {
269
+ setError(null);
270
+ setFeishuAllowChat(e.target.value);
271
+ }}
272
+ className={inputCls}
273
+ placeholder="oc_xxx 或 *"
274
+ />
353
275
  </div>
354
- )}
276
+ </div>
277
+ <div className="grid gap-2 md:grid-cols-3">
278
+ <label className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]">
279
+ <Checkbox
280
+ checked={showContextIndicator}
281
+ onCheckedChange={(c) => {
282
+ setError(null);
283
+ setShowContextIndicator(c === true);
284
+ }}
285
+ />
286
+ 上下文指示
287
+ </label>
288
+ <label className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]">
289
+ <Checkbox
290
+ checked={replyFooter}
291
+ onCheckedChange={(c) => {
292
+ setError(null);
293
+ setReplyFooter(c === true);
294
+ }}
295
+ />
296
+ 回复尾部信息
297
+ </label>
298
+ <label className="flex cursor-pointer items-center gap-2 rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs text-[var(--color-text-secondary)]">
299
+ <Checkbox
300
+ checked={injectSender}
301
+ onCheckedChange={(c) => {
302
+ setError(null);
303
+ setInjectSender(c === true);
304
+ }}
305
+ />
306
+ 注入发送者
307
+ </label>
308
+ </div>
355
309
  </div>
356
310
  </div>
357
311
 
358
- {/* ── Section 6: 危险操作 ─────────────────────────── */}
359
- <FormSection title="危险操作" variant="danger">
360
- <div>
361
- <label className={labelCls}>已禁用命令</label>
362
- <input
363
- type="text"
364
- value={form.disabledCommandsInput}
365
- onChange={(e) => {
366
- form.clearError();
367
- form.setDisabledCommandsInput(e.target.value);
368
- }}
369
- className={inputCls}
370
- placeholder="restart, upgrade, cron"
371
- />
372
- </div>
373
- {onDeleteTeam && form.canDelete && (
374
- <>
375
- <p className="text-xs text-[var(--color-text-muted)]">
376
- 删除项目会将团队从当前控制面板移除。
377
- </p>
378
- <Button
379
- type="button"
380
- variant="destructive"
381
- size="sm"
382
- onClick={() => {
383
- onClose();
384
- window.setTimeout(onDeleteTeam, 0);
385
- }}
386
- >
387
- <Trash2 size={14} className="mr-1.5" />
388
- 删除项目
389
- </Button>
390
- </>
391
- )}
392
- </FormSection>
393
-
394
- {/* ── Status messages ──────────────────────────────── */}
395
- {form.error && <p className="text-xs text-red-400">{form.error}</p>}
312
+ {error && <p className="text-xs text-red-400">{error}</p>}
396
313
  </div>
397
314
 
398
315
  <DialogFooter>
399
- <Button variant="outline" size="sm" onClick={onClose} disabled={form.saving}>
400
- {form.savePhase === 'done' ? '关闭' : '取消'}
316
+ <Button variant="outline" size="sm" onClick={onClose} disabled={saving}>
317
+ {savePhase === 'done' ? '关闭' : '取消'}
401
318
  </Button>
402
319
  <Button
403
320
  size="sm"
404
- onClick={form.handleSave}
405
- disabled={form.saving || form.savePhase === 'done' || !form.name.trim()}
321
+ onClick={handleSave}
322
+ disabled={saving || savePhase === 'done' || !name.trim()}
406
323
  >
407
- {form.saving && <Loader2 size={14} className="mr-1.5 animate-spin" />}
324
+ {saving && <Loader2 size={14} className="mr-1.5 animate-spin" />}
408
325
  {saveLabel}
409
326
  </Button>
410
327
  </DialogFooter>
@@ -103,7 +103,7 @@ export const GlobalTaskDetailDialog = (): React.JSX.Element | null => {
103
103
 
104
104
  const handleOpenTeam = useCallback((): void => {
105
105
  closeGlobalTaskDetail();
106
- openTeamTab(teamName, undefined, taskId);
106
+ openTeamTab(teamName, undefined, { taskId });
107
107
  }, [closeGlobalTaskDetail, openTeamTab, teamName, taskId]);
108
108
 
109
109
  const handleViewChanges = useCallback(