@parhelia/core 0.3.12831 → 0.4.12796

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 (339) hide show
  1. package/dist/agents-view/AgentCard.js +2 -2
  2. package/dist/agents-view/AgentCard.js.map +1 -1
  3. package/dist/agents-view/AgentsView.js +4 -2
  4. package/dist/agents-view/AgentsView.js.map +1 -1
  5. package/dist/agents-view/AgentsWorkspaceView.js +8 -1
  6. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  7. package/dist/agents-view/DateAgentsGroup.js +1 -1
  8. package/dist/agents-view/DateAgentsGroup.js.map +1 -1
  9. package/dist/components/ui/checkbox.js +3 -2
  10. package/dist/components/ui/checkbox.js.map +1 -1
  11. package/dist/components/ui/context-menu.d.ts +9 -1
  12. package/dist/components/ui/context-menu.js +59 -12
  13. package/dist/components/ui/context-menu.js.map +1 -1
  14. package/dist/components/ui/select.js +16 -2
  15. package/dist/components/ui/select.js.map +1 -1
  16. package/dist/config/config.d.ts +2 -0
  17. package/dist/config/config.js +66 -10
  18. package/dist/config/config.js.map +1 -1
  19. package/dist/config/types/sidebar.d.ts +8 -0
  20. package/dist/config/types/workspace.d.ts +8 -0
  21. package/dist/config/types.d.ts +24 -0
  22. package/dist/config/types.js.map +1 -1
  23. package/dist/editor/ContextMenu.js +59 -6
  24. package/dist/editor/ContextMenu.js.map +1 -1
  25. package/dist/editor/Editor.js +9 -2
  26. package/dist/editor/Editor.js.map +1 -1
  27. package/dist/editor/EditorWarning.d.ts +3 -1
  28. package/dist/editor/EditorWarning.js +24 -7
  29. package/dist/editor/EditorWarning.js.map +1 -1
  30. package/dist/editor/FieldList.js +1 -1
  31. package/dist/editor/FieldList.js.map +1 -1
  32. package/dist/editor/GlobalMenuBar.js +8 -6
  33. package/dist/editor/GlobalMenuBar.js.map +1 -1
  34. package/dist/editor/LinkEditorDialog.d.ts +2 -0
  35. package/dist/editor/LinkEditorDialog.js +6 -1
  36. package/dist/editor/LinkEditorDialog.js.map +1 -1
  37. package/dist/editor/ai/AgentSharingSection.d.ts +1 -1
  38. package/dist/editor/ai/AgentSharingSection.js +7 -0
  39. package/dist/editor/ai/AgentSharingSection.js.map +1 -1
  40. package/dist/editor/ai/Agents.js +7 -7
  41. package/dist/editor/ai/Agents.js.map +1 -1
  42. package/dist/editor/ai/InlineAiDialog.d.ts +7 -1
  43. package/dist/editor/ai/InlineAiDialog.js +27 -7
  44. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  45. package/dist/editor/ai/InlineAiTrigger.js +63 -1
  46. package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
  47. package/dist/editor/ai/terminal/activeReasoningModel.d.ts +9 -0
  48. package/dist/editor/ai/terminal/activeReasoningModel.js +20 -0
  49. package/dist/editor/ai/terminal/activeReasoningModel.js.map +1 -0
  50. package/dist/editor/ai/terminal/agentDurations.d.ts +27 -0
  51. package/dist/editor/ai/terminal/agentDurations.js +89 -0
  52. package/dist/editor/ai/terminal/agentDurations.js.map +1 -0
  53. package/dist/editor/ai/terminal/agentStartRequest.d.ts +1 -0
  54. package/dist/editor/ai/terminal/agentStartRequest.js +1 -0
  55. package/dist/editor/ai/terminal/agentStartRequest.js.map +1 -1
  56. package/dist/editor/ai/terminal/agentTurnTiming.d.ts +33 -0
  57. package/dist/editor/ai/terminal/agentTurnTiming.js +103 -0
  58. package/dist/editor/ai/terminal/agentTurnTiming.js.map +1 -0
  59. package/dist/editor/ai/terminal/components/AgentCostDisplay.d.ts +3 -1
  60. package/dist/editor/ai/terminal/components/AgentCostDisplay.js +16 -25
  61. package/dist/editor/ai/terminal/components/AgentCostDisplay.js.map +1 -1
  62. package/dist/editor/ai/terminal/components/AgentGreeting.js +4 -1
  63. package/dist/editor/ai/terminal/components/AgentGreeting.js.map +1 -1
  64. package/dist/editor/ai/terminal/components/AgentProfileModelSettingsSection.d.ts +5 -1
  65. package/dist/editor/ai/terminal/components/AgentProfileModelSettingsSection.js +7 -2
  66. package/dist/editor/ai/terminal/components/AgentProfileModelSettingsSection.js.map +1 -1
  67. package/dist/editor/ai/terminal/components/AgentProfileRecovery.d.ts +10 -0
  68. package/dist/editor/ai/terminal/components/AgentProfileRecovery.js +12 -0
  69. package/dist/editor/ai/terminal/components/AgentProfileRecovery.js.map +1 -0
  70. package/dist/editor/ai/terminal/components/AgentProfileSwitcher.js +1 -1
  71. package/dist/editor/ai/terminal/components/AgentProfileSwitcher.js.map +1 -1
  72. package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js +1 -1
  73. package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js.map +1 -1
  74. package/dist/editor/ai/terminal/components/AgentPromptComposer.js +1 -1
  75. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js +1 -1
  76. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js.map +1 -1
  77. package/dist/editor/ai/terminal/components/AgentSettingsContent.d.ts +5 -1
  78. package/dist/editor/ai/terminal/components/AgentSettingsContent.js +2 -2
  79. package/dist/editor/ai/terminal/components/AgentSettingsContent.js.map +1 -1
  80. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.d.ts +2 -1
  81. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js +2 -2
  82. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js.map +1 -1
  83. package/dist/editor/ai/terminal/components/AgentTerminalFullPromptControls.d.ts +1 -1
  84. package/dist/editor/ai/terminal/components/AgentTerminalFullPromptControls.js +2 -2
  85. package/dist/editor/ai/terminal/components/AgentTerminalFullPromptControls.js.map +1 -1
  86. package/dist/editor/ai/terminal/components/AgentTerminalFullUpperContent.js +17 -1
  87. package/dist/editor/ai/terminal/components/AgentTerminalFullUpperContent.js.map +1 -1
  88. package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js +2 -1
  89. package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js.map +1 -1
  90. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.d.ts +1 -1
  91. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js +69 -8
  92. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js.map +1 -1
  93. package/dist/editor/ai/terminal/components/AgentTerminalSummaryLayout.d.ts +2 -1
  94. package/dist/editor/ai/terminal/components/AgentTerminalSummaryLayout.js +2 -2
  95. package/dist/editor/ai/terminal/components/AgentTerminalSummaryLayout.js.map +1 -1
  96. package/dist/editor/ai/terminal/components/AgentThinkingIndicator.d.ts +21 -1
  97. package/dist/editor/ai/terminal/components/AgentThinkingIndicator.js +15 -4
  98. package/dist/editor/ai/terminal/components/AgentThinkingIndicator.js.map +1 -1
  99. package/dist/editor/ai/terminal/components/AiResponseMessage.d.ts +3 -1
  100. package/dist/editor/ai/terminal/components/AiResponseMessage.js +84 -58
  101. package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
  102. package/dist/editor/ai/terminal/components/ApprovalCard.js +72 -10
  103. package/dist/editor/ai/terminal/components/ApprovalCard.js.map +1 -1
  104. package/dist/editor/ai/terminal/components/InitialThinkingSplash.js +2 -2
  105. package/dist/editor/ai/terminal/components/InitialThinkingSplash.js.map +1 -1
  106. package/dist/editor/ai/terminal/components/QueuedPromptsPanel.js +2 -2
  107. package/dist/editor/ai/terminal/components/ResponseTurnDuration.d.ts +15 -0
  108. package/dist/editor/ai/terminal/components/ResponseTurnDuration.js +52 -0
  109. package/dist/editor/ai/terminal/components/ResponseTurnDuration.js.map +1 -0
  110. package/dist/editor/ai/terminal/components/ToolCallDisplay.d.ts +3 -1
  111. package/dist/editor/ai/terminal/components/ToolCallDisplay.js +35 -57
  112. package/dist/editor/ai/terminal/components/ToolCallDisplay.js.map +1 -1
  113. package/dist/editor/ai/terminal/components/UserMessage.js +1 -1
  114. package/dist/editor/ai/terminal/components/UserMessage.js.map +1 -1
  115. package/dist/editor/ai/terminal/components/agentThinkingStyles.d.ts +26 -1
  116. package/dist/editor/ai/terminal/components/agentThinkingStyles.js +26 -1
  117. package/dist/editor/ai/terminal/components/agentThinkingStyles.js.map +1 -1
  118. package/dist/editor/ai/terminal/components/approvalActions.d.ts +1 -0
  119. package/dist/editor/ai/terminal/components/approvalActions.js +5 -2
  120. package/dist/editor/ai/terminal/components/approvalActions.js.map +1 -1
  121. package/dist/editor/ai/terminal/components/useApprovalActions.d.ts +4 -4
  122. package/dist/editor/ai/terminal/components/useApprovalActions.js +5 -2
  123. package/dist/editor/ai/terminal/components/useApprovalActions.js.map +1 -1
  124. package/dist/editor/ai/terminal/reasoningEffortLevels.d.ts +8 -0
  125. package/dist/editor/ai/terminal/reasoningEffortLevels.js +54 -0
  126. package/dist/editor/ai/terminal/reasoningEffortLevels.js.map +1 -0
  127. package/dist/editor/ai/terminal/requestUsage.d.ts +3 -0
  128. package/dist/editor/ai/terminal/requestUsage.js +22 -0
  129. package/dist/editor/ai/terminal/requestUsage.js.map +1 -0
  130. package/dist/editor/ai/terminal/types.d.ts +1 -0
  131. package/dist/editor/ai/terminal/useAgentModeState.js.map +1 -1
  132. package/dist/editor/ai/terminal/useAgentProfileSelection.d.ts +10 -0
  133. package/dist/editor/ai/terminal/useAgentProfileSelection.js +10 -2
  134. package/dist/editor/ai/terminal/useAgentProfileSelection.js.map +1 -1
  135. package/dist/editor/ai/terminal/useAgentReasoningEffortState.d.ts +5 -0
  136. package/dist/editor/ai/terminal/useAgentReasoningEffortState.js +10 -0
  137. package/dist/editor/ai/terminal/useAgentReasoningEffortState.js.map +1 -0
  138. package/dist/editor/ai/terminal/useAgentSessionSync.d.ts +1 -0
  139. package/dist/editor/ai/terminal/useAgentSettingsCommands.d.ts +9 -0
  140. package/dist/editor/ai/terminal/useAgentSettingsCommands.js +63 -6
  141. package/dist/editor/ai/terminal/useAgentSettingsCommands.js.map +1 -1
  142. package/dist/editor/ai/terminal/useAgentSettingsPanel.d.ts +5 -0
  143. package/dist/editor/ai/terminal/useAgentSettingsPanel.js +8 -0
  144. package/dist/editor/ai/terminal/useAgentSettingsPanel.js.map +1 -1
  145. package/dist/editor/ai/terminal/useAgentSkillActions.d.ts +1 -0
  146. package/dist/editor/ai/terminal/useAgentSkillActions.js +1 -0
  147. package/dist/editor/ai/terminal/useAgentSkillActions.js.map +1 -1
  148. package/dist/editor/ai/terminal/useAgentSubmitHandlers.d.ts +1 -0
  149. package/dist/editor/ai/terminal/useAgentSubmitHandlers.js +6 -1
  150. package/dist/editor/ai/terminal/useAgentSubmitHandlers.js.map +1 -1
  151. package/dist/editor/ai/terminal/useAgentTerminalController.d.ts +1 -1
  152. package/dist/editor/ai/terminal/useAgentTerminalController.js +21 -4
  153. package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
  154. package/dist/editor/ai/terminal/useAgentTerminalControls.d.ts +4 -0
  155. package/dist/editor/ai/terminal/useAgentTerminalControls.js +5 -1
  156. package/dist/editor/ai/terminal/useAgentTerminalControls.js.map +1 -1
  157. package/dist/editor/ai-image-editor/AiImageEditorDialog.d.ts +6 -0
  158. package/dist/editor/ai-image-editor/AiImageEditorDialog.js +202 -64
  159. package/dist/editor/ai-image-editor/AiImageEditorDialog.js.map +1 -1
  160. package/dist/editor/client/EditorShell.js +733 -722
  161. package/dist/editor/client/EditorShell.js.map +1 -1
  162. package/dist/editor/client/SandboxWelcomeOverlay.d.ts +4 -1
  163. package/dist/editor/client/SandboxWelcomeOverlay.js +6 -5
  164. package/dist/editor/client/SandboxWelcomeOverlay.js.map +1 -1
  165. package/dist/editor/client/SessionsDialog.d.ts +2 -0
  166. package/dist/editor/client/SessionsDialog.js +27 -0
  167. package/dist/editor/client/SessionsDialog.js.map +1 -0
  168. package/dist/editor/client/hooks/useSocketMessageHandler.js +4 -0
  169. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  170. package/dist/editor/client/ui/DevModeIndicator.js +6 -4
  171. package/dist/editor/client/ui/DevModeIndicator.js.map +1 -1
  172. package/dist/editor/commands/componentCommands.js +1 -2
  173. package/dist/editor/commands/componentCommands.js.map +1 -1
  174. package/dist/editor/editor-warnings/ItemLocked.js +1 -1
  175. package/dist/editor/editor-warnings/ItemLocked.js.map +1 -1
  176. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js +1 -1
  177. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js.map +1 -1
  178. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.js +1 -1
  179. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.js.map +1 -1
  180. package/dist/editor/editor-warnings/NoWriteAccess.js +1 -1
  181. package/dist/editor/editor-warnings/NoWriteAccess.js.map +1 -1
  182. package/dist/editor/field-types/LinkFieldEditor.js +15 -4
  183. package/dist/editor/field-types/LinkFieldEditor.js.map +1 -1
  184. package/dist/editor/field-types/MultiLineText.js +6 -1
  185. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  186. package/dist/editor/field-types/RichTextEditor.js +5 -5
  187. package/dist/editor/field-types/RichTextEditor.js.map +1 -1
  188. package/dist/editor/field-types/SingleLineText.js +6 -1
  189. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  190. package/dist/editor/field-types/TreeListEditor.js +3 -3
  191. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  192. package/dist/editor/fieldTypes.d.ts +2 -0
  193. package/dist/editor/itemContextMenuGroups.d.ts +16 -0
  194. package/dist/editor/itemContextMenuGroups.js +48 -0
  195. package/dist/editor/itemContextMenuGroups.js.map +1 -0
  196. package/dist/editor/media-selector/MediaFolderBrowser.js +1 -1
  197. package/dist/editor/menubar/ActiveUsers.js +4 -1
  198. package/dist/editor/menubar/ActiveUsers.js.map +1 -1
  199. package/dist/editor/menubar/OpenPublishedPageButton.d.ts +1 -0
  200. package/dist/editor/menubar/OpenPublishedPageButton.js +22 -0
  201. package/dist/editor/menubar/OpenPublishedPageButton.js.map +1 -0
  202. package/dist/editor/menubar/WorkflowButton.js +77 -22
  203. package/dist/editor/menubar/WorkflowButton.js.map +1 -1
  204. package/dist/editor/menubar/toolbar-sections/PreviewModeControl.js +1 -1
  205. package/dist/editor/menubar/toolbar-sections/PreviewModeControl.js.map +1 -1
  206. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +8 -4
  207. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  208. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +36 -1
  209. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -1
  210. package/dist/editor/page-editor-chrome/PageEditorChrome.js +4 -0
  211. package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
  212. package/dist/editor/page-editor-chrome/bridgeInlineFormatToolbarLayout.d.ts +19 -0
  213. package/dist/editor/page-editor-chrome/bridgeInlineFormatToolbarLayout.js +14 -0
  214. package/dist/editor/page-editor-chrome/bridgeInlineFormatToolbarLayout.js.map +1 -1
  215. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.d.ts +3 -0
  216. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js +18 -0
  217. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
  218. package/dist/editor/page-viewer/DeviceToolbar.js +20 -8
  219. package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -1
  220. package/dist/editor/page-viewer/EditorForm.js +8 -7
  221. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  222. package/dist/editor/page-viewer/PageViewerFrame.js +10 -0
  223. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  224. package/dist/editor/page-viewer/PreviewModeNotice.d.ts +7 -0
  225. package/dist/editor/page-viewer/PreviewModeNotice.js +19 -0
  226. package/dist/editor/page-viewer/PreviewModeNotice.js.map +1 -0
  227. package/dist/editor/page-viewer/pageViewContext.d.ts +5 -1
  228. package/dist/editor/page-viewer/pageViewContext.js +59 -2
  229. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  230. package/dist/editor/page-viewer/previewEditAttempt.d.ts +31 -0
  231. package/dist/editor/page-viewer/previewEditAttempt.js +68 -0
  232. package/dist/editor/page-viewer/previewEditAttempt.js.map +1 -0
  233. package/dist/editor/pageModel.d.ts +1 -0
  234. package/dist/editor/services/agentService.d.ts +67 -0
  235. package/dist/editor/services/agentService.js +2 -0
  236. package/dist/editor/services/agentService.js.map +1 -1
  237. package/dist/editor/services/aiService.d.ts +7 -0
  238. package/dist/editor/services/aiService.js.map +1 -1
  239. package/dist/editor/services/contentService.d.ts +9 -0
  240. package/dist/editor/services/contentService.js.map +1 -1
  241. package/dist/editor/services/editService.d.ts +13 -0
  242. package/dist/editor/services/editService.js +8 -0
  243. package/dist/editor/services/editService.js.map +1 -1
  244. package/dist/editor/services/migrationService.d.ts +31 -0
  245. package/dist/editor/services/migrationService.js +22 -0
  246. package/dist/editor/services/migrationService.js.map +1 -0
  247. package/dist/editor/services/publicSiteService.d.ts +40 -0
  248. package/dist/editor/services/publicSiteService.js +5 -0
  249. package/dist/editor/services/publicSiteService.js.map +1 -0
  250. package/dist/editor/settings/About.js +71 -32
  251. package/dist/editor/settings/About.js.map +1 -1
  252. package/dist/editor/settings/MigrationJournalCard.d.ts +12 -0
  253. package/dist/editor/settings/MigrationJournalCard.js +114 -0
  254. package/dist/editor/settings/MigrationJournalCard.js.map +1 -0
  255. package/dist/editor/settings/QuotaUserPicker.js +1 -1
  256. package/dist/editor/settings/SettingsView.js +18 -5
  257. package/dist/editor/settings/SettingsView.js.map +1 -1
  258. package/dist/editor/settings/panels/AgentProfileConfigPanel.js +1 -0
  259. package/dist/editor/settings/panels/AgentProfileConfigPanel.js.map +1 -1
  260. package/dist/editor/settings/panels/ModelConfigPanel.js +2 -0
  261. package/dist/editor/settings/panels/ModelConfigPanel.js.map +1 -1
  262. package/dist/editor/settings/panels/PublicSiteEntryDialog.d.ts +8 -0
  263. package/dist/editor/settings/panels/PublicSiteEntryDialog.js +113 -0
  264. package/dist/editor/settings/panels/PublicSiteEntryDialog.js.map +1 -0
  265. package/dist/editor/settings/panels/PublicSitesPanel.d.ts +1 -0
  266. package/dist/editor/settings/panels/PublicSitesPanel.js +153 -0
  267. package/dist/editor/settings/panels/PublicSitesPanel.js.map +1 -0
  268. package/dist/editor/settings/panels/StatusPanel.js +2 -1
  269. package/dist/editor/settings/panels/StatusPanel.js.map +1 -1
  270. package/dist/editor/settings/panels/UserPreferencesPanel.js +4 -4
  271. package/dist/editor/settings/panels/UserPreferencesPanel.js.map +1 -1
  272. package/dist/editor/settings/panels/index.d.ts +1 -0
  273. package/dist/editor/settings/panels/index.js +1 -0
  274. package/dist/editor/settings/panels/index.js.map +1 -1
  275. package/dist/editor/settings/panels/publicSiteHelpers.d.ts +6 -0
  276. package/dist/editor/settings/panels/publicSiteHelpers.js +30 -0
  277. package/dist/editor/settings/panels/publicSiteHelpers.js.map +1 -0
  278. package/dist/editor/settings/status/coreStatusChecks.js +4 -0
  279. package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
  280. package/dist/editor/sidebar/OperationDetailsContent.d.ts +14 -0
  281. package/dist/editor/sidebar/OperationDetailsContent.js +521 -0
  282. package/dist/editor/sidebar/OperationDetailsContent.js.map +1 -0
  283. package/dist/editor/sidebar/OperationItem.js +9 -77
  284. package/dist/editor/sidebar/OperationItem.js.map +1 -1
  285. package/dist/editor/sidebar/Sessions.d.ts +3 -1
  286. package/dist/editor/sidebar/Sessions.js +2 -1
  287. package/dist/editor/sidebar/Sessions.js.map +1 -1
  288. package/dist/editor/sidebar/Workbox.js +22 -7
  289. package/dist/editor/sidebar/Workbox.js.map +1 -1
  290. package/dist/editor/ui/PerfectTree.js +14 -7
  291. package/dist/editor/ui/PerfectTree.js.map +1 -1
  292. package/dist/editor/ui/PublishDialog.d.ts +7 -2
  293. package/dist/editor/ui/PublishDialog.js +67 -33
  294. package/dist/editor/ui/PublishDialog.js.map +1 -1
  295. package/dist/editor/ui/PublishItemDialog.js +31 -20
  296. package/dist/editor/ui/PublishItemDialog.js.map +1 -1
  297. package/dist/editor/ui/PublishReadinessSummary.d.ts +12 -0
  298. package/dist/editor/ui/PublishReadinessSummary.js +34 -0
  299. package/dist/editor/ui/PublishReadinessSummary.js.map +1 -0
  300. package/dist/editor/ui/TemplateSelectorDialog.js +27 -1
  301. package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -1
  302. package/dist/editor/ui/publishReadiness.d.ts +85 -0
  303. package/dist/editor/ui/publishReadiness.js +251 -0
  304. package/dist/editor/ui/publishReadiness.js.map +1 -0
  305. package/dist/editor/ui/usePublishingItem.d.ts +8 -0
  306. package/dist/editor/ui/usePublishingItem.js +47 -0
  307. package/dist/editor/ui/usePublishingItem.js.map +1 -0
  308. package/dist/editor/utils/linkDisplay.d.ts +12 -0
  309. package/dist/editor/utils/linkDisplay.js +23 -0
  310. package/dist/editor/utils/linkDisplay.js.map +1 -0
  311. package/dist/editor/views/ItemEditor.js +44 -27
  312. package/dist/editor/views/ItemEditor.js.map +1 -1
  313. package/dist/index.d.ts +9 -1
  314. package/dist/index.js +8 -1
  315. package/dist/index.js.map +1 -1
  316. package/dist/lib/viewportClip.d.ts +18 -0
  317. package/dist/lib/viewportClip.js +22 -0
  318. package/dist/lib/viewportClip.js.map +1 -0
  319. package/dist/revision.d.ts +2 -2
  320. package/dist/revision.js +2 -2
  321. package/dist/setup/wizard/steps/ImportModelDialog.js +238 -176
  322. package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
  323. package/dist/task-board/components/ProjectSettingsDialog.js +4 -1
  324. package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
  325. package/dist/tour/Tour.d.ts +10 -2
  326. package/dist/tour/Tour.js +136 -31
  327. package/dist/tour/Tour.js.map +1 -1
  328. package/dist/tour/default-tour.js +5 -16
  329. package/dist/tour/default-tour.js.map +1 -1
  330. package/dist/tour/preview-tour.js +1 -1
  331. package/dist/tour/preview-tour.js.map +1 -1
  332. package/dist/tour/sandbox-tour.js +4 -3
  333. package/dist/tour/sandbox-tour.js.map +1 -1
  334. package/dist/tour/tour-utils.d.ts +6 -0
  335. package/dist/tour/tour-utils.js +10 -0
  336. package/dist/tour/tour-utils.js.map +1 -1
  337. package/dist/types.d.ts +7 -0
  338. package/package.json +1 -1
  339. package/styles.css +6 -1
@@ -740,8 +740,11 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
740
740
  // moved into useWorkbox
741
741
  // Initialize tour state from URL parameter to survive navigation/remounts
742
742
  // Memoize to avoid triggering Router state updates during render
743
- const tourRestoredFromUrl = useMemo(() => Boolean(configuration.activeTour) &&
744
- searchParams.get("tour") === "active", [configuration.activeTour, searchParams]);
743
+ const tourRestoredFromUrl = useMemo(() => {
744
+ const tour = searchParams.get("tour");
745
+ return (Boolean(configuration.activeTour) &&
746
+ (tour === "active" || tour === configuration.activeTour));
747
+ }, [configuration.activeTour, searchParams]);
745
748
  const [isTourActive, setIsTourActive] = useState(tourRestoredFromUrl);
746
749
  // Track if tour was restored from URL to skip prepareAction on initial render
747
750
  const tourRestoredRef = useRef(tourRestoredFromUrl);
@@ -1400,7 +1403,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1400
1403
  // Persist tour state to URL so it survives navigation/remounts
1401
1404
  // Use history.replaceState instead of router.replace to avoid triggering React navigation
1402
1405
  const params = new URLSearchParams(window.location.search);
1403
- params.set("tour", "active");
1406
+ params.set("tour", configuration.activeTour);
1404
1407
  const newUrl = `${window.location.pathname}?${params.toString()}`;
1405
1408
  window.history.replaceState(getCurrentHistoryState(), "", newUrl);
1406
1409
  }, [configuration.activeTour, setIsTourActive]);
@@ -1876,42 +1879,30 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1876
1879
  };
1877
1880
  }, []);
1878
1881
  const media = useMediaSelector();
1882
+ const canStartTour = useMemo(() => searchParams.get("noTour") === null &&
1883
+ startupChecks.state === "complete" &&
1884
+ !startupChecks.hasBlockingIssues &&
1885
+ !(viewName === "settings" && searchParams.get("ccpanel") === "status") &&
1886
+ Boolean(configuration.activeTour), [
1887
+ configuration.activeTour,
1888
+ searchParams,
1889
+ startupChecks.hasBlockingIssues,
1890
+ startupChecks.state,
1891
+ viewName,
1892
+ ]);
1893
+ const sandboxTourShown = configuration.activeTour === "sandbox" &&
1894
+ Boolean(localStorageService.getString("editor.tourShown.sandbox"));
1879
1895
  useEffect(() => {
1880
- // Suppress auto-start tour when `noTour` query parameter is present
1881
- if (searchParams.get("noTour") !== null) {
1882
- return;
1883
- }
1884
- // Don't start tour when there are setup errors (user is or will be on system status page)
1885
- if (startupChecks.state === "complete" && startupChecks.hasBlockingIssues) {
1886
- return;
1887
- }
1888
- // Don't start tour when already on settings system status page
1889
- if (viewName === "settings" && searchParams.get("ccpanel") === "status") {
1890
- return;
1891
- }
1892
- // Wait for startup checks so we know whether we'll redirect to status
1893
- if (startupChecks.state !== "complete") {
1896
+ if (!canStartTour || showSandboxWelcome)
1894
1897
  return;
1895
- }
1896
1898
  const tour = configuration.activeTour;
1897
- if (!tour) {
1898
- return;
1899
- }
1900
1899
  const key = tour === "default" ? "editor.tourShown" : "editor.tourShown." + tour;
1901
1900
  const tourShown = localStorageService.getString(key);
1902
1901
  if (!tourShown) {
1903
1902
  startTour();
1904
1903
  localStorageService.setString(key, "true");
1905
1904
  }
1906
- }, [
1907
- user,
1908
- startupChecks.state,
1909
- startupChecks.hasBlockingIssues,
1910
- viewName,
1911
- searchParams,
1912
- configuration.activeTour,
1913
- startTour,
1914
- ]);
1905
+ }, [canStartTour, configuration.activeTour, showSandboxWelcome, startTour]);
1915
1906
  // WebSocket initialization is performed after messageHandler is defined
1916
1907
  // Defer URL sync until loadItem is defined below
1917
1908
  // Mark end of initial load phase
@@ -4864,732 +4855,747 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4864
4855
  };
4865
4856
  }
4866
4857
  const factoriesRef = globalThis.__editorContextFactoriesRef;
4867
- const editContext = useMemo(() => ({
4868
- operations: operationsContext.ops,
4869
- itemsRepository,
4870
- configuration,
4871
- updateUrl,
4872
- openSplashScreen: () => {
4873
- const currentParams = new URLSearchParams(window.location.search);
4874
- const isAlreadyOnHome = workspaceId === "home" &&
4875
- (!currentParams.get("workspace") ||
4876
- currentParams.get("workspace") === "home");
4877
- if (isAlreadyOnHome) {
4878
- // Already on home workspace, no need to navigate - this prevents reloading the tour
4879
- return;
4880
- }
4881
- // Ensure we actually land on the home workspace (not just change the URL).
4882
- // This is especially important when called from the tour, where the current workspace
4883
- // might be the editor and URL-only navigation would get "corrected" back.
4884
- try {
4885
- switchWorkspace("home", {
4886
- skipConfirmation: true,
4887
- skipNavigationHistory: true,
4888
- });
4889
- }
4890
- catch { }
4891
- const preservedParams = new URLSearchParams();
4892
- if (currentParams.get("fullscreen") === "true") {
4893
- preservedParams.set("fullscreen", "true");
4894
- }
4895
- // Preserve tour state so the tour survives navigation
4896
- if (currentParams.get("tour") === "active") {
4897
- preservedParams.set("tour", "active");
4898
- }
4899
- const queryString = preservedParams.toString();
4900
- // Use the current Next.js pathname so this works correctly with or without
4901
- // a configured basePath (e.g. basePath="/parhelia" in the static export).
4902
- // Avoid hard-coding "/parhelia" here because Next will automatically
4903
- // prepend the basePath when navigating.
4904
- const basePath = pathname || "/";
4905
- const newUrl = queryString ? `${basePath}?${queryString}` : basePath;
4906
- router.push(newUrl, { scroll: false });
4907
- },
4908
- item: item || page?.item,
4909
- itemLanguages,
4910
- itemVersions,
4911
- isLoadingVersions,
4912
- loadItemVersions,
4913
- sessionId: sessionId,
4914
- readonly: isReadOnly,
4915
- getSelection: () => selectionRef.current,
4916
- select: (ids) => {
4917
- // Re-selecting the same components is a no-op: without this bail a
4918
- // fresh array identity re-renders every selection consumer.
4919
- const current = selectionRef.current;
4920
- if (ids.length === current.length &&
4921
- ids.every((id, index) => id === current[index])) {
4922
- perfTraceStep("shell:setSelection-bailed (unchanged)", { ids });
4923
- return;
4924
- }
4925
- perfTraceStep("shell:setSelection-state-update", { ids });
4926
- setSelection(ids);
4927
- },
4928
- selectWithoutAutoScroll,
4929
- consumeNextSelectionAutoScrollSuppression,
4930
- consumeNextFocusedFieldAutoScrollSuppression,
4931
- contentTreeSelection,
4932
- setContentTreeSelection,
4933
- selectedForInsertion,
4934
- setSelectedForInsertion,
4935
- dragObject,
4936
- getDragObject: () => dragObjectRef.current,
4937
- clipboard,
4938
- setClipboard,
4939
- workboxItems,
4940
- isWorkboxLoading,
4941
- refreshWorkbox,
4942
- requestRefresh,
4943
- refreshCompletedFlag,
4944
- openCreatePageDialog: () => {
4945
- const current = new URLSearchParams(searchParams.toString());
4946
- current.delete("version");
4947
- current.delete("itemid");
4948
- current.delete("workspace"); // Clear workspace
4949
- current.set("create", "1");
4950
- const newUrl = `${pathname}?${current.toString()}`;
4951
- const oldUrl = `${pathname}?${searchParams.toString()}`;
4952
- router.push(newUrl, { scroll: false });
4953
- },
4954
- selectMedia: media.selectMedia,
4955
- showToast: (message) => {
4956
- // Ensure only strings are passed to toast to prevent accidental JSON display
4957
- if (typeof message === "string") {
4958
- toast(message);
4959
- }
4960
- else {
4961
- console.warn("showToast called with non-string value:", message);
4962
- toast("An operation occurred");
4963
- }
4964
- },
4965
- scrollIntoView,
4966
- setScrollIntoView,
4967
- focusedField,
4968
- setFocusedField: setFocusedFieldWithLock,
4969
- getComponentCommands: async (components, providerContext) => {
4970
- return await getComponentCommands(components, editContext, providerContext);
4971
- },
4972
- dragStart: (nextDragObject) => {
4973
- // A drag supersedes any unresolved scroll request (e.g. a comment
4974
- // target still waiting for geometry). Left pending, it would replay
4975
- // against the post-drop refresh and yank the canvas to a stale spot.
4976
- setScrollIntoView(undefined);
4977
- dragObjectRef.current = nextDragObject;
4978
- setDragObject(nextDragObject);
4979
- },
4980
- dragEnd: () => {
4981
- dragObjectRef.current = undefined;
4982
- setDragObject(undefined);
4983
- },
4984
- droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption, spotPosition, color) => {
4985
- const droppedDragObject = dragObjectRef.current;
4986
- if ((!droppedDragObject && !insertOption) || !page) {
4987
- return { committed: false };
4988
- }
4989
- dragObjectRef.current = undefined;
4990
- setDragObject(undefined);
4991
- const placeholderKeyComponents = placeholderKey.split("_");
4992
- const parentId = placeholderKeyComponents.length === 1
4993
- ? undefined
4994
- : placeholderKeyComponents[1];
4995
- // Selection is left alone at drop. The server response's focus id
4996
- // selects the moved/added component (executeEditOperation); selecting
4997
- // the drop target's parent here made the single-selection frame
4998
- // FLIP-animate component -> parent -> component around every drop.
4999
- let op;
5000
- // A placeholder is rendered from this page model, so its insertion
5001
- // must target the same item. The shell-level descriptor can briefly
5002
- // lag while slots or a newly created page settle; using it here could
5003
- // either discard a valid click or write the component to another page.
5004
- const dropTargetDescriptor = page.item.descriptor;
5005
- let insertionSequence;
5006
- if ((spotPosition || spotPositionElement) && spotPositionAnchor) {
5007
- insertionSequence = ++insertingSequenceRef.current;
5008
- setInserting({
5009
- position: spotPosition,
5010
- positionElement: spotPositionElement,
5011
- positionAnchor: spotPositionAnchor,
5012
- color,
5013
- });
5014
- }
5015
- let operationPromise;
5016
- if (insertOption) {
5017
- // Clear any selected component type for insertion once the component
5018
- // has been dropped into a placeholder. This ensures that insert mode
5019
- // can exit cleanly and the editor header updates from "Add Component"
5020
- // to the actual component name after the operation completes.
5021
- setSelectedForInsertion("");
5022
- operationPromise = operations.addComponent(insertOption.typeId, placeholderKey, index, dropTargetDescriptor, { showIndicator: false });
5023
- }
5024
- else if (droppedDragObject?.type == "template") {
5025
- operationPromise = operations.addComponent(droppedDragObject.typeId, placeholderKey, index, dropTargetDescriptor, { showIndicator: false });
5026
- }
5027
- else if (droppedDragObject?.type == "component" ||
5028
- (droppedDragObject?.type == "items" && droppedDragObject.items)) {
5029
- const parentComponent = parentId && page ? getComponentById(parentId, page) : null;
5030
- if (droppedDragObject.type == "items" && droppedDragObject.items) {
5031
- op = {
5032
- type: "link-component",
5033
- mainItem: page.item.descriptor,
5034
- parent: parentId && {
5035
- id: parentId,
5036
- language: page.item.descriptor.language,
5037
- version: page.item.descriptor.version,
5038
- name: parentComponent?.name,
5039
- },
5040
- placeholderKey,
5041
- placeholderIndex: index,
5042
- date: new Date().toISOString(),
5043
- id: uuid(),
5044
- linkedComponentItem: droppedDragObject.items[0],
5045
- title: "Link component",
5046
- };
4858
+ /**
4859
+ * Workspaces shown in the rail: not hidden, allowed by the server's workspace list (when provided) and,
4860
+ * for workspaces with a dynamic `visible` callback, visible for the given (complete) context.
4861
+ */
4862
+ const filterVisibleWorkspaces = (context) => (context.configuration.editor.workspaces ?? [])
4863
+ .filter((w) => {
4864
+ if (w.hidden)
4865
+ return false;
4866
+ if (w.visible && !w.visible(context))
4867
+ return false;
4868
+ // Filter by workspace settings from Sitecore (if provided)
4869
+ const serverWorkspaces = context.userInfo?.workspaces;
4870
+ if (serverWorkspaces && serverWorkspaces.length > 0) {
4871
+ return serverWorkspaces.some((ws) => ws.id === w.id);
4872
+ }
4873
+ return true;
4874
+ })
4875
+ .sort((a, b) => (a.sortOrder ?? 100) - (b.sortOrder ?? 100));
4876
+ const editContext = useMemo(() => {
4877
+ // Typed as the context (for contextual parameter types) plus the runtime-only extras the literal carries.
4878
+ const editContextValue = {
4879
+ operations: operationsContext.ops,
4880
+ itemsRepository,
4881
+ configuration,
4882
+ updateUrl,
4883
+ openSplashScreen: () => {
4884
+ const currentParams = new URLSearchParams(window.location.search);
4885
+ const isAlreadyOnHome = workspaceId === "home" &&
4886
+ (!currentParams.get("workspace") ||
4887
+ currentParams.get("workspace") === "home");
4888
+ if (isAlreadyOnHome) {
4889
+ // Already on home workspace, no need to navigate - this prevents reloading the tour
4890
+ return;
4891
+ }
4892
+ // Ensure we actually land on the home workspace (not just change the URL).
4893
+ // This is especially important when called from the tour, where the current workspace
4894
+ // might be the editor and URL-only navigation would get "corrected" back.
4895
+ try {
4896
+ switchWorkspace("home", {
4897
+ skipConfirmation: true,
4898
+ skipNavigationHistory: true,
4899
+ });
4900
+ }
4901
+ catch { }
4902
+ const preservedParams = new URLSearchParams();
4903
+ if (currentParams.get("fullscreen") === "true") {
4904
+ preservedParams.set("fullscreen", "true");
4905
+ }
4906
+ // Preserve tour state so the tour survives navigation
4907
+ const currentTour = currentParams.get("tour");
4908
+ if (currentTour) {
4909
+ preservedParams.set("tour", currentTour);
4910
+ }
4911
+ const queryString = preservedParams.toString();
4912
+ // Use the current Next.js pathname so this works correctly with or without
4913
+ // a configured basePath (e.g. basePath="/parhelia" in the static export).
4914
+ // Avoid hard-coding "/parhelia" here because Next will automatically
4915
+ // prepend the basePath when navigating.
4916
+ const basePath = pathname || "/";
4917
+ const newUrl = queryString ? `${basePath}?${queryString}` : basePath;
4918
+ router.push(newUrl, { scroll: false });
4919
+ },
4920
+ item: item || page?.item,
4921
+ itemLanguages,
4922
+ itemVersions,
4923
+ isLoadingVersions,
4924
+ loadItemVersions,
4925
+ sessionId: sessionId,
4926
+ readonly: isReadOnly,
4927
+ getSelection: () => selectionRef.current,
4928
+ select: (ids) => {
4929
+ // Re-selecting the same components is a no-op: without this bail a
4930
+ // fresh array identity re-renders every selection consumer.
4931
+ const current = selectionRef.current;
4932
+ if (ids.length === current.length &&
4933
+ ids.every((id, index) => id === current[index])) {
4934
+ perfTraceStep("shell:setSelection-bailed (unchanged)", { ids });
4935
+ return;
4936
+ }
4937
+ perfTraceStep("shell:setSelection-state-update", { ids });
4938
+ setSelection(ids);
4939
+ },
4940
+ selectWithoutAutoScroll,
4941
+ consumeNextSelectionAutoScrollSuppression,
4942
+ consumeNextFocusedFieldAutoScrollSuppression,
4943
+ contentTreeSelection,
4944
+ setContentTreeSelection,
4945
+ selectedForInsertion,
4946
+ setSelectedForInsertion,
4947
+ dragObject,
4948
+ getDragObject: () => dragObjectRef.current,
4949
+ clipboard,
4950
+ setClipboard,
4951
+ workboxItems,
4952
+ isWorkboxLoading,
4953
+ refreshWorkbox,
4954
+ requestRefresh,
4955
+ refreshCompletedFlag,
4956
+ openCreatePageDialog: () => {
4957
+ const current = new URLSearchParams(searchParams.toString());
4958
+ current.delete("version");
4959
+ current.delete("itemid");
4960
+ current.delete("workspace"); // Clear workspace
4961
+ current.set("create", "1");
4962
+ const newUrl = `${pathname}?${current.toString()}`;
4963
+ const oldUrl = `${pathname}?${searchParams.toString()}`;
4964
+ router.push(newUrl, { scroll: false });
4965
+ },
4966
+ selectMedia: media.selectMedia,
4967
+ showToast: (message) => {
4968
+ // Ensure only strings are passed to toast to prevent accidental JSON display
4969
+ if (typeof message === "string") {
4970
+ toast(message);
5047
4971
  }
5048
4972
  else {
5049
- const componentIds = droppedDragObject.components?.map((c) => c.id) ?? [];
5050
- if (componentIds.length > 0) {
4973
+ console.warn("showToast called with non-string value:", message);
4974
+ toast("An operation occurred");
4975
+ }
4976
+ },
4977
+ scrollIntoView,
4978
+ setScrollIntoView,
4979
+ focusedField,
4980
+ setFocusedField: setFocusedFieldWithLock,
4981
+ getComponentCommands: async (components, providerContext) => {
4982
+ return await getComponentCommands(components, editContext, providerContext);
4983
+ },
4984
+ dragStart: (nextDragObject) => {
4985
+ // A drag supersedes any unresolved scroll request (e.g. a comment
4986
+ // target still waiting for geometry). Left pending, it would replay
4987
+ // against the post-drop refresh and yank the canvas to a stale spot.
4988
+ setScrollIntoView(undefined);
4989
+ dragObjectRef.current = nextDragObject;
4990
+ setDragObject(nextDragObject);
4991
+ },
4992
+ dragEnd: () => {
4993
+ dragObjectRef.current = undefined;
4994
+ setDragObject(undefined);
4995
+ },
4996
+ droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption, spotPosition, color) => {
4997
+ const droppedDragObject = dragObjectRef.current;
4998
+ if ((!droppedDragObject && !insertOption) || !page) {
4999
+ return { committed: false };
5000
+ }
5001
+ dragObjectRef.current = undefined;
5002
+ setDragObject(undefined);
5003
+ const placeholderKeyComponents = placeholderKey.split("_");
5004
+ const parentId = placeholderKeyComponents.length === 1
5005
+ ? undefined
5006
+ : placeholderKeyComponents[1];
5007
+ // Selection is left alone at drop. The server response's focus id
5008
+ // selects the moved/added component (executeEditOperation); selecting
5009
+ // the drop target's parent here made the single-selection frame
5010
+ // FLIP-animate component -> parent -> component around every drop.
5011
+ let op;
5012
+ // A placeholder is rendered from this page model, so its insertion
5013
+ // must target the same item. The shell-level descriptor can briefly
5014
+ // lag while slots or a newly created page settle; using it here could
5015
+ // either discard a valid click or write the component to another page.
5016
+ const dropTargetDescriptor = page.item.descriptor;
5017
+ let insertionSequence;
5018
+ if ((spotPosition || spotPositionElement) && spotPositionAnchor) {
5019
+ insertionSequence = ++insertingSequenceRef.current;
5020
+ setInserting({
5021
+ position: spotPosition,
5022
+ positionElement: spotPositionElement,
5023
+ positionAnchor: spotPositionAnchor,
5024
+ color,
5025
+ });
5026
+ }
5027
+ let operationPromise;
5028
+ if (insertOption) {
5029
+ // Clear any selected component type for insertion once the component
5030
+ // has been dropped into a placeholder. This ensures that insert mode
5031
+ // can exit cleanly and the editor header updates from "Add Component"
5032
+ // to the actual component name after the operation completes.
5033
+ setSelectedForInsertion("");
5034
+ operationPromise = operations.addComponent(insertOption.typeId, placeholderKey, index, dropTargetDescriptor, { showIndicator: false });
5035
+ }
5036
+ else if (droppedDragObject?.type == "template") {
5037
+ operationPromise = operations.addComponent(droppedDragObject.typeId, placeholderKey, index, dropTargetDescriptor, { showIndicator: false });
5038
+ }
5039
+ else if (droppedDragObject?.type == "component" ||
5040
+ (droppedDragObject?.type == "items" && droppedDragObject.items)) {
5041
+ const parentComponent = parentId && page ? getComponentById(parentId, page) : null;
5042
+ if (droppedDragObject.type == "items" && droppedDragObject.items) {
5051
5043
  op = {
5052
- type: "move-component",
5044
+ type: "link-component",
5053
5045
  mainItem: page.item.descriptor,
5054
5046
  parent: parentId && {
5055
5047
  id: parentId,
5056
5048
  language: page.item.descriptor.language,
5057
5049
  version: page.item.descriptor.version,
5050
+ name: parentComponent?.name,
5058
5051
  },
5059
5052
  placeholderKey,
5060
5053
  placeholderIndex: index,
5061
- componentIds,
5062
5054
  date: new Date().toISOString(),
5063
5055
  id: uuid(),
5064
- title: "Move component",
5056
+ linkedComponentItem: droppedDragObject.items[0],
5057
+ title: "Link component",
5065
5058
  };
5066
5059
  }
5060
+ else {
5061
+ const componentIds = droppedDragObject.components?.map((c) => c.id) ?? [];
5062
+ if (componentIds.length > 0) {
5063
+ op = {
5064
+ type: "move-component",
5065
+ mainItem: page.item.descriptor,
5066
+ parent: parentId && {
5067
+ id: parentId,
5068
+ language: page.item.descriptor.language,
5069
+ version: page.item.descriptor.version,
5070
+ },
5071
+ placeholderKey,
5072
+ placeholderIndex: index,
5073
+ componentIds,
5074
+ date: new Date().toISOString(),
5075
+ id: uuid(),
5076
+ title: "Move component",
5077
+ };
5078
+ }
5079
+ }
5067
5080
  }
5068
- }
5069
- if (op)
5070
- operationPromise = operations.executeEditOperation(op);
5071
- if (!operationPromise) {
5072
- if (insertionSequence !== undefined &&
5073
- insertingSequenceRef.current === insertionSequence) {
5074
- setInserting(undefined);
5075
- }
5076
- return { committed: false };
5077
- }
5078
- let operationFailed = false;
5079
- try {
5080
- // executeOp resolves (instead of throwing) with a failed status when
5081
- // the server rejects the operation — no refresh follows then.
5082
- const result = (await operationPromise);
5083
- operationFailed = result?.executionStatus === "failed";
5084
- }
5085
- catch (err) {
5086
- operationFailed = true;
5087
- console.error("Failed to drop component in placeholder", err);
5088
- }
5089
- finally {
5090
- if (insertionSequence !== undefined &&
5091
- insertingSequenceRef.current === insertionSequence) {
5092
- if (operationFailed) {
5081
+ if (op)
5082
+ operationPromise = operations.executeEditOperation(op);
5083
+ if (!operationPromise) {
5084
+ if (insertionSequence !== undefined &&
5085
+ insertingSequenceRef.current === insertionSequence) {
5093
5086
  setInserting(undefined);
5094
5087
  }
5095
- else {
5096
- // The server accepted the drop; the canvas has not repainted
5097
- // yet. Hold the indicator until the refresh lands so it stops
5098
- // when the component actually appears, not seconds earlier.
5099
- holdInsertingUntilCanvasRefresh(insertionSequence);
5100
- }
5088
+ return { committed: false };
5101
5089
  }
5102
- }
5103
- return { committed: !operationFailed };
5104
- },
5105
- page,
5106
- triggerFieldAction: async (fieldDescriptor, actionButton, parameters, event) => {
5107
- const field = await itemsRepository.getField(fieldDescriptor);
5108
- if (!field)
5109
- return;
5110
- const op = {
5111
- field: fieldDescriptor,
5112
- // actionButton,
5113
- label: actionButton.label,
5114
- state: "running",
5115
- };
5116
- const fieldItem = fieldDescriptor.item;
5117
- if ("clientAction" in actionButton) {
5118
- await actionButton.clientAction({
5119
- field,
5120
- editContext,
5121
- event,
5122
- //dialogContext,
5123
- });
5124
- }
5125
- if (actionButton.action) {
5126
- setActiveFieldActions((prevFieldActions) => {
5127
- const isSameField = (x) => x.field.fieldId == fieldDescriptor.fieldId &&
5128
- x.field.item.id == fieldItem.id &&
5129
- x.field.item.language == fieldItem.language &&
5130
- x.field.item.version == fieldItem.version;
5131
- const existing = prevFieldActions.find(isSameField);
5132
- // Preserve any existing state/message (e.g., an early websocket error)
5133
- // to avoid overwriting it with a stale "running" state
5134
- const mergedOp = existing
5135
- ? {
5136
- ...op,
5137
- state: existing.state,
5138
- message: existing.message,
5139
- label: existing.label ?? op.label,
5140
- }
5141
- : op;
5142
- return [
5143
- ...prevFieldActions.filter((x) => !isSameField(x)),
5144
- mergedOp,
5145
- ];
5146
- });
5090
+ let operationFailed = false;
5147
5091
  try {
5148
- await executeFieldServerAction(fieldDescriptor.item, fieldDescriptor.fieldId, item.descriptor, actionButton.action, editContext.sessionId, selectedRange?.text || "", parameters || {}, (data) => {
5149
- // Update progress message if available
5150
- if (data?.responseText) {
5151
- op.message = data.responseText;
5152
- setActiveFieldActions((prevFieldActions) => [
5153
- ...prevFieldActions,
5154
- ]);
5092
+ // executeOp resolves (instead of throwing) with a failed status when
5093
+ // the server rejects the operation — no refresh follows then.
5094
+ const result = (await operationPromise);
5095
+ operationFailed = result?.executionStatus === "failed";
5096
+ }
5097
+ catch (err) {
5098
+ operationFailed = true;
5099
+ console.error("Failed to drop component in placeholder", err);
5100
+ }
5101
+ finally {
5102
+ if (insertionSequence !== undefined &&
5103
+ insertingSequenceRef.current === insertionSequence) {
5104
+ if (operationFailed) {
5105
+ setInserting(undefined);
5155
5106
  }
5156
- // Handle error state from the server response
5157
- if (data?.state === "Error" || data?.state === "failed") {
5158
- op.state = "error";
5159
- op.message = data.errorMessage || "Field action failed";
5160
- setActiveFieldActions((prevFieldActions) => [
5161
- ...prevFieldActions,
5162
- ]);
5107
+ else {
5108
+ // The server accepted the drop; the canvas has not repainted
5109
+ // yet. Hold the indicator until the refresh lands so it stops
5110
+ // when the component actually appears, not seconds earlier.
5111
+ holdInsertingUntilCanvasRefresh(insertionSequence);
5163
5112
  }
5113
+ }
5114
+ }
5115
+ return { committed: !operationFailed };
5116
+ },
5117
+ page,
5118
+ triggerFieldAction: async (fieldDescriptor, actionButton, parameters, event) => {
5119
+ const field = await itemsRepository.getField(fieldDescriptor);
5120
+ if (!field)
5121
+ return;
5122
+ const op = {
5123
+ field: fieldDescriptor,
5124
+ // actionButton,
5125
+ label: actionButton.label,
5126
+ state: "running",
5127
+ };
5128
+ const fieldItem = fieldDescriptor.item;
5129
+ if ("clientAction" in actionButton) {
5130
+ await actionButton.clientAction({
5131
+ field,
5132
+ editContext,
5133
+ event,
5134
+ //dialogContext,
5164
5135
  });
5165
- itemsRepository.refreshItems([fieldDescriptor.item]);
5166
- // Only mark as success if no websocket error has been reported
5167
- if (op.state === "running") {
5168
- op.state = "success";
5169
- // Auto-dismiss successful actions after a brief delay
5170
- setTimeout(() => {
5171
- setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5172
- x.field.item.id === fieldDescriptor.item.id &&
5173
- x.field.item.language ===
5174
- fieldDescriptor.item.language &&
5175
- x.field.item.version === fieldDescriptor.item.version &&
5176
- x.state === "success")));
5177
- }, 500);
5136
+ }
5137
+ if (actionButton.action) {
5138
+ setActiveFieldActions((prevFieldActions) => {
5139
+ const isSameField = (x) => x.field.fieldId == fieldDescriptor.fieldId &&
5140
+ x.field.item.id == fieldItem.id &&
5141
+ x.field.item.language == fieldItem.language &&
5142
+ x.field.item.version == fieldItem.version;
5143
+ const existing = prevFieldActions.find(isSameField);
5144
+ // Preserve any existing state/message (e.g., an early websocket error)
5145
+ // to avoid overwriting it with a stale "running" state
5146
+ const mergedOp = existing
5147
+ ? {
5148
+ ...op,
5149
+ state: existing.state,
5150
+ message: existing.message,
5151
+ label: existing.label ?? op.label,
5152
+ }
5153
+ : op;
5154
+ return [
5155
+ ...prevFieldActions.filter((x) => !isSameField(x)),
5156
+ mergedOp,
5157
+ ];
5158
+ });
5159
+ try {
5160
+ await executeFieldServerAction(fieldDescriptor.item, fieldDescriptor.fieldId, item.descriptor, actionButton.action, editContext.sessionId, selectedRange?.text || "", parameters || {}, (data) => {
5161
+ // Update progress message if available
5162
+ if (data?.responseText) {
5163
+ op.message = data.responseText;
5164
+ setActiveFieldActions((prevFieldActions) => [
5165
+ ...prevFieldActions,
5166
+ ]);
5167
+ }
5168
+ // Handle error state from the server response
5169
+ if (data?.state === "Error" || data?.state === "failed") {
5170
+ op.state = "error";
5171
+ op.message = data.errorMessage || "Field action failed";
5172
+ setActiveFieldActions((prevFieldActions) => [
5173
+ ...prevFieldActions,
5174
+ ]);
5175
+ }
5176
+ });
5177
+ itemsRepository.refreshItems([fieldDescriptor.item]);
5178
+ // Only mark as success if no websocket error has been reported
5179
+ if (op.state === "running") {
5180
+ op.state = "success";
5181
+ // Auto-dismiss successful actions after a brief delay
5182
+ setTimeout(() => {
5183
+ setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5184
+ x.field.item.id === fieldDescriptor.item.id &&
5185
+ x.field.item.language ===
5186
+ fieldDescriptor.item.language &&
5187
+ x.field.item.version === fieldDescriptor.item.version &&
5188
+ x.state === "success")));
5189
+ }, 500);
5190
+ }
5191
+ else if (op.state === "error") {
5192
+ // Auto-dismiss error after a longer delay (matching the catch block)
5193
+ setTimeout(() => {
5194
+ setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5195
+ x.field.item.id === fieldDescriptor.item.id &&
5196
+ x.field.item.language ===
5197
+ fieldDescriptor.item.language &&
5198
+ x.field.item.version === fieldDescriptor.item.version)));
5199
+ }, 3000);
5200
+ }
5201
+ requestRefresh("immediate");
5178
5202
  }
5179
- else if (op.state === "error") {
5180
- // Auto-dismiss error after a longer delay (matching the catch block)
5203
+ catch (error) {
5204
+ console.error("Field action failed", error);
5205
+ // Mark as failed and show error message
5206
+ op.state = "error";
5207
+ op.message =
5208
+ error instanceof Error ? error.message : "Field action failed";
5209
+ // Update the field action state to show error
5210
+ setActiveFieldActions((prevFieldActions) => {
5211
+ const isSameField = (x) => x.field.fieldId == fieldDescriptor.fieldId &&
5212
+ x.field.item.id == fieldItem.id &&
5213
+ x.field.item.language == fieldItem.language &&
5214
+ x.field.item.version == fieldItem.version;
5215
+ return [...prevFieldActions.filter((x) => !isSameField(x)), op];
5216
+ });
5217
+ // Auto-dismiss error after a longer delay
5181
5218
  setTimeout(() => {
5182
5219
  setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5183
5220
  x.field.item.id === fieldDescriptor.item.id &&
5184
- x.field.item.language ===
5185
- fieldDescriptor.item.language &&
5221
+ x.field.item.language === fieldDescriptor.item.language &&
5186
5222
  x.field.item.version === fieldDescriptor.item.version)));
5187
5223
  }, 3000);
5188
5224
  }
5189
- requestRefresh("immediate");
5190
5225
  }
5191
- catch (error) {
5192
- console.error("Field action failed", error);
5193
- // Mark as failed and show error message
5194
- op.state = "error";
5195
- op.message =
5196
- error instanceof Error ? error.message : "Field action failed";
5197
- // Update the field action state to show error
5198
- setActiveFieldActions((prevFieldActions) => {
5199
- const isSameField = (x) => x.field.fieldId == fieldDescriptor.fieldId &&
5200
- x.field.item.id == fieldItem.id &&
5201
- x.field.item.language == fieldItem.language &&
5202
- x.field.item.version == fieldItem.version;
5203
- return [...prevFieldActions.filter((x) => !isSameField(x)), op];
5204
- });
5205
- // Auto-dismiss error after a longer delay
5206
- setTimeout(() => {
5207
- setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5208
- x.field.item.id === fieldDescriptor.item.id &&
5209
- x.field.item.language === fieldDescriptor.item.language &&
5210
- x.field.item.version === fieldDescriptor.item.version)));
5211
- }, 3000);
5226
+ },
5227
+ dismissFieldAction: (fieldDescriptor) => {
5228
+ setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5229
+ x.field.item.id === fieldDescriptor.item.id &&
5230
+ x.field.item.language === fieldDescriptor.item.language &&
5231
+ x.field.item.version === fieldDescriptor.item.version)));
5232
+ },
5233
+ addFieldAction: (action) => {
5234
+ setActiveFieldActions((prev) => {
5235
+ const isSameField = (x) => x.field.fieldId === action.field.fieldId &&
5236
+ x.field.item.id === action.field.item.id &&
5237
+ x.field.item.language === action.field.item.language &&
5238
+ x.field.item.version === action.field.item.version;
5239
+ return [...prev.filter((x) => !isSameField(x)), action];
5240
+ });
5241
+ },
5242
+ updateFieldAction: (fieldDescriptor, updates) => {
5243
+ setActiveFieldActions((prev) => prev.map((x) => x.field.fieldId === fieldDescriptor.fieldId &&
5244
+ x.field.item.id === fieldDescriptor.item.id &&
5245
+ x.field.item.language === fieldDescriptor.item.language &&
5246
+ x.field.item.version === fieldDescriptor.item.version
5247
+ ? { ...x, ...updates }
5248
+ : x));
5249
+ },
5250
+ activeFieldActions,
5251
+ showContextMenu: (event, items, options) => {
5252
+ contextMenuRef.current?.show(event, items);
5253
+ setContextMenuSource(options?.source);
5254
+ setCurrentOverlay("context-menu");
5255
+ },
5256
+ updateContextMenu: (items) => {
5257
+ contextMenuRef.current?.update(items);
5258
+ },
5259
+ showFieldEditorPopup: (fields, sections, ev) => {
5260
+ setCurrentOverlay("fields");
5261
+ fieldEditorPopupRef.current?.show(fields, sections, ev);
5262
+ },
5263
+ inserting,
5264
+ removingComponentIds,
5265
+ validating,
5266
+ validationResult,
5267
+ loadItem,
5268
+ editHistory: editHistory,
5269
+ historyMode,
5270
+ setHistoryMode,
5271
+ showOnlyMyChanges,
5272
+ setShowOnlyMyChanges,
5273
+ filterByCurrentLanguage,
5274
+ setFilterByCurrentLanguage,
5275
+ historySearchQuery,
5276
+ setHistorySearchQuery,
5277
+ refreshHistory,
5278
+ isRefreshing,
5279
+ isHistoryLoading,
5280
+ canLoadMoreHistory,
5281
+ isHistoryLoadingMore,
5282
+ loadMoreHistory,
5283
+ activeSessions,
5284
+ remoteCarets,
5285
+ unlockField: async () => {
5286
+ setLockedField(undefined); // Clear client-side lock state
5287
+ await releaseFieldLocks(sessionId);
5288
+ },
5289
+ isCommandDisabled: ({ command, data, }) => {
5290
+ const props = {
5291
+ editContext,
5292
+ pathname,
5293
+ router,
5294
+ searchParams,
5295
+ data,
5296
+ openDialog,
5297
+ };
5298
+ return command.disabled(props);
5299
+ },
5300
+ executeCommand,
5301
+ // Workspace state
5302
+ workspace: currentWorkspace,
5303
+ // Filled in below: a workspace's dynamic `visible` callback receives the finished context object.
5304
+ // Evaluating it inside this literal would read `editContext` before its initialization.
5305
+ visibleWorkspaces: [],
5306
+ workspaceId,
5307
+ previousWorkspaceId,
5308
+ switchWorkspace,
5309
+ // Sidebar state
5310
+ availableSidebars: getSidebarsForWorkspace(workspaceId),
5311
+ openSidebars,
5312
+ pinnedSidebars,
5313
+ lockedSidebars,
5314
+ sidebarStacks,
5315
+ toggleSidebar,
5316
+ openSidebar,
5317
+ toggleSidebarPin,
5318
+ toggleSidebarLock,
5319
+ stackSidebar,
5320
+ moveSidebarToColumn,
5321
+ unstackSidebar,
5322
+ reorderSidebarInStack,
5323
+ reorderPinnedSidebars,
5324
+ reorderOpenSidebars,
5325
+ getResolvedSidebar,
5326
+ compareMode,
5327
+ setCompareMode,
5328
+ fullscreen,
5329
+ setFullscreen,
5330
+ componentDesignerComponent,
5331
+ setComponentDesignerComponent,
5332
+ componentDesignerRendering,
5333
+ setComponentDesignerRendering,
5334
+ insertMode,
5335
+ setInsertMode,
5336
+ currentOverlay,
5337
+ contextMenuSource,
5338
+ setCurrentOverlay,
5339
+ lockedField,
5340
+ timings,
5341
+ setTimings,
5342
+ selectedRange,
5343
+ setSelectedRange,
5344
+ replaceSelectedText,
5345
+ insertTextAtCursor,
5346
+ confirm: (props) => {
5347
+ confirmationDialogRef.current?.confirm(props);
5348
+ },
5349
+ showMessageDialog: (props) => {
5350
+ confirmationDialogRef.current?.confirm({
5351
+ header: props.header,
5352
+ message: props.message,
5353
+ accept: () => { },
5354
+ acceptLabel: "Ok",
5355
+ });
5356
+ },
5357
+ showInfoToast,
5358
+ showErrorToast,
5359
+ browseHistory,
5360
+ setCenterPanelView,
5361
+ handleKeyDown,
5362
+ startTour,
5363
+ addSocketMessageListener,
5364
+ sendSocketMessage,
5365
+ socketConnectionVersion,
5366
+ socketDiagnostics,
5367
+ currentItemDescriptor,
5368
+ editorSlots,
5369
+ activeSlotId,
5370
+ slotContexts,
5371
+ registerSlotContext,
5372
+ unregisterSlotContext,
5373
+ getActiveSlotContext,
5374
+ getActiveSlotId,
5375
+ getFieldModificationStoreForSlot,
5376
+ closeEditorSlot,
5377
+ setActiveSlot,
5378
+ revision,
5379
+ fullReloadToken,
5380
+ notifyPageModelReady,
5381
+ pageModelReadyToken,
5382
+ selectedComment,
5383
+ setSelectedComment,
5384
+ selectedSuggestedEdit,
5385
+ setSelectedSuggestedEdit,
5386
+ comments,
5387
+ commentsLoaded,
5388
+ availableCommentTags,
5389
+ loadComments,
5390
+ loadSuggestedEdits,
5391
+ setComments,
5392
+ showComments,
5393
+ setShowComments,
5394
+ showResolvedComments,
5395
+ setShowResolvedComments,
5396
+ addComment: async (options) => {
5397
+ const descriptor = item?.descriptor;
5398
+ if (!descriptor)
5399
+ return;
5400
+ // Only keep a single empty draft comment at a time. Clicking
5401
+ // "add comment" again while an unsaved draft already exists should
5402
+ // focus that draft instead of stacking up more empty inputs.
5403
+ const existingDraft = comments.find((c) => c.isNew);
5404
+ if (existingDraft) {
5405
+ await activateCommentsModeForWriting("comment-add");
5406
+ setSelectedComment(existingDraft);
5407
+ setSelectedSuggestedEdit(undefined);
5408
+ return;
5212
5409
  }
5213
- }
5214
- },
5215
- dismissFieldAction: (fieldDescriptor) => {
5216
- setActiveFieldActions((prevFieldActions) => prevFieldActions.filter((x) => !(x.field.fieldId === fieldDescriptor.fieldId &&
5217
- x.field.item.id === fieldDescriptor.item.id &&
5218
- x.field.item.language === fieldDescriptor.item.language &&
5219
- x.field.item.version === fieldDescriptor.item.version)));
5220
- },
5221
- addFieldAction: (action) => {
5222
- setActiveFieldActions((prev) => {
5223
- const isSameField = (x) => x.field.fieldId === action.field.fieldId &&
5224
- x.field.item.id === action.field.item.id &&
5225
- x.field.item.language === action.field.item.language &&
5226
- x.field.item.version === action.field.item.version;
5227
- return [...prev.filter((x) => !isSameField(x)), action];
5228
- });
5229
- },
5230
- updateFieldAction: (fieldDescriptor, updates) => {
5231
- setActiveFieldActions((prev) => prev.map((x) => x.field.fieldId === fieldDescriptor.fieldId &&
5232
- x.field.item.id === fieldDescriptor.item.id &&
5233
- x.field.item.language === fieldDescriptor.item.language &&
5234
- x.field.item.version === fieldDescriptor.item.version
5235
- ? { ...x, ...updates }
5236
- : x));
5237
- },
5238
- activeFieldActions,
5239
- showContextMenu: (event, items, options) => {
5240
- contextMenuRef.current?.show(event, items);
5241
- setContextMenuSource(options?.source);
5242
- setCurrentOverlay("context-menu");
5243
- },
5244
- updateContextMenu: (items) => {
5245
- contextMenuRef.current?.update(items);
5246
- },
5247
- showFieldEditorPopup: (fields, sections, ev) => {
5248
- setCurrentOverlay("fields");
5249
- fieldEditorPopupRef.current?.show(fields, sections, ev);
5250
- },
5251
- inserting,
5252
- removingComponentIds,
5253
- validating,
5254
- validationResult,
5255
- loadItem,
5256
- editHistory: editHistory,
5257
- historyMode,
5258
- setHistoryMode,
5259
- showOnlyMyChanges,
5260
- setShowOnlyMyChanges,
5261
- filterByCurrentLanguage,
5262
- setFilterByCurrentLanguage,
5263
- historySearchQuery,
5264
- setHistorySearchQuery,
5265
- refreshHistory,
5266
- isRefreshing,
5267
- isHistoryLoading,
5268
- canLoadMoreHistory,
5269
- isHistoryLoadingMore,
5270
- loadMoreHistory,
5271
- activeSessions,
5272
- remoteCarets,
5273
- unlockField: async () => {
5274
- setLockedField(undefined); // Clear client-side lock state
5275
- await releaseFieldLocks(sessionId);
5276
- },
5277
- isCommandDisabled: ({ command, data, }) => {
5278
- const props = {
5279
- editContext,
5280
- pathname,
5281
- router,
5282
- searchParams,
5283
- data,
5284
- openDialog,
5285
- };
5286
- return command.disabled(props);
5287
- },
5288
- executeCommand,
5289
- // Workspace state
5290
- workspace: currentWorkspace,
5291
- visibleWorkspaces: (configuration.editor.workspaces ?? [])
5292
- .filter((w) => {
5293
- if (w.hidden)
5294
- return false;
5295
- if (w.visible && !w.visible(editContext))
5296
- return false;
5297
- // Filter by workspace settings from Sitecore (if provided)
5298
- if (userInfo.workspaces && userInfo.workspaces.length > 0) {
5299
- return userInfo.workspaces.some((ws) => ws.id === w.id);
5300
- }
5301
- return true;
5302
- })
5303
- .sort((a, b) => (a.sortOrder ?? 100) - (b.sortOrder ?? 100)),
5304
- workspaceId,
5305
- previousWorkspaceId,
5306
- switchWorkspace,
5307
- // Sidebar state
5308
- availableSidebars: getSidebarsForWorkspace(workspaceId),
5309
- openSidebars,
5310
- pinnedSidebars,
5311
- lockedSidebars,
5312
- sidebarStacks,
5313
- toggleSidebar,
5314
- openSidebar,
5315
- toggleSidebarPin,
5316
- toggleSidebarLock,
5317
- stackSidebar,
5318
- moveSidebarToColumn,
5319
- unstackSidebar,
5320
- reorderSidebarInStack,
5321
- reorderPinnedSidebars,
5322
- reorderOpenSidebars,
5323
- getResolvedSidebar,
5324
- compareMode,
5325
- setCompareMode,
5326
- fullscreen,
5327
- setFullscreen,
5328
- componentDesignerComponent,
5329
- setComponentDesignerComponent,
5330
- componentDesignerRendering,
5331
- setComponentDesignerRendering,
5332
- insertMode,
5333
- setInsertMode,
5334
- currentOverlay,
5335
- contextMenuSource,
5336
- setCurrentOverlay,
5337
- lockedField,
5338
- timings,
5339
- setTimings,
5340
- selectedRange,
5341
- setSelectedRange,
5342
- replaceSelectedText,
5343
- insertTextAtCursor,
5344
- confirm: (props) => {
5345
- confirmationDialogRef.current?.confirm(props);
5346
- },
5347
- showMessageDialog: (props) => {
5348
- confirmationDialogRef.current?.confirm({
5349
- header: props.header,
5350
- message: props.message,
5351
- accept: () => { },
5352
- acceptLabel: "Ok",
5353
- });
5354
- },
5355
- showInfoToast,
5356
- showErrorToast,
5357
- browseHistory,
5358
- setCenterPanelView,
5359
- handleKeyDown,
5360
- startTour,
5361
- addSocketMessageListener,
5362
- sendSocketMessage,
5363
- socketConnectionVersion,
5364
- socketDiagnostics,
5365
- currentItemDescriptor,
5366
- editorSlots,
5367
- activeSlotId,
5368
- slotContexts,
5369
- registerSlotContext,
5370
- unregisterSlotContext,
5371
- getActiveSlotContext,
5372
- getActiveSlotId,
5373
- getFieldModificationStoreForSlot,
5374
- closeEditorSlot,
5375
- setActiveSlot,
5376
- revision,
5377
- fullReloadToken,
5378
- notifyPageModelReady,
5379
- pageModelReadyToken,
5380
- selectedComment,
5381
- setSelectedComment,
5382
- selectedSuggestedEdit,
5383
- setSelectedSuggestedEdit,
5384
- comments,
5385
- commentsLoaded,
5386
- availableCommentTags,
5387
- loadComments,
5388
- loadSuggestedEdits,
5389
- setComments,
5390
- showComments,
5391
- setShowComments,
5392
- showResolvedComments,
5393
- setShowResolvedComments,
5394
- addComment: async (options) => {
5395
- const descriptor = item?.descriptor;
5396
- if (!descriptor)
5397
- return;
5398
- // Only keep a single empty draft comment at a time. Clicking
5399
- // "add comment" again while an unsaved draft already exists should
5400
- // focus that draft instead of stacking up more empty inputs.
5401
- const existingDraft = comments.find((c) => c.isNew);
5402
- if (existingDraft) {
5410
+ // Snapshot selection context up-front so switching views doesn't change what we comment on.
5411
+ const hintedFieldSnapshot = options?.field;
5412
+ const focusedFieldSnapshot = focusedFieldRef.current;
5413
+ const selectedRangeCandidate = isUsableTextSelectionRange(selectedRange)
5414
+ ? selectedRange
5415
+ : lastTextSelectionRangeRef.current;
5416
+ const selectedRangeSnapshot = !hintedFieldSnapshot ||
5417
+ selectionRangeMatchesField(selectedRangeCandidate, hintedFieldSnapshot)
5418
+ ? selectedRangeCandidate
5419
+ : undefined;
5420
+ const selectedRangeFieldSnapshot = isUsableTextSelectionRange(selectedRangeSnapshot)
5421
+ ? {
5422
+ fieldId: selectedRangeSnapshot.fieldId,
5423
+ item: {
5424
+ id: selectedRangeSnapshot.itemId,
5425
+ language: selectedRangeSnapshot.language || descriptor.language,
5426
+ version: typeof selectedRangeSnapshot.version === "number"
5427
+ ? selectedRangeSnapshot.version
5428
+ : descriptor.version,
5429
+ },
5430
+ }
5431
+ : undefined;
5432
+ const commentFieldSnapshot = selectedRangeFieldSnapshot ??
5433
+ hintedFieldSnapshot ??
5434
+ focusedFieldSnapshot;
5435
+ const itemId = commentFieldSnapshot?.item.id ||
5436
+ (selection.length > 0 ? selection[0] : undefined) ||
5437
+ descriptor.id;
5438
+ if (!itemId)
5439
+ return;
5440
+ // Ensure the promoted comments surface is active when adding a comment.
5403
5441
  await activateCommentsModeForWriting("comment-add");
5404
- setSelectedComment(existingDraft);
5405
- setSelectedSuggestedEdit(undefined);
5406
- return;
5407
- }
5408
- // Snapshot selection context up-front so switching views doesn't change what we comment on.
5409
- const hintedFieldSnapshot = options?.field;
5410
- const focusedFieldSnapshot = focusedFieldRef.current;
5411
- const selectedRangeCandidate = isUsableTextSelectionRange(selectedRange)
5412
- ? selectedRange
5413
- : lastTextSelectionRangeRef.current;
5414
- const selectedRangeSnapshot = !hintedFieldSnapshot ||
5415
- selectionRangeMatchesField(selectedRangeCandidate, hintedFieldSnapshot)
5416
- ? selectedRangeCandidate
5417
- : undefined;
5418
- const selectedRangeFieldSnapshot = isUsableTextSelectionRange(selectedRangeSnapshot)
5419
- ? {
5420
- fieldId: selectedRangeSnapshot.fieldId,
5421
- item: {
5422
- id: selectedRangeSnapshot.itemId,
5423
- language: selectedRangeSnapshot.language || descriptor.language,
5424
- version: typeof selectedRangeSnapshot.version === "number"
5425
- ? selectedRangeSnapshot.version
5426
- : descriptor.version,
5427
- },
5428
- }
5429
- : undefined;
5430
- const commentFieldSnapshot = selectedRangeFieldSnapshot ??
5431
- hintedFieldSnapshot ??
5432
- focusedFieldSnapshot;
5433
- const itemId = commentFieldSnapshot?.item.id ||
5434
- (selection.length > 0 ? selection[0] : undefined) ||
5435
- descriptor.id;
5436
- if (!itemId)
5437
- return;
5438
- // Ensure the promoted comments surface is active when adding a comment.
5439
- await activateCommentsModeForWriting("comment-add");
5440
- const language = commentFieldSnapshot?.item.language || descriptor.language;
5441
- const version = typeof commentFieldSnapshot?.item.version === "number"
5442
- ? commentFieldSnapshot.item.version
5443
- : descriptor.version;
5444
- const getFieldName = async () => {
5445
- if (!commentFieldSnapshot)
5446
- return "";
5447
- const field = await itemsRepository.getField(commentFieldSnapshot);
5448
- return field?.name;
5449
- };
5450
- const getItemName = async () => {
5451
- const item = await itemsRepository.getItem({
5452
- id: itemId,
5442
+ const language = commentFieldSnapshot?.item.language || descriptor.language;
5443
+ const version = typeof commentFieldSnapshot?.item.version === "number"
5444
+ ? commentFieldSnapshot.item.version
5445
+ : descriptor.version;
5446
+ const getFieldName = async () => {
5447
+ if (!commentFieldSnapshot)
5448
+ return "";
5449
+ const field = await itemsRepository.getField(commentFieldSnapshot);
5450
+ return field?.name;
5451
+ };
5452
+ const getItemName = async () => {
5453
+ const item = await itemsRepository.getItem({
5454
+ id: itemId,
5455
+ language,
5456
+ version,
5457
+ });
5458
+ return item?.name;
5459
+ };
5460
+ const newComment = {
5461
+ id: uuid(),
5462
+ isNew: true,
5463
+ itemId,
5464
+ itemName: await getItemName(),
5465
+ fieldId: commentFieldSnapshot?.fieldId,
5466
+ fieldName: await getFieldName(),
5467
+ mainItemId: descriptor.id,
5453
5468
  language,
5454
5469
  version,
5455
- });
5456
- return item?.name;
5457
- };
5458
- const newComment = {
5459
- id: uuid(),
5460
- isNew: true,
5461
- itemId,
5462
- itemName: await getItemName(),
5463
- fieldId: commentFieldSnapshot?.fieldId,
5464
- fieldName: await getFieldName(),
5465
- mainItemId: descriptor.id,
5466
- language,
5467
- version,
5468
- position: 0,
5469
- rangeStart: isUsableTextSelectionRange(selectedRangeSnapshot)
5470
- ? selectedRangeSnapshot.startOffset
5471
- : 0,
5472
- rangeEnd: isUsableTextSelectionRange(selectedRangeSnapshot)
5473
- ? selectedRangeSnapshot.endOffset
5474
- : 0,
5475
- author: user?.name,
5476
- authorDisplayName: user?.fullName,
5477
- created: new Date().toISOString(),
5478
- };
5479
- if (selectedRangeSnapshot?.clientRect) {
5480
- newComment[COMMENT_TRANSIENT_SELECTION_RECT] =
5481
- selectedRangeSnapshot.clientRect;
5482
- }
5483
- if (selectedRangeSnapshot?.elementKey) {
5484
- newComment[COMMENT_TRANSIENT_ELEMENT_KEY] =
5485
- selectedRangeSnapshot.elementKey;
5486
- }
5487
- setComments([newComment, ...comments]);
5488
- setSelectedComment(newComment);
5489
- setSelectedSuggestedEdit(undefined);
5490
- lastTextSelectionRangeRef.current = undefined;
5491
- },
5492
- mode,
5493
- changeMode,
5494
- setMode,
5495
- registerModeChangeParticipant,
5496
- modeTransitionRevision,
5497
- previewDate,
5498
- setPreviewDate,
5499
- layoutMode,
5500
- setLayoutMode,
5501
- user,
5502
- reviews,
5503
- statusMessage,
5504
- setStatusMessage,
5505
- suggestedEdits,
5506
- setSuggestedEdits,
5507
- getCurrentSuggestedEdits,
5508
- suggestionVariantSelection,
5509
- setSuggestionVariantSelection,
5510
- showSuggestedEdits,
5511
- setShowSuggestedEdits,
5512
- showSuggestedEditsDiff,
5513
- setShowSuggestedEditsDiff,
5514
- showVersionDiffHighlighting,
5515
- setShowVersionDiffHighlighting,
5516
- enableCompletions,
5517
- setEnableCompletions,
5518
- showComponentNavigator,
5519
- setShowComponentNavigator: handleSetShowComponentNavigator,
5520
- isComponentNavigatorOpenForSlot,
5521
- setComponentNavigatorOpenForSlot,
5522
- showAgentsPanel,
5523
- setShowAgentsPanel: handleSetShowAgentsPanel,
5524
- waitForSurfaceSettled: settleRegistry.waitForSurfaceSettled,
5525
- notifySurfaceSettled: settleRegistry.notifySettled,
5526
- isEditorFormHiddenForSlot,
5527
- setEditorFormHiddenForSlot,
5528
- editorFormHintSeen,
5529
- markEditorFormHintSeen,
5530
- editorFormHintVisible,
5531
- showEditorFormHint,
5532
- dismissEditorFormHint,
5533
- editorFormToggleButtonRef,
5534
- showMinimap: effectiveShowMinimap,
5535
- setShowMinimap: handleSetShowMinimap,
5536
- showHelpTerminal,
5537
- setShowHelpTerminal: handleSetShowHelpTerminal,
5538
- toggleHelpTerminal,
5539
- helpTerminalInitialPrompt,
5540
- helpTerminalProfileName,
5541
- helpTerminalActiveTab,
5542
- setHelpTerminalActiveTab,
5543
- selectedHelpSectionId,
5544
- setSelectedHelpSectionId,
5545
- showAgentsWorkspaceEditor,
5546
- setShowAgentsWorkspaceEditor: handleSetShowAgentsWorkspaceEditor,
5547
- selectedAgentsWorkspaceAgentId,
5548
- setSelectedAgentsWorkspaceAgentId,
5549
- activeEditorTab,
5550
- setActiveEditorTab,
5551
- showLayoutComponents,
5552
- setShowLayoutComponents: handleSetShowLayoutComponents,
5553
- quotaInfo,
5554
- isQuotaExceeded: isQuotaExceeded(),
5555
- getQuotaWarningMessage,
5556
- isMobile,
5557
- mobileEditorPanelOpen,
5558
- setMobileEditorPanelOpen: handleSetMobileEditorPanelOpen,
5559
- openDialog,
5560
- webSocketMessages,
5561
- clearWebSocketMessages: () => setWebSocketMessages([]),
5562
- userInfo: userInfo,
5563
- parheliaSettings: effectiveParheliaSettings,
5564
- setUserPreferences,
5565
- currentWizardId,
5566
- setCurrentWizardId,
5567
- favorites,
5568
- loadFavorites,
5569
- refreshFavorites,
5570
- isQuickSwitcherVisible: quickSwitcherVisible,
5571
- // Context factory registry methods
5572
- registerContextFactory: (name, factory) => {
5573
- try {
5574
- factoriesRef.map.set(name, factory);
5575
- }
5576
- catch { }
5577
- },
5578
- unregisterContextFactory: (name) => {
5579
- try {
5580
- factoriesRef.map.delete(name);
5581
- }
5582
- catch { }
5583
- },
5584
- getContextFactory: (name) => {
5585
- try {
5586
- return factoriesRef.map.get(name);
5587
- }
5588
- catch {
5589
- return undefined;
5590
- }
5591
- },
5592
- }), [
5470
+ position: 0,
5471
+ rangeStart: isUsableTextSelectionRange(selectedRangeSnapshot)
5472
+ ? selectedRangeSnapshot.startOffset
5473
+ : 0,
5474
+ rangeEnd: isUsableTextSelectionRange(selectedRangeSnapshot)
5475
+ ? selectedRangeSnapshot.endOffset
5476
+ : 0,
5477
+ author: user?.name,
5478
+ authorDisplayName: user?.fullName,
5479
+ created: new Date().toISOString(),
5480
+ };
5481
+ if (selectedRangeSnapshot?.clientRect) {
5482
+ newComment[COMMENT_TRANSIENT_SELECTION_RECT] =
5483
+ selectedRangeSnapshot.clientRect;
5484
+ }
5485
+ if (selectedRangeSnapshot?.elementKey) {
5486
+ newComment[COMMENT_TRANSIENT_ELEMENT_KEY] =
5487
+ selectedRangeSnapshot.elementKey;
5488
+ }
5489
+ setComments([newComment, ...comments]);
5490
+ setSelectedComment(newComment);
5491
+ setSelectedSuggestedEdit(undefined);
5492
+ lastTextSelectionRangeRef.current = undefined;
5493
+ },
5494
+ mode,
5495
+ changeMode,
5496
+ setMode,
5497
+ registerModeChangeParticipant,
5498
+ modeTransitionRevision,
5499
+ previewDate,
5500
+ setPreviewDate,
5501
+ layoutMode,
5502
+ setLayoutMode,
5503
+ user,
5504
+ reviews,
5505
+ statusMessage,
5506
+ setStatusMessage,
5507
+ suggestedEdits,
5508
+ setSuggestedEdits,
5509
+ getCurrentSuggestedEdits,
5510
+ suggestionVariantSelection,
5511
+ setSuggestionVariantSelection,
5512
+ showSuggestedEdits,
5513
+ setShowSuggestedEdits,
5514
+ showSuggestedEditsDiff,
5515
+ setShowSuggestedEditsDiff,
5516
+ showVersionDiffHighlighting,
5517
+ setShowVersionDiffHighlighting,
5518
+ enableCompletions,
5519
+ setEnableCompletions,
5520
+ showComponentNavigator,
5521
+ setShowComponentNavigator: handleSetShowComponentNavigator,
5522
+ isComponentNavigatorOpenForSlot,
5523
+ setComponentNavigatorOpenForSlot,
5524
+ showAgentsPanel,
5525
+ setShowAgentsPanel: handleSetShowAgentsPanel,
5526
+ waitForSurfaceSettled: settleRegistry.waitForSurfaceSettled,
5527
+ notifySurfaceSettled: settleRegistry.notifySettled,
5528
+ isEditorFormHiddenForSlot,
5529
+ setEditorFormHiddenForSlot,
5530
+ editorFormHintSeen,
5531
+ markEditorFormHintSeen,
5532
+ editorFormHintVisible,
5533
+ showEditorFormHint,
5534
+ dismissEditorFormHint,
5535
+ editorFormToggleButtonRef,
5536
+ showMinimap: effectiveShowMinimap,
5537
+ setShowMinimap: handleSetShowMinimap,
5538
+ showHelpTerminal,
5539
+ setShowHelpTerminal: handleSetShowHelpTerminal,
5540
+ toggleHelpTerminal,
5541
+ helpTerminalInitialPrompt,
5542
+ helpTerminalProfileName,
5543
+ helpTerminalActiveTab,
5544
+ setHelpTerminalActiveTab,
5545
+ selectedHelpSectionId,
5546
+ setSelectedHelpSectionId,
5547
+ showAgentsWorkspaceEditor,
5548
+ setShowAgentsWorkspaceEditor: handleSetShowAgentsWorkspaceEditor,
5549
+ selectedAgentsWorkspaceAgentId,
5550
+ setSelectedAgentsWorkspaceAgentId,
5551
+ activeEditorTab,
5552
+ setActiveEditorTab,
5553
+ showLayoutComponents,
5554
+ setShowLayoutComponents: handleSetShowLayoutComponents,
5555
+ quotaInfo,
5556
+ isQuotaExceeded: isQuotaExceeded(),
5557
+ getQuotaWarningMessage,
5558
+ isMobile,
5559
+ mobileEditorPanelOpen,
5560
+ setMobileEditorPanelOpen: handleSetMobileEditorPanelOpen,
5561
+ openDialog,
5562
+ webSocketMessages,
5563
+ clearWebSocketMessages: () => setWebSocketMessages([]),
5564
+ userInfo: userInfo,
5565
+ parheliaSettings: effectiveParheliaSettings,
5566
+ setUserPreferences,
5567
+ currentWizardId,
5568
+ setCurrentWizardId,
5569
+ favorites,
5570
+ loadFavorites,
5571
+ refreshFavorites,
5572
+ isQuickSwitcherVisible: quickSwitcherVisible,
5573
+ // Context factory registry methods
5574
+ registerContextFactory: (name, factory) => {
5575
+ try {
5576
+ factoriesRef.map.set(name, factory);
5577
+ }
5578
+ catch { }
5579
+ },
5580
+ unregisterContextFactory: (name) => {
5581
+ try {
5582
+ factoriesRef.map.delete(name);
5583
+ }
5584
+ catch { }
5585
+ },
5586
+ getContextFactory: (name) => {
5587
+ try {
5588
+ return factoriesRef.map.get(name);
5589
+ }
5590
+ catch {
5591
+ return undefined;
5592
+ }
5593
+ },
5594
+ };
5595
+ editContextValue.visibleWorkspaces =
5596
+ filterVisibleWorkspaces(editContextValue);
5597
+ return editContextValue;
5598
+ }, [
5593
5599
  operationsContext.ops,
5594
5600
  itemsRepository,
5595
5601
  configuration,
@@ -6034,7 +6040,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
6034
6040
  ? `${window.location.pathname}?${queryString}`
6035
6041
  : window.location.pathname;
6036
6042
  window.history.replaceState(getCurrentHistoryState(), "", newUrl);
6037
- }, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), showSandboxWelcome && (_jsx(SandboxWelcomeOverlay, { userName: userInfo.user.fullName, onDismiss: dismissSandboxWelcome })), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(GuidanceOverlay, {}) }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(AgentDialogHandler, {}) })] }));
6043
+ }, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), showSandboxWelcome && (_jsx(SandboxWelcomeOverlay, { userName: userInfo.user.fullName, onDismiss: dismissSandboxWelcome, onReplayTour: sandboxTourShown
6044
+ ? () => {
6045
+ dismissSandboxWelcome();
6046
+ startTour();
6047
+ }
6048
+ : undefined, replayEnabled: canStartTour })), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(GuidanceOverlay, {}) }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(AgentDialogHandler, {}) })] }));
6038
6049
  const showRefreshSpinner = editContext.isRefreshing && !activePageViewContext.iframeSupportsRefresh;
6039
6050
  return (_jsx(LicenseProvider, { initialLicenseStatus: initialLicenseStatus, initialStatusLoaded: initialLicenseStatusLoaded, children: _jsx("div", { className: `editor h-full w-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(FieldsEditContextProvider, { value: fieldsEditContext, children: _jsx(EditContextProvider, { value: editContext, children: _jsxs(SelectionContextProvider, { value: selectionContextValue, children: [_jsx(DevModeIndicator, {}), startupChecks.state === "loading" && _jsx(EditorLoadingOverlay, {}), showRefreshSpinner && (_jsx("div", { className: "text-neutral-grey-50 pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center opacity-50 select-none", children: _jsx(Spinner, {}) })), (currentWorkspace.id === "agents" ||
6040
6051
  currentWorkspace.id === "taskboard" ||