@alpaca-editor/core 1.0.3762-mono

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 (460) hide show
  1. package/.prettierrc +3 -0
  2. package/dist/client-components/api.js +6 -0
  3. package/dist/client-components/index.js +36 -0
  4. package/dist/components/ActionButton.js +9 -0
  5. package/dist/components/Error.js +28 -0
  6. package/dist/config/config.js +654 -0
  7. package/dist/config/types.js +2 -0
  8. package/dist/editor/ComponentInfo.js +31 -0
  9. package/dist/editor/ConfirmationDialog.js +32 -0
  10. package/dist/editor/ContentTree.js +406 -0
  11. package/dist/editor/ContextMenu.js +117 -0
  12. package/dist/editor/Editor.js +55 -0
  13. package/dist/editor/EditorWarning.js +13 -0
  14. package/dist/editor/EditorWarnings.js +24 -0
  15. package/dist/editor/FieldEditorPopup.js +24 -0
  16. package/dist/editor/FieldHistory.js +40 -0
  17. package/dist/editor/FieldList.js +63 -0
  18. package/dist/editor/FieldListField.js +164 -0
  19. package/dist/editor/FieldListFieldWithFallbacks.js +114 -0
  20. package/dist/editor/FloatingToolbar.js +92 -0
  21. package/dist/editor/ImageEditor.js +55 -0
  22. package/dist/editor/InsertMenu.js +164 -0
  23. package/dist/editor/ItemInfo.js +30 -0
  24. package/dist/editor/LinkEditorDialog.js +89 -0
  25. package/dist/editor/MainLayout.js +46 -0
  26. package/dist/editor/NewEditorClient.js +9 -0
  27. package/dist/editor/PictureCropper.js +332 -0
  28. package/dist/editor/PictureEditor.js +104 -0
  29. package/dist/editor/PictureEditorDialog.js +194 -0
  30. package/dist/editor/ScrollingContentTree.js +30 -0
  31. package/dist/editor/Terminal.js +109 -0
  32. package/dist/editor/Titlebar.js +11 -0
  33. package/dist/editor/ai/AiPopup.js +25 -0
  34. package/dist/editor/ai/AiResponseMessage.js +24 -0
  35. package/dist/editor/ai/AiTerminal.js +241 -0
  36. package/dist/editor/ai/AiToolCall.js +18 -0
  37. package/dist/editor/ai/EditorAiTerminal.js +9 -0
  38. package/dist/editor/ai/editorAiContext.js +14 -0
  39. package/dist/editor/client/DialogContext.js +29 -0
  40. package/dist/editor/client/EditorClient.js +1336 -0
  41. package/dist/editor/client/GenericDialog.js +27 -0
  42. package/dist/editor/client/editContext.js +59 -0
  43. package/dist/editor/client/helpers.js +31 -0
  44. package/dist/editor/client/itemsRepository.js +255 -0
  45. package/dist/editor/client/operations.js +398 -0
  46. package/dist/editor/client/pageModelBuilder.js +129 -0
  47. package/dist/editor/commands/commands.js +2 -0
  48. package/dist/editor/commands/componentCommands.js +277 -0
  49. package/dist/editor/commands/createVersionCommand.js +26 -0
  50. package/dist/editor/commands/deleteVersionCommand.js +55 -0
  51. package/dist/editor/commands/itemCommands.js +134 -0
  52. package/dist/editor/commands/localizeItem/LocalizeItemDialog.js +94 -0
  53. package/dist/editor/commands/undo.js +32 -0
  54. package/dist/editor/component-designer/ComponentDesigner.js +58 -0
  55. package/dist/editor/component-designer/ComponentDesignerAiTerminal.js +9 -0
  56. package/dist/editor/component-designer/ComponentDesignerMenu.js +67 -0
  57. package/dist/editor/component-designer/ComponentEditor.js +59 -0
  58. package/dist/editor/component-designer/ComponentRenderingCodeEditor.js +16 -0
  59. package/dist/editor/component-designer/ComponentRenderingEditor.js +71 -0
  60. package/dist/editor/component-designer/ComponentsDropdown.js +22 -0
  61. package/dist/editor/component-designer/PlaceholdersEditor.js +70 -0
  62. package/dist/editor/component-designer/RenderingsDropdown.js +25 -0
  63. package/dist/editor/component-designer/TemplateEditor.js +144 -0
  64. package/dist/editor/component-designer/aiContext.js +18 -0
  65. package/dist/editor/componentTreeHelper.js +97 -0
  66. package/dist/editor/control-center/ControlCenterMenu.js +59 -0
  67. package/dist/editor/control-center/IndexOverview.js +27 -0
  68. package/dist/editor/control-center/IndexSettings.js +106 -0
  69. package/dist/editor/control-center/Status.js +7 -0
  70. package/dist/editor/editor-warnings/ItemLocked.js +40 -0
  71. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js +16 -0
  72. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.js +16 -0
  73. package/dist/editor/editor-warnings/NoWriteAccess.js +14 -0
  74. package/dist/editor/editor-warnings/ValidationErrors.js +27 -0
  75. package/dist/editor/field-types/AttachmentEditor.js +7 -0
  76. package/dist/editor/field-types/CheckboxEditor.js +32 -0
  77. package/dist/editor/field-types/DropLinkEditor.js +51 -0
  78. package/dist/editor/field-types/DropListEditor.js +58 -0
  79. package/dist/editor/field-types/ImageFieldEditor.js +36 -0
  80. package/dist/editor/field-types/InternalLinkFieldEditor.js +64 -0
  81. package/dist/editor/field-types/LinkFieldEditor.js +58 -0
  82. package/dist/editor/field-types/MultiLineText.js +35 -0
  83. package/dist/editor/field-types/PictureFieldEditor.js +59 -0
  84. package/dist/editor/field-types/RawEditor.js +33 -0
  85. package/dist/editor/field-types/ReactQuill.js +366 -0
  86. package/dist/editor/field-types/RichTextEditor.js +46 -0
  87. package/dist/editor/field-types/RichTextEditorComponent.js +72 -0
  88. package/dist/editor/field-types/SingleLineText.js +92 -0
  89. package/dist/editor/field-types/TreeListEditor.js +137 -0
  90. package/dist/editor/fieldTypes.js +2 -0
  91. package/dist/editor/media-selector/AiImageSearch.js +110 -0
  92. package/dist/editor/media-selector/AiImageSearchPrompt.js +58 -0
  93. package/dist/editor/media-selector/MediaSelector.js +11 -0
  94. package/dist/editor/media-selector/Preview.js +9 -0
  95. package/dist/editor/media-selector/Thumbnails.js +11 -0
  96. package/dist/editor/media-selector/TreeSelector.js +171 -0
  97. package/dist/editor/media-selector/UploadZone.js +80 -0
  98. package/dist/editor/menubar/ActionsMenu.js +33 -0
  99. package/dist/editor/menubar/ActiveUsers.js +13 -0
  100. package/dist/editor/menubar/ApproveAndPublish.js +13 -0
  101. package/dist/editor/menubar/BrowseHistory.js +14 -0
  102. package/dist/editor/menubar/ItemLanguageVersion.js +36 -0
  103. package/dist/editor/menubar/LanguageSelector.js +33 -0
  104. package/dist/editor/menubar/Menu.js +65 -0
  105. package/dist/editor/menubar/NavButtons.js +43 -0
  106. package/dist/editor/menubar/PageSelector.js +50 -0
  107. package/dist/editor/menubar/PageViewerControls.js +37 -0
  108. package/dist/editor/menubar/Separator.js +8 -0
  109. package/dist/editor/menubar/SiteInfo.js +26 -0
  110. package/dist/editor/menubar/User.js +18 -0
  111. package/dist/editor/menubar/VersionSelector.js +49 -0
  112. package/dist/editor/page-editor-chrome/CommentHighlighting.js +214 -0
  113. package/dist/editor/page-editor-chrome/CommentHighlightings.js +17 -0
  114. package/dist/editor/page-editor-chrome/FieldActionIndicator.js +27 -0
  115. package/dist/editor/page-editor-chrome/FieldActionIndicators.js +15 -0
  116. package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +27 -0
  117. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js +15 -0
  118. package/dist/editor/page-editor-chrome/FrameMenu.js +178 -0
  119. package/dist/editor/page-editor-chrome/FrameMenus.js +24 -0
  120. package/dist/editor/page-editor-chrome/InlineEditor.js +101 -0
  121. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +35 -0
  122. package/dist/editor/page-editor-chrome/NoLayout.js +21 -0
  123. package/dist/editor/page-editor-chrome/PageEditorChrome.js +65 -0
  124. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +109 -0
  125. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +82 -0
  126. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +147 -0
  127. package/dist/editor/page-viewer/DeviceToolbar.js +21 -0
  128. package/dist/editor/page-viewer/EditorForm.js +130 -0
  129. package/dist/editor/page-viewer/MiniMap.js +257 -0
  130. package/dist/editor/page-viewer/PageViewer.js +64 -0
  131. package/dist/editor/page-viewer/PageViewerFrame.js +696 -0
  132. package/dist/editor/page-viewer/pageViewContext.js +117 -0
  133. package/dist/editor/pageModel.js +2 -0
  134. package/dist/editor/picture-shared.js +28 -0
  135. package/dist/editor/reviews/Comment.js +112 -0
  136. package/dist/editor/reviews/Comments.js +24 -0
  137. package/dist/editor/reviews/PreviewInfo.js +13 -0
  138. package/dist/editor/reviews/Reviews.js +165 -0
  139. package/dist/editor/reviews/reviewCommands.js +44 -0
  140. package/dist/editor/reviews/useReviews.js +48 -0
  141. package/dist/editor/services/aiService.js +99 -0
  142. package/dist/editor/services/componentDesignerService.js +79 -0
  143. package/dist/editor/services/contentService.js +104 -0
  144. package/dist/editor/services/editService.js +322 -0
  145. package/dist/editor/services/indexService.js +25 -0
  146. package/dist/editor/services/reviewsService.js +43 -0
  147. package/dist/editor/services/serviceHelper.js +67 -0
  148. package/dist/editor/services/systemService.js +7 -0
  149. package/dist/editor/services/translationService.js +15 -0
  150. package/dist/editor/services-server/api.js +119 -0
  151. package/dist/editor/services-server/graphQL.js +56 -0
  152. package/dist/editor/sidebar/ComponentPalette.js +55 -0
  153. package/dist/editor/sidebar/ComponentTree.js +362 -0
  154. package/dist/editor/sidebar/Debug.js +60 -0
  155. package/dist/editor/sidebar/DictionaryEditor.js +160 -0
  156. package/dist/editor/sidebar/EditHistory.js +74 -0
  157. package/dist/editor/sidebar/GraphQL.js +115 -0
  158. package/dist/editor/sidebar/Insert.js +24 -0
  159. package/dist/editor/sidebar/MainContentTree.js +52 -0
  160. package/dist/editor/sidebar/Performance.js +34 -0
  161. package/dist/editor/sidebar/Sessions.js +31 -0
  162. package/dist/editor/sidebar/Sidebar.js +15 -0
  163. package/dist/editor/sidebar/SidebarView.js +76 -0
  164. package/dist/editor/sidebar/Translations.js +160 -0
  165. package/dist/editor/sidebar/Validation.js +52 -0
  166. package/dist/editor/sidebar/ViewSelector.js +15 -0
  167. package/dist/editor/sidebar/Workbox.js +80 -0
  168. package/dist/editor/ui/CenteredMessage.js +7 -0
  169. package/dist/editor/ui/CopyToClipboardButton.js +17 -0
  170. package/dist/editor/ui/DialogButtons.js +7 -0
  171. package/dist/editor/ui/Icons.js +75 -0
  172. package/dist/editor/ui/ItemNameDialog.js +45 -0
  173. package/dist/editor/ui/ItemNameDialogNew.js +61 -0
  174. package/dist/editor/ui/ItemSearch.js +93 -0
  175. package/dist/editor/ui/PerfectTree.js +223 -0
  176. package/dist/editor/ui/Section.js +12 -0
  177. package/dist/editor/ui/SimpleIconButton.js +11 -0
  178. package/dist/editor/ui/SimpleMenu.js +9 -0
  179. package/dist/editor/ui/SimpleTable.js +11 -0
  180. package/dist/editor/ui/SimpleTabs.js +21 -0
  181. package/dist/editor/ui/SimpleToolbar.js +7 -0
  182. package/dist/editor/ui/Spinner.js +7 -0
  183. package/dist/editor/ui/Splitter.js +187 -0
  184. package/dist/editor/ui/StackedPanels.js +69 -0
  185. package/dist/editor/ui/Toolbar.js +7 -0
  186. package/dist/editor/utils/id-helper.js +7 -0
  187. package/dist/editor/utils/insertOptions.js +45 -0
  188. package/dist/editor/utils/itemutils.js +25 -0
  189. package/dist/editor/utils/useMemoDebug.js +20 -0
  190. package/dist/editor/utils.js +328 -0
  191. package/dist/editor/views/CompareView.js +147 -0
  192. package/dist/editor/views/EditView.js +17 -0
  193. package/dist/editor/views/ItemEditor.js +24 -0
  194. package/dist/editor/views/SingleEditView.js +25 -0
  195. package/dist/index.js +22 -0
  196. package/dist/page-wizard/PageWizard.js +62 -0
  197. package/dist/page-wizard/SelectWizard.js +43 -0
  198. package/dist/page-wizard/WizardSteps.js +71 -0
  199. package/dist/page-wizard/service.js +26 -0
  200. package/dist/page-wizard/startPageWizardCommand.js +23 -0
  201. package/dist/page-wizard/steps/BuildPageStep.js +138 -0
  202. package/dist/page-wizard/steps/CollectStep.js +124 -0
  203. package/dist/page-wizard/steps/ComponentTypesSelector.js +211 -0
  204. package/dist/page-wizard/steps/Components.js +94 -0
  205. package/dist/page-wizard/steps/CreatePage.js +142 -0
  206. package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +230 -0
  207. package/dist/page-wizard/steps/EditButton.js +7 -0
  208. package/dist/page-wizard/steps/FieldEditor.js +30 -0
  209. package/dist/page-wizard/steps/Generate.js +11 -0
  210. package/dist/page-wizard/steps/ImagesStep.js +159 -0
  211. package/dist/page-wizard/steps/LayoutStep.js +120 -0
  212. package/dist/page-wizard/steps/SelectStep.js +150 -0
  213. package/dist/page-wizard/steps/schema.js +140 -0
  214. package/dist/page-wizard/steps/usePageCreator.js +194 -0
  215. package/dist/splash-screen/NewPage.js +131 -0
  216. package/dist/splash-screen/SectionHeadline.js +9 -0
  217. package/dist/splash-screen/SplashScreen.js +81 -0
  218. package/dist/tour/Tour.js +321 -0
  219. package/dist/tour/default-tour.js +231 -0
  220. package/dist/tour/preview-tour.js +93 -0
  221. package/dist/tsconfig.build.tsbuildinfo +1 -0
  222. package/dist/types.js +2 -0
  223. package/eslint.config.mjs +4 -0
  224. package/images/bg-shape-black.webp +0 -0
  225. package/package.json +52 -0
  226. package/src/client-components/api.ts +6 -0
  227. package/src/client-components/index.ts +19 -0
  228. package/src/components/ActionButton.tsx +43 -0
  229. package/src/components/Error.tsx +57 -0
  230. package/src/config/config.tsx +737 -0
  231. package/src/config/types.ts +263 -0
  232. package/src/editor/ComponentInfo.tsx +77 -0
  233. package/src/editor/ConfirmationDialog.tsx +103 -0
  234. package/src/editor/ContentTree.tsx +654 -0
  235. package/src/editor/ContextMenu.tsx +155 -0
  236. package/src/editor/Editor.tsx +91 -0
  237. package/src/editor/EditorWarning.tsx +34 -0
  238. package/src/editor/EditorWarnings.tsx +33 -0
  239. package/src/editor/FieldEditorPopup.tsx +65 -0
  240. package/src/editor/FieldHistory.tsx +74 -0
  241. package/src/editor/FieldList.tsx +190 -0
  242. package/src/editor/FieldListField.tsx +387 -0
  243. package/src/editor/FieldListFieldWithFallbacks.tsx +211 -0
  244. package/src/editor/FloatingToolbar.tsx +163 -0
  245. package/src/editor/ImageEditor.tsx +129 -0
  246. package/src/editor/InsertMenu.tsx +332 -0
  247. package/src/editor/ItemInfo.tsx +90 -0
  248. package/src/editor/LinkEditorDialog.tsx +192 -0
  249. package/src/editor/MainLayout.tsx +94 -0
  250. package/src/editor/NewEditorClient.tsx +11 -0
  251. package/src/editor/PictureCropper.tsx +505 -0
  252. package/src/editor/PictureEditor.tsx +206 -0
  253. package/src/editor/PictureEditorDialog.tsx +381 -0
  254. package/src/editor/PublishDialog.ignore +74 -0
  255. package/src/editor/ScrollingContentTree.tsx +47 -0
  256. package/src/editor/Terminal.tsx +215 -0
  257. package/src/editor/Titlebar.tsx +23 -0
  258. package/src/editor/ai/AiPopup.tsx +59 -0
  259. package/src/editor/ai/AiResponseMessage.tsx +82 -0
  260. package/src/editor/ai/AiTerminal.tsx +450 -0
  261. package/src/editor/ai/AiToolCall.tsx +46 -0
  262. package/src/editor/ai/EditorAiTerminal.tsx +20 -0
  263. package/src/editor/ai/editorAiContext.ts +18 -0
  264. package/src/editor/client/DialogContext.tsx +49 -0
  265. package/src/editor/client/EditorClient.tsx +1831 -0
  266. package/src/editor/client/GenericDialog.tsx +50 -0
  267. package/src/editor/client/editContext.ts +330 -0
  268. package/src/editor/client/helpers.ts +44 -0
  269. package/src/editor/client/itemsRepository.ts +391 -0
  270. package/src/editor/client/operations.ts +610 -0
  271. package/src/editor/client/pageModelBuilder.ts +182 -0
  272. package/src/editor/commands/commands.ts +23 -0
  273. package/src/editor/commands/componentCommands.tsx +408 -0
  274. package/src/editor/commands/createVersionCommand.ts +33 -0
  275. package/src/editor/commands/deleteVersionCommand.ts +71 -0
  276. package/src/editor/commands/itemCommands.tsx +186 -0
  277. package/src/editor/commands/localizeItem/LocalizeItemDialog.tsx +201 -0
  278. package/src/editor/commands/undo.ts +39 -0
  279. package/src/editor/component-designer/ComponentDesigner.tsx +70 -0
  280. package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx +11 -0
  281. package/src/editor/component-designer/ComponentDesignerMenu.tsx +91 -0
  282. package/src/editor/component-designer/ComponentEditor.tsx +97 -0
  283. package/src/editor/component-designer/ComponentRenderingCodeEditor.tsx +31 -0
  284. package/src/editor/component-designer/ComponentRenderingEditor.tsx +104 -0
  285. package/src/editor/component-designer/ComponentsDropdown.tsx +39 -0
  286. package/src/editor/component-designer/PlaceholdersEditor.tsx +183 -0
  287. package/src/editor/component-designer/RenderingsDropdown.tsx +36 -0
  288. package/src/editor/component-designer/TemplateEditor.tsx +236 -0
  289. package/src/editor/component-designer/aiContext.ts +23 -0
  290. package/src/editor/componentTreeHelper.tsx +114 -0
  291. package/src/editor/control-center/ControlCenterMenu.tsx +71 -0
  292. package/src/editor/control-center/IndexOverview.tsx +50 -0
  293. package/src/editor/control-center/IndexSettings.tsx +266 -0
  294. package/src/editor/control-center/Status.tsx +7 -0
  295. package/src/editor/editor-warnings/ItemLocked.tsx +63 -0
  296. package/src/editor/editor-warnings/NoLanguageWriteAccess.tsx +22 -0
  297. package/src/editor/editor-warnings/NoWorkflowWriteAccess.tsx +23 -0
  298. package/src/editor/editor-warnings/NoWriteAccess.tsx +15 -0
  299. package/src/editor/editor-warnings/ValidationErrors.tsx +54 -0
  300. package/src/editor/field-types/AttachmentEditor.tsx +9 -0
  301. package/src/editor/field-types/CheckboxEditor.tsx +47 -0
  302. package/src/editor/field-types/DropLinkEditor.tsx +75 -0
  303. package/src/editor/field-types/DropListEditor.tsx +84 -0
  304. package/src/editor/field-types/ImageFieldEditor.tsx +65 -0
  305. package/src/editor/field-types/InternalLinkFieldEditor.tsx +112 -0
  306. package/src/editor/field-types/LinkFieldEditor.tsx +85 -0
  307. package/src/editor/field-types/MultiLineText.tsx +63 -0
  308. package/src/editor/field-types/PictureFieldEditor.tsx +121 -0
  309. package/src/editor/field-types/RawEditor.tsx +53 -0
  310. package/src/editor/field-types/ReactQuill.tsx +580 -0
  311. package/src/editor/field-types/RichTextEditor.tsx +22 -0
  312. package/src/editor/field-types/RichTextEditorComponent.tsx +108 -0
  313. package/src/editor/field-types/SingleLineText.tsx +150 -0
  314. package/src/editor/field-types/TreeListEditor.tsx +261 -0
  315. package/src/editor/fieldTypes.ts +140 -0
  316. package/src/editor/media-selector/AiImageSearch.tsx +186 -0
  317. package/src/editor/media-selector/AiImageSearchPrompt.tsx +95 -0
  318. package/src/editor/media-selector/MediaSelector.tsx +42 -0
  319. package/src/editor/media-selector/Preview.tsx +14 -0
  320. package/src/editor/media-selector/Thumbnails.tsx +48 -0
  321. package/src/editor/media-selector/TreeSelector.tsx +292 -0
  322. package/src/editor/media-selector/UploadZone.tsx +137 -0
  323. package/src/editor/menubar/ActionsMenu.tsx +47 -0
  324. package/src/editor/menubar/ActiveUsers.tsx +17 -0
  325. package/src/editor/menubar/ApproveAndPublish.tsx +18 -0
  326. package/src/editor/menubar/BrowseHistory.tsx +37 -0
  327. package/src/editor/menubar/ItemLanguageVersion.tsx +52 -0
  328. package/src/editor/menubar/LanguageSelector.tsx +152 -0
  329. package/src/editor/menubar/Menu.tsx +83 -0
  330. package/src/editor/menubar/NavButtons.tsx +74 -0
  331. package/src/editor/menubar/PageSelector.tsx +139 -0
  332. package/src/editor/menubar/PageViewerControls.tsx +99 -0
  333. package/src/editor/menubar/Separator.tsx +12 -0
  334. package/src/editor/menubar/SiteInfo.tsx +53 -0
  335. package/src/editor/menubar/User.tsx +27 -0
  336. package/src/editor/menubar/VersionSelector.tsx +143 -0
  337. package/src/editor/page-editor-chrome/CommentHighlighting.tsx +287 -0
  338. package/src/editor/page-editor-chrome/CommentHighlightings.tsx +35 -0
  339. package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +44 -0
  340. package/src/editor/page-editor-chrome/FieldActionIndicators.tsx +23 -0
  341. package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +64 -0
  342. package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +35 -0
  343. package/src/editor/page-editor-chrome/FrameMenu.tsx +263 -0
  344. package/src/editor/page-editor-chrome/FrameMenus.tsx +48 -0
  345. package/src/editor/page-editor-chrome/InlineEditor.tsx +147 -0
  346. package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +61 -0
  347. package/src/editor/page-editor-chrome/NoLayout.tsx +36 -0
  348. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +119 -0
  349. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +154 -0
  350. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +171 -0
  351. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +233 -0
  352. package/src/editor/page-viewer/DeviceToolbar.tsx +70 -0
  353. package/src/editor/page-viewer/EditorForm.tsx +247 -0
  354. package/src/editor/page-viewer/MiniMap.tsx +351 -0
  355. package/src/editor/page-viewer/PageViewer.tsx +127 -0
  356. package/src/editor/page-viewer/PageViewerFrame.tsx +1030 -0
  357. package/src/editor/page-viewer/pageViewContext.ts +186 -0
  358. package/src/editor/pageModel.ts +191 -0
  359. package/src/editor/picture-shared.tsx +53 -0
  360. package/src/editor/reviews/Comment.tsx +265 -0
  361. package/src/editor/reviews/Comments.tsx +50 -0
  362. package/src/editor/reviews/PreviewInfo.tsx +35 -0
  363. package/src/editor/reviews/Reviews.tsx +280 -0
  364. package/src/editor/reviews/reviewCommands.tsx +47 -0
  365. package/src/editor/reviews/useReviews.tsx +70 -0
  366. package/src/editor/services/aiService.ts +155 -0
  367. package/src/editor/services/componentDesignerService.ts +151 -0
  368. package/src/editor/services/contentService.ts +159 -0
  369. package/src/editor/services/editService.ts +462 -0
  370. package/src/editor/services/indexService.ts +24 -0
  371. package/src/editor/services/reviewsService.ts +45 -0
  372. package/src/editor/services/serviceHelper.ts +95 -0
  373. package/src/editor/services/systemService.ts +5 -0
  374. package/src/editor/services/translationService.ts +21 -0
  375. package/src/editor/services-server/api.ts +150 -0
  376. package/src/editor/services-server/graphQL.ts +106 -0
  377. package/src/editor/sidebar/ComponentPalette.tsx +146 -0
  378. package/src/editor/sidebar/ComponentTree.tsx +512 -0
  379. package/src/editor/sidebar/ComponentTree2.tsxx +490 -0
  380. package/src/editor/sidebar/Debug.tsx +105 -0
  381. package/src/editor/sidebar/DictionaryEditor.tsx +261 -0
  382. package/src/editor/sidebar/EditHistory.tsx +134 -0
  383. package/src/editor/sidebar/GraphQL.tsx +164 -0
  384. package/src/editor/sidebar/Insert.tsx +35 -0
  385. package/src/editor/sidebar/MainContentTree.tsx +95 -0
  386. package/src/editor/sidebar/Performance.tsx +53 -0
  387. package/src/editor/sidebar/Sessions.tsx +35 -0
  388. package/src/editor/sidebar/Sidebar.tsx +20 -0
  389. package/src/editor/sidebar/SidebarView.tsx +150 -0
  390. package/src/editor/sidebar/Translations.tsx +276 -0
  391. package/src/editor/sidebar/Validation.tsx +102 -0
  392. package/src/editor/sidebar/ViewSelector.tsx +49 -0
  393. package/src/editor/sidebar/Workbox.tsx +209 -0
  394. package/src/editor/ui/CenteredMessage.tsx +7 -0
  395. package/src/editor/ui/CopyToClipboardButton.tsx +23 -0
  396. package/src/editor/ui/DialogButtons.tsx +11 -0
  397. package/src/editor/ui/Icons.tsx +585 -0
  398. package/src/editor/ui/ItemNameDialog.tsx +94 -0
  399. package/src/editor/ui/ItemNameDialogNew.tsx +118 -0
  400. package/src/editor/ui/ItemSearch.tsx +173 -0
  401. package/src/editor/ui/PerfectTree.tsx +550 -0
  402. package/src/editor/ui/Section.tsx +35 -0
  403. package/src/editor/ui/SimpleIconButton.tsx +43 -0
  404. package/src/editor/ui/SimpleMenu.tsx +48 -0
  405. package/src/editor/ui/SimpleTable.tsx +63 -0
  406. package/src/editor/ui/SimpleTabs.tsx +55 -0
  407. package/src/editor/ui/SimpleToolbar.tsx +7 -0
  408. package/src/editor/ui/Spinner.tsx +7 -0
  409. package/src/editor/ui/Splitter.tsx +247 -0
  410. package/src/editor/ui/StackedPanels.tsx +134 -0
  411. package/src/editor/ui/Toolbar.tsx +7 -0
  412. package/src/editor/utils/id-helper.ts +3 -0
  413. package/src/editor/utils/insertOptions.ts +69 -0
  414. package/src/editor/utils/itemutils.ts +29 -0
  415. package/src/editor/utils/useMemoDebug.ts +28 -0
  416. package/src/editor/utils.ts +435 -0
  417. package/src/editor/views/CompareView.tsx +256 -0
  418. package/src/editor/views/EditView.tsx +27 -0
  419. package/src/editor/views/ItemEditor.tsx +58 -0
  420. package/src/editor/views/SingleEditView.tsx +44 -0
  421. package/src/fonts/Geist-Black.woff2 +0 -0
  422. package/src/fonts/Geist-Bold.woff2 +0 -0
  423. package/src/fonts/Geist-ExtraBold.woff2 +0 -0
  424. package/src/fonts/Geist-ExtraLight.woff2 +0 -0
  425. package/src/fonts/Geist-Light.woff2 +0 -0
  426. package/src/fonts/Geist-Medium.woff2 +0 -0
  427. package/src/fonts/Geist-Regular.woff2 +0 -0
  428. package/src/fonts/Geist-SemiBold.woff2 +0 -0
  429. package/src/fonts/Geist-Thin.woff2 +0 -0
  430. package/src/fonts/Geist[wght].woff2 +0 -0
  431. package/src/index.ts +7 -0
  432. package/src/page-wizard/PageWizard.tsx +163 -0
  433. package/src/page-wizard/SelectWizard.tsx +109 -0
  434. package/src/page-wizard/WizardSteps.tsx +207 -0
  435. package/src/page-wizard/service.ts +35 -0
  436. package/src/page-wizard/startPageWizardCommand.ts +27 -0
  437. package/src/page-wizard/steps/BuildPageStep.tsx +266 -0
  438. package/src/page-wizard/steps/CollectStep.tsx +233 -0
  439. package/src/page-wizard/steps/ComponentTypesSelector.tsx +443 -0
  440. package/src/page-wizard/steps/Components.tsx +193 -0
  441. package/src/page-wizard/steps/CreatePage.tsx +285 -0
  442. package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +384 -0
  443. package/src/page-wizard/steps/EditButton.tsx +34 -0
  444. package/src/page-wizard/steps/FieldEditor.tsx +102 -0
  445. package/src/page-wizard/steps/Generate.tsx +32 -0
  446. package/src/page-wizard/steps/ImagesStep.tsx +318 -0
  447. package/src/page-wizard/steps/LayoutStep.tsx +228 -0
  448. package/src/page-wizard/steps/SelectStep.tsx +256 -0
  449. package/src/page-wizard/steps/schema.ts +180 -0
  450. package/src/page-wizard/steps/usePageCreator.ts +279 -0
  451. package/src/splash-screen/NewPage.tsx +232 -0
  452. package/src/splash-screen/SectionHeadline.tsx +21 -0
  453. package/src/splash-screen/SplashScreen.tsx +156 -0
  454. package/src/tour/Tour.tsx +558 -0
  455. package/src/tour/default-tour.tsx +300 -0
  456. package/src/tour/preview-tour.tsx +127 -0
  457. package/src/types.ts +302 -0
  458. package/styles.css +476 -0
  459. package/tsconfig.build.json +21 -0
  460. package/tsconfig.json +11 -0
@@ -0,0 +1,1336 @@
1
+ "use client";
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.EditorClient = EditorClient;
41
+ const jsx_runtime_1 = require("react/jsx-runtime");
42
+ const react_1 = __importStar(require("react"));
43
+ const toast_1 = require("primereact/toast");
44
+ const editContext_1 = require("./editContext");
45
+ const navigation_1 = require("next/navigation");
46
+ const componentTreeHelper_1 = require("../componentTreeHelper");
47
+ const operations_1 = require("./operations");
48
+ const helpers_1 = require("./helpers");
49
+ const editService_1 = require("../services/editService");
50
+ const sans_1 = require("geist/font/sans");
51
+ require("primeicons/primeicons.css");
52
+ require("primereact/resources/themes/md-light-indigo/theme.css");
53
+ require("react-json-view-lite/dist/index.css");
54
+ const MediaSelector_1 = require("../media-selector/MediaSelector");
55
+ const componentCommands_1 = require("../commands/componentCommands");
56
+ const contentService_1 = require("../services/contentService");
57
+ const ConfirmationDialog_1 = __importDefault(require("../ConfirmationDialog"));
58
+ const MainLayout_1 = __importDefault(require("../MainLayout"));
59
+ const utils_1 = require("../utils");
60
+ const ContextMenu_1 = require("../ContextMenu");
61
+ const FieldEditorPopup_1 = require("../FieldEditorPopup");
62
+ const AiPopup_1 = require("../ai/AiPopup");
63
+ const serviceHelper_1 = require("../services/serviceHelper");
64
+ const SidebarView_1 = require("../sidebar/SidebarView");
65
+ const PageViewerFrame_1 = require("../page-viewer/PageViewerFrame");
66
+ const itemsRepository_1 = require("./itemsRepository");
67
+ const Spinner_1 = require("../ui/Spinner");
68
+ const id_helper_1 = require("../utils/id-helper");
69
+ const DialogContext_1 = require("./DialogContext");
70
+ const use_debounce_1 = require("use-debounce");
71
+ const Tour_1 = require("../../tour/Tour");
72
+ const pageViewContext_1 = require("../page-viewer/pageViewContext");
73
+ const reviewsService_1 = require("../services/reviewsService");
74
+ const useReviews_1 = require("../reviews/useReviews");
75
+ const react_uuid_1 = __importDefault(require("react-uuid"));
76
+ const react_dom_1 = require("react-dom");
77
+ function EditorClient({ configuration, className, item: loadItemDescriptor, sessionId, }) {
78
+ const router = (0, navigation_1.useRouter)();
79
+ const pathname = (0, navigation_1.usePathname)();
80
+ const searchParams = (0, navigation_1.useSearchParams)();
81
+ const [selection, setSelection] = (0, react_1.useState)([]);
82
+ const [selectedForInsertion, setSelectedForInsertion] = (0, react_1.useState)("");
83
+ const [refreshCompletedFlag, setRefreshCompletedFlag] = (0, react_1.useState)(false);
84
+ const [isRefreshing, setIsRefreshing] = (0, react_1.useState)(false);
85
+ const [dragObject, setDragObject] = (0, react_1.useState)();
86
+ const [mediaResolver, setMediaResolver] = (0, react_1.useState)();
87
+ const [mediaSelectorVisible, setMediaSelectorVisible] = (0, react_1.useState)(false);
88
+ const [mediaSelectorMode, setMediaSelectorMode] = (0, react_1.useState)("images");
89
+ const [selectedMediaIdPath, setSelectedMediaIdPath] = (0, react_1.useState)("");
90
+ const [scrollIntoView, setScrollIntoView] = (0, react_1.useState)();
91
+ const confirmationDialogRef = (0, react_1.useRef)(null);
92
+ const contextMenuRef = (0, react_1.useRef)(null);
93
+ const editContextRef = (0, react_1.useRef)(undefined);
94
+ const [currentOverlay, setCurrentOverlay] = (0, react_1.useState)();
95
+ const [contentEditorItem, setContentEditorItem] = (0, react_1.useState)();
96
+ const [focusedField, setFocusedField] = (0, react_1.useState)();
97
+ const [selectedRange, setSelectedRange] = (0, react_1.useState)();
98
+ const [validating, setValidating] = (0, react_1.useState)(false);
99
+ const [inserting, setInserting] = (0, react_1.useState)();
100
+ const [showFullscreenHint, setShowFullscreenHint] = (0, react_1.useState)(false);
101
+ // const [showPublishDialog, setShowPublishDialog] = useState(false);
102
+ const [activeFieldActions, setActiveFieldActions] = (0, react_1.useState)([]);
103
+ const [renderedFields, setRenderedFields] = (0, react_1.useState)([]);
104
+ const aiPopupRef = react_1.default.useRef(null);
105
+ const fieldEditorPopupRef = react_1.default.useRef(null);
106
+ const [validationResult, setValidationResult] = (0, react_1.useState)();
107
+ const [editHistory, setEditHistory] = (0, react_1.useState)([]);
108
+ const [lastEditedFields, setLastEditedFields] = (0, react_1.useState)([]);
109
+ const [activeSessions, setActiveSessions] = (0, react_1.useState)([]);
110
+ if (typeof window !== "undefined")
111
+ sessionStorage?.setItem("sessionId", sessionId);
112
+ const [viewName, setViewName] = (0, react_1.useState)(
113
+ // default from query string
114
+ searchParams.get("view") ??
115
+ configuration.editor.views[0]?.name ??
116
+ "splash-screen");
117
+ const [compareMode, setCompareMode] = (0, react_1.useState)(false);
118
+ const [compareTo, setCompareTo] = (0, react_1.useState)();
119
+ const [componentDesignerComponent, setComponentDesignerComponent] = (0, react_1.useState)();
120
+ const [componentDesignerRendering, setComponentDesignerRendering] = (0, react_1.useState)();
121
+ const [insertMode, setInsertMode] = (0, react_1.useState)(false);
122
+ const [ignoreBlur, setIgnoreBlur] = (0, react_1.useState)(false);
123
+ const [currentItemDescriptor, setCurrentItemDescriptor] = (0, react_1.useState)();
124
+ const currentItemDescriptorRef = (0, react_1.useRef)(undefined);
125
+ (0, react_1.useEffect)(() => {
126
+ currentItemDescriptorRef.current = currentItemDescriptor;
127
+ }, [currentItemDescriptor]);
128
+ const currentItemRef = (0, react_1.useRef)(undefined);
129
+ (0, react_1.useEffect)(() => {
130
+ currentItemRef.current = contentEditorItem;
131
+ }, [contentEditorItem]);
132
+ const [inlineEditingFieldElement, setInlineEditingFieldElement] = (0, react_1.useState)();
133
+ const [lockedField, setLockedField] = (0, react_1.useState)();
134
+ const [itemLanguages, setItemLanguages] = (0, react_1.useState)([]);
135
+ const [itemVersions, setItemVersions] = (0, react_1.useState)([]);
136
+ const [modifiedFields, setModifiedFields] = (0, react_1.useState)([]);
137
+ const [comments, setComments] = (0, react_1.useState)([]);
138
+ const [showComments, setShowComments] = (0, react_1.useState)(() => {
139
+ const savedShowComments = typeof window !== "undefined"
140
+ ? localStorage.getItem("editor.showComments")
141
+ : null;
142
+ return savedShowComments ? JSON.parse(savedShowComments) : true;
143
+ });
144
+ (0, react_1.useEffect)(() => {
145
+ if (typeof window !== "undefined") {
146
+ localStorage.setItem("editor.showComments", JSON.stringify(showComments));
147
+ }
148
+ }, [showComments]);
149
+ const [selectedComment, setSelectedComment] = (0, react_1.useState)();
150
+ const [browseHistory, setBrowseHistory] = (0, react_1.useState)(() => {
151
+ const savedHistory = typeof window !== "undefined"
152
+ ? localStorage.getItem("editor.browseHistory")
153
+ : null;
154
+ return savedHistory ? JSON.parse(savedHistory) : [];
155
+ });
156
+ const [centerPanelView, setCenterPanelView] = (0, react_1.useState)();
157
+ const [timings, setTimings] = (0, react_1.useState)({});
158
+ const [revision, setRevision] = (0, react_1.useState)();
159
+ const [workboxItems, setWorkboxItems] = (0, react_1.useState)([]);
160
+ const [isTourActive, setIsTourActive] = (0, react_1.useState)(false);
161
+ const [previewMode, setPreviewMode] = (0, react_1.useState)(false);
162
+ const [statusMessage, setStatusMessage] = (0, react_1.useState)("");
163
+ const mode = searchParams.get("mode");
164
+ (0, react_1.useEffect)(() => {
165
+ if (mode === "preview") {
166
+ setPreviewMode(true);
167
+ }
168
+ }, [mode]);
169
+ (0, react_1.useEffect)(() => {
170
+ if (previewMode) {
171
+ }
172
+ }, [previewMode]);
173
+ (0, react_1.useEffect)(() => {
174
+ if (focusedField &&
175
+ selection.length > 0 &&
176
+ selection[0] !== focusedField.item.id) {
177
+ setFocusedField(undefined);
178
+ }
179
+ }, [selection]);
180
+ const dialogContext = (0, DialogContext_1.useDialog)();
181
+ const itemsRepository = (0, itemsRepository_1.useItemsRepository)(setModifiedFields, setLastEditedFields);
182
+ const pageViewContext = (0, pageViewContext_1.usePageViewContext)({
183
+ pageItemDescriptor: currentItemDescriptor,
184
+ itemsRepository,
185
+ configuration,
186
+ });
187
+ const socketMessageListeners = (0, react_1.useRef)(new Set());
188
+ const addSocketMessageListener = (callback) => {
189
+ socketMessageListeners.current.add(callback);
190
+ return () => socketMessageListeners.current.delete(callback);
191
+ };
192
+ const reviews = (0, useReviews_1.useReviews)({
193
+ currentItemDescriptor,
194
+ addSocketMessageListener: addSocketMessageListener,
195
+ });
196
+ const validate = (0, use_debounce_1.useDebouncedCallback)(async (items) => {
197
+ setValidating(true);
198
+ const result = await (0, editService_1.validateItems)(items, sessionId);
199
+ if (result.type === "success")
200
+ setValidationResult(await result.data);
201
+ setValidating(false);
202
+ }, 1000);
203
+ (0, react_1.useEffect)(() => {
204
+ setSelectedForInsertion("");
205
+ }, [selection]);
206
+ (0, react_1.useEffect)(() => {
207
+ if (focusedField?.fieldId !== selectedRange?.fieldId) {
208
+ setSelectedRange(undefined);
209
+ }
210
+ }, [focusedField]);
211
+ const currentView = configuration.editor.views.find((x) => x.name === viewName) ??
212
+ configuration.editor.views[0];
213
+ (0, react_1.useEffect)(() => {
214
+ if (currentView?.defaultCenterPanelView)
215
+ setCenterPanelView(currentView.defaultCenterPanelView);
216
+ }, [currentView]);
217
+ const sendClientInfo = async () => {
218
+ const socket = globalThis.editorSocket;
219
+ const clientInfoMessage = {
220
+ type: "client-info",
221
+ sessionId: sessionId,
222
+ url: window.location.href,
223
+ userAgent: navigator.userAgent,
224
+ item: currentItemRef.current
225
+ ? {
226
+ ...currentItemRef.current.descriptor,
227
+ name: currentItemRef.current.name,
228
+ }
229
+ : null,
230
+ };
231
+ if (socket.readyState !== WebSocket.OPEN) {
232
+ const url = "/alpaca/editor/client";
233
+ await (0, serviceHelper_1.post)(url, clientInfoMessage);
234
+ }
235
+ else
236
+ socket.send(JSON.stringify(clientInfoMessage));
237
+ };
238
+ const startTour = () => {
239
+ setIsTourActive(true);
240
+ };
241
+ const messageHandler = (0, react_1.useCallback)(async (event) => {
242
+ if (!event.data.startsWith("{"))
243
+ return;
244
+ const message = JSON.parse(event.data);
245
+ if (message.type === "active-sessions") {
246
+ setActiveSessions(() => {
247
+ return message.payload;
248
+ });
249
+ }
250
+ if (message.type === "item-deleted") {
251
+ itemsRepository.onItemsDeleted([
252
+ { item: message.payload.item, parentId: message.payload.parentId },
253
+ ]);
254
+ if (message.payload.item.id === currentItemDescriptor?.id) {
255
+ console.log("Load", message.payload.parentId);
256
+ loadItem({
257
+ id: message.payload.parentId,
258
+ language: currentItemDescriptor?.language ?? "en",
259
+ version: 0,
260
+ });
261
+ }
262
+ }
263
+ if (message.type === "item-changed") {
264
+ await itemsRepository.refreshItems([message.payload.item]);
265
+ if (message.payload.item.id === currentItemDescriptor?.id)
266
+ loadItemVersions();
267
+ }
268
+ if (message.type === "item-version-added") {
269
+ if (currentItemDescriptorRef.current) {
270
+ if (currentItemDescriptorRef.current.id === message.payload.item.id)
271
+ await loadItemVersions();
272
+ setCurrentItemDescriptor({ ...currentItemDescriptorRef.current });
273
+ }
274
+ }
275
+ if (message.type === "comment-updated") {
276
+ setComments((x) => {
277
+ const newComments = [...x];
278
+ const index = newComments.findIndex((c) => c.id === message.payload.comment.id);
279
+ if (index !== -1)
280
+ newComments[index] = message.payload.comment;
281
+ else
282
+ newComments.push(message.payload.comment);
283
+ return newComments;
284
+ });
285
+ }
286
+ if (message.type === "comment-deleted") {
287
+ setComments((x) => {
288
+ return x.filter((c) => c.id !== message.payload.id);
289
+ });
290
+ }
291
+ if (message.type === "edit-operation") {
292
+ const op = message.payload;
293
+ if (op.type === "edit-field") {
294
+ const editFieldOperation = op;
295
+ const field = await itemsRepository.getField(editFieldOperation);
296
+ if (!field ||
297
+ (field.type !== "single-line text" &&
298
+ field.type !== "multi-line text" &&
299
+ field.type !== "rich text")) {
300
+ itemsRepository.refreshItems([editFieldOperation.item]);
301
+ requestRefresh("immediate");
302
+ }
303
+ //TODO: field value changes that require rerender
304
+ else
305
+ itemsRepository.updateFieldValue({
306
+ fieldId: editFieldOperation.fieldId,
307
+ item: editFieldOperation.item,
308
+ }, editFieldOperation.user ?? { name: "unknown", ai: false }, false, editFieldOperation.undone
309
+ ? editFieldOperation.oldValue
310
+ : editFieldOperation.value);
311
+ }
312
+ else {
313
+ requestRefresh("immediate");
314
+ }
315
+ if (op.mainItem &&
316
+ op.mainItem.id === currentItemRef.current?.descriptor.id &&
317
+ op.mainItem.language ===
318
+ currentItemRef.current?.descriptor.language &&
319
+ op.mainItem.version === currentItemRef.current?.descriptor.version) {
320
+ loadHistory(op.mainItem);
321
+ }
322
+ }
323
+ socketMessageListeners.current.forEach((listener) => listener(message));
324
+ }, [currentItemDescriptorRef, setLastEditedFields]);
325
+ const user = activeSessions.find((x) => x.sessionId === sessionId)?.user;
326
+ (0, react_1.useEffect)(() => {
327
+ if (typeof window === "undefined")
328
+ return;
329
+ var keepAliveUrl = "/alpaca/editor/keepalive";
330
+ const interval = setInterval(() => {
331
+ fetch(keepAliveUrl + "?ts=" + Date.now()).catch((error) => console.error("Keep Alive error:", error));
332
+ }, 5 * 60 * 1000);
333
+ const handleMessage = (event) => {
334
+ if (event.data.type === "componentsSelected") {
335
+ setSelection(event.data.componentIds);
336
+ }
337
+ };
338
+ window.addEventListener("message", handleMessage);
339
+ return () => {
340
+ window.removeEventListener("message", handleMessage);
341
+ clearInterval(interval);
342
+ };
343
+ }, []);
344
+ (0, react_1.useEffect)(() => {
345
+ const tour = configuration.activeTour;
346
+ const key = tour === "default" ? "editor.tourShown" : "editor.tourShown." + tour;
347
+ const tourShown = localStorage.getItem(key);
348
+ if (!tourShown) {
349
+ setIsTourActive(true);
350
+ localStorage.setItem(key, "true");
351
+ }
352
+ }, []);
353
+ (0, react_1.useEffect)(() => {
354
+ let socket = globalThis.editorSocket;
355
+ if (socket &&
356
+ (socket.readyState === WebSocket.OPEN ||
357
+ socket.readyState === WebSocket.CONNECTING))
358
+ return;
359
+ socket = (0, editService_1.connectSocket)(sessionId);
360
+ // Connection opened
361
+ socket.addEventListener("open", () => {
362
+ console.log("Connected!");
363
+ sendClientInfo();
364
+ //TODO: Load clients
365
+ });
366
+ // Listen for messages
367
+ socket.addEventListener("message", messageHandler);
368
+ globalThis.editorSocket = socket;
369
+ }, []);
370
+ (0, react_1.useEffect)(() => {
371
+ const itemid = searchParams.get("itemid");
372
+ if (searchParams.has("view")) {
373
+ setViewName(searchParams.get("view"));
374
+ }
375
+ else if (!itemid) {
376
+ setViewName("splash-screen");
377
+ }
378
+ if (searchParams.has("compare"))
379
+ setCompareMode(searchParams.get("compare") === "true");
380
+ const itemId = (0, id_helper_1.cleanId)(loadItemDescriptor?.id ?? itemid ?? undefined);
381
+ const language = loadItemDescriptor?.language ?? searchParams.get("lang");
382
+ const version = loadItemDescriptor?.version ??
383
+ (searchParams.has("version")
384
+ ? parseInt(searchParams.get("version"))
385
+ : 0);
386
+ if (itemid && viewName === "splash-screen") {
387
+ setViewName("page-editor");
388
+ }
389
+ if (!itemId || !language)
390
+ return;
391
+ if (currentItemDescriptor?.id === itemId &&
392
+ currentItemDescriptor?.language === language &&
393
+ (!version || currentItemDescriptor?.version === version)) {
394
+ return;
395
+ }
396
+ loadItem({ id: itemId, language, version });
397
+ }, [searchParams, loadItemDescriptor]);
398
+ (0, react_1.useEffect)(() => {
399
+ if (selection.length)
400
+ setSelectedForInsertion("");
401
+ // Does the current focused field belong to the current item?
402
+ const currentItem = selection.length > 0 ? selection[0] : pageViewContext.page?.item.id;
403
+ if (currentItem && focusedField?.item.id !== currentItem) {
404
+ setFocusedField(undefined);
405
+ }
406
+ }, [selection]);
407
+ const addToEditHistory = (0, react_1.useCallback)((currentEditOperation) => {
408
+ setEditHistory((history) => {
409
+ // Check if the operation was updated or needs to be added
410
+ const exists = history.some((item) => item.id === currentEditOperation.id);
411
+ return exists ? history : [currentEditOperation, ...history];
412
+ });
413
+ }, []);
414
+ (0, react_1.useEffect)(() => {
415
+ setRefreshCompletedFlag(!refreshCompletedFlag);
416
+ setInserting(undefined);
417
+ }, [currentItemDescriptor, pageViewContext.page]);
418
+ (0, react_1.useEffect)(() => {
419
+ sendClientInfo();
420
+ }, [currentItemRef.current]);
421
+ const loadComments = (0, react_1.useCallback)(async () => {
422
+ if (!currentItemDescriptor)
423
+ return;
424
+ const result = await (0, reviewsService_1.getComments)(currentItemDescriptor.id, currentItemDescriptor.language, currentItemDescriptor.version);
425
+ if ((0, helpers_1.handleErrorResult)(result, ui, state))
426
+ return;
427
+ setComments((x) => {
428
+ const loadedComments = result.data;
429
+ const newComments = x.filter((c) => c.isNew &&
430
+ c.mainItemId === currentItemDescriptor.id &&
431
+ c.language === currentItemDescriptor.language &&
432
+ c.version === currentItemDescriptor.version);
433
+ var allComments = [...loadedComments, ...newComments];
434
+ allComments.sort((a, b) => a.position - b.position);
435
+ return allComments;
436
+ });
437
+ }, [currentItemDescriptor]);
438
+ const page = pageViewContext.page;
439
+ (0, react_1.useEffect)(() => {
440
+ const isLoading = !page || (page?.editRevision ?? "") != (revision ?? "");
441
+ setIsRefreshing(isLoading && viewName === "page-editor");
442
+ if (!isLoading)
443
+ setInserting(undefined);
444
+ }, [page, viewName, revision]);
445
+ (0, react_1.useEffect)(() => {
446
+ if (searchParams.get("fullscreen")) {
447
+ pageViewContext.setFullscreen(true);
448
+ }
449
+ const handleMessage = (event) => {
450
+ if (event.data.action === "refresh") {
451
+ requestRefresh("immediate");
452
+ }
453
+ };
454
+ window.addEventListener("message", handleMessage);
455
+ return () => {
456
+ window.removeEventListener("message", handleMessage);
457
+ };
458
+ }, []);
459
+ const loadHistory = (0, use_debounce_1.useDebouncedCallback)(async (item) => {
460
+ const result = await (0, editService_1.getEditHistory)(item);
461
+ if ((0, helpers_1.handleErrorResult)(result, ui, state))
462
+ return;
463
+ setEditHistory(result.data || []);
464
+ }, 200);
465
+ const refreshHistory = (0, react_1.useCallback)(async (item) => {
466
+ const result = await (0, editService_1.getEditHistory)(item);
467
+ if ((0, helpers_1.handleErrorResult)(result, ui, state))
468
+ return;
469
+ setEditHistory(result.data || []);
470
+ }, []);
471
+ const requestRefresh = (0, react_1.useCallback)((mode) => {
472
+ const refreshTimer = globalThis.editorRefreshTimer;
473
+ const doRefresh = () => {
474
+ //console.log("Refreshing");
475
+ //const url = new URL(window.location.href);
476
+ //url.searchParams.set("edit_rev", uuid());
477
+ const newRevision = (0, react_uuid_1.default)();
478
+ setRevision(newRevision);
479
+ console.log("doRefresh", newRevision);
480
+ //router.replace(url.toString(), { scroll: false });
481
+ globalThis.editorRefreshTimer = undefined;
482
+ };
483
+ if (mode === "immediate") {
484
+ // console.error(
485
+ // "Immediate refresh requested. Stack trace:",
486
+ // new Error().stack
487
+ // );
488
+ console.log("Immediate refresh requested");
489
+ doRefresh();
490
+ return;
491
+ }
492
+ //console.log("request refresh with mode: " + mode, "timer: ", refreshTimer);
493
+ if (mode === "waitForQuietPeriod" && refreshTimer) {
494
+ clearTimeout(refreshTimer);
495
+ }
496
+ if (!refreshTimer || mode === "waitForQuietPeriod") {
497
+ globalThis.editorRefreshTimer = setTimeout(() => {
498
+ doRefresh();
499
+ }, mode === "waitForQuietPeriod" ? 1200 : 700);
500
+ }
501
+ }, [contentEditorItem, router]);
502
+ (0, react_1.useEffect)(() => {
503
+ if (!currentItemDescriptor)
504
+ return;
505
+ loadComments();
506
+ }, [currentItemDescriptor]);
507
+ (0, react_1.useEffect)(() => {
508
+ if (!currentItemDescriptor)
509
+ return;
510
+ const current = new URLSearchParams(Array.from(searchParams.entries()));
511
+ if (current.get("itemid") !== currentItemDescriptor?.id) {
512
+ current.set("itemid", currentItemDescriptor.id);
513
+ }
514
+ if (current.get("lang") !== currentItemDescriptor?.language) {
515
+ current.set("lang", currentItemDescriptor.language);
516
+ }
517
+ if (current.get("version") !== currentItemDescriptor?.version.toString()) {
518
+ current.set("version", currentItemDescriptor.version.toString());
519
+ }
520
+ if (current.get("view") !== viewName) {
521
+ current.set("view", viewName);
522
+ }
523
+ if (!compareMode) {
524
+ current.delete("compare");
525
+ current.delete("compareLanguage");
526
+ current.delete("compareVersion");
527
+ current.delete("compareDevice");
528
+ }
529
+ else {
530
+ current.set("compare", "true");
531
+ }
532
+ if (previewMode) {
533
+ current.set("mode", "preview");
534
+ }
535
+ else {
536
+ current.delete("mode");
537
+ }
538
+ const newUrl = `${pathname}?${current.toString()}`;
539
+ router.push(newUrl, { scroll: false });
540
+ }, [currentItemDescriptor, viewName, compareMode, previewMode]);
541
+ (0, react_1.useEffect)(() => {
542
+ async function load() {
543
+ if (!currentItemDescriptor)
544
+ return;
545
+ const item = await itemsRepository.getItem(currentItemDescriptor);
546
+ setContentEditorItem(item);
547
+ if (!item)
548
+ return;
549
+ if (contentEditorItem?.descriptor.id === currentItemDescriptor.id &&
550
+ contentEditorItem?.descriptor.language ===
551
+ currentItemDescriptor.language &&
552
+ contentEditorItem?.descriptor.version !== item.version) {
553
+ showInfoToast({
554
+ summary: "New version!",
555
+ details: "New version of item loaded",
556
+ });
557
+ }
558
+ }
559
+ load();
560
+ }, [itemsRepository.revision]);
561
+ const addToBrowseHistory = (0, react_1.useCallback)((item) => {
562
+ let historyEntry = {
563
+ path: item.path || "unknown",
564
+ name: item.name || "unknown",
565
+ language: item.language,
566
+ templateName: item.templateName,
567
+ id: item.id,
568
+ hasLayout: item.hasLayout,
569
+ icon: item.icon,
570
+ version: item.version,
571
+ };
572
+ setBrowseHistory((history) => {
573
+ const newItem = item;
574
+ if (!newItem)
575
+ return history;
576
+ const newHistory = [
577
+ historyEntry,
578
+ ...history
579
+ .filter((x) => x.id !== newItem.id || x.language !== newItem.language)
580
+ .slice(0, 25),
581
+ ];
582
+ localStorage.setItem("editor.browseHistory", JSON.stringify(newHistory));
583
+ return newHistory;
584
+ });
585
+ }, [browseHistory, setBrowseHistory]);
586
+ const loadItem = (0, react_1.useCallback)(async (itemToLoad, options) => {
587
+ if (typeof itemToLoad === "string")
588
+ itemToLoad = {
589
+ id: itemToLoad,
590
+ language: contentEditorItem?.language || "en",
591
+ version: 0,
592
+ };
593
+ console.log("load item: " + itemToLoad.id, itemToLoad.language);
594
+ const item = await itemsRepository.getItem(itemToLoad);
595
+ if (!item) {
596
+ //TODO: Show error
597
+ console.log("item not found: ", itemToLoad.id, itemToLoad.language);
598
+ return undefined;
599
+ }
600
+ if (!item.hasLayout && viewName === "page-editor") {
601
+ setViewName("content-editor");
602
+ }
603
+ // Set state for the item
604
+ setCurrentItemDescriptor(itemToLoad);
605
+ setContentEditorItem(item);
606
+ setSelection([]);
607
+ // Directly update URL here
608
+ const current = new URLSearchParams(Array.from(searchParams.entries()));
609
+ current.set("itemid", itemToLoad.id);
610
+ current.set("lang", itemToLoad.language);
611
+ current.set("version", itemToLoad.version.toString());
612
+ current.set("view", viewName);
613
+ if (!compareMode) {
614
+ current.delete("compare");
615
+ current.delete("compareLanguage");
616
+ current.delete("compareVersion");
617
+ current.delete("compareDevice");
618
+ }
619
+ else {
620
+ current.set("compare", "true");
621
+ }
622
+ if (previewMode) {
623
+ current.set("mode", "preview");
624
+ }
625
+ else {
626
+ current.delete("mode");
627
+ }
628
+ const newUrl = `${pathname}?${current.toString()}`;
629
+ // Wait for the URL update to complete
630
+ await router.push(newUrl, { scroll: false });
631
+ // Now that URL is updated, load history and add to browse history
632
+ loadHistory(itemToLoad);
633
+ if (options?.addToBrowseHistory ||
634
+ options?.addToBrowseHistory === undefined) {
635
+ addToBrowseHistory(item);
636
+ }
637
+ return item;
638
+ }, [
639
+ itemsRepository,
640
+ setContentEditorItem,
641
+ searchParams,
642
+ pathname,
643
+ router,
644
+ viewName,
645
+ compareMode,
646
+ previewMode,
647
+ ]);
648
+ (0, react_1.useEffect)(() => {
649
+ if (pageViewContext.fullscreen && !searchParams.get("fullscreen"))
650
+ setShowFullscreenHint(true);
651
+ }, [pageViewContext.fullscreen]);
652
+ const executeCommand = (0, react_1.useCallback)(async ({ command, event, data, }) => {
653
+ if (!editContextRef.current)
654
+ return;
655
+ const context = {
656
+ editContext: editContextRef.current,
657
+ pathname,
658
+ router,
659
+ searchParams,
660
+ openDialog: dialogContext.openDialog,
661
+ event,
662
+ data,
663
+ };
664
+ const result = await command.execute(context);
665
+ return result;
666
+ }, [editContextRef, pathname, router, searchParams, dialogContext]);
667
+ const handleKeyDownDebounced = (0, use_debounce_1.useDebouncedCallback)(async (event) => {
668
+ if (!event.key)
669
+ return;
670
+ if (event.ctrlKey && event.key === "z") {
671
+ await operations.undo();
672
+ }
673
+ if (event.ctrlKey && event.key === "y") {
674
+ await operations.redo();
675
+ }
676
+ if (event.ctrlKey && event.key === "F11") {
677
+ event.preventDefault();
678
+ pageViewContext.setFullscreen(false);
679
+ }
680
+ const command = configuration.commands.allItemCommands.find((x) => x.keyBinding === event.key);
681
+ if (command) {
682
+ event.preventDefault();
683
+ const contentEditorItem = editContextRef.current?.contentEditorItem;
684
+ if (!contentEditorItem)
685
+ return;
686
+ const items = editContextRef.current?.selection?.map((x) => ({
687
+ id: x,
688
+ language: contentEditorItem.language,
689
+ version: 0,
690
+ })) || [];
691
+ if (!items.length)
692
+ items.push(contentEditorItem.descriptor);
693
+ if (items.length > 0) {
694
+ const fullItems = await editContextRef.current?.itemsRepository.getItems(items);
695
+ executeCommand({
696
+ command,
697
+ data: {
698
+ items: fullItems,
699
+ },
700
+ });
701
+ }
702
+ }
703
+ }, 50);
704
+ const handleKeyDown = (0, react_1.useCallback)(async (event) => {
705
+ if (event.key === "Insert") {
706
+ event.preventDefault();
707
+ event.stopPropagation();
708
+ editContext.setInsertMode((x) => !x);
709
+ }
710
+ if (event.ctrlKey && event.key === "s") {
711
+ event.preventDefault();
712
+ event.stopPropagation();
713
+ return;
714
+ }
715
+ const target = event.target;
716
+ const isTyping = target instanceof HTMLInputElement ||
717
+ target instanceof HTMLTextAreaElement ||
718
+ target.isContentEditable;
719
+ if ((event.ctrlKey && event.key === "z") ||
720
+ (event.ctrlKey && event.key === "y")) {
721
+ if (!isTyping) {
722
+ event.preventDefault();
723
+ event.stopPropagation();
724
+ handleKeyDownDebounced(event);
725
+ }
726
+ return;
727
+ }
728
+ handleKeyDownDebounced(event);
729
+ }, [
730
+ configuration.commands.allItemCommands,
731
+ executeCommand,
732
+ editContextRef.current,
733
+ ]);
734
+ if (typeof window !== "undefined")
735
+ if (typeof window !== "undefined")
736
+ (0, utils_1.useEventListenerExt)("keydown", handleKeyDown, window, true);
737
+ if (typeof window !== "undefined")
738
+ (0, utils_1.useEventListenerExt)("click", () => {
739
+ contextMenuRef.current?.close({});
740
+ }, window, true);
741
+ const state = (0, react_1.useMemo)(() => ({
742
+ page,
743
+ configuration,
744
+ selection,
745
+ setSelection,
746
+ loadItem,
747
+ addToEditHistory,
748
+ setLockedField,
749
+ contentEditorItem,
750
+ sessionId,
751
+ requestRefresh,
752
+ lockedField,
753
+ itemsRepository,
754
+ user,
755
+ editHistory,
756
+ refreshHistory,
757
+ }), [
758
+ page,
759
+ configuration,
760
+ selection,
761
+ setSelection,
762
+ loadItem,
763
+ addToEditHistory,
764
+ setLockedField,
765
+ contentEditorItem,
766
+ sessionId,
767
+ requestRefresh,
768
+ lockedField,
769
+ itemsRepository,
770
+ user,
771
+ editHistory,
772
+ refreshHistory,
773
+ ]);
774
+ (0, react_1.useEffect)(() => {
775
+ if (currentOverlay !== "ai")
776
+ aiPopupRef.current?.close();
777
+ if (currentOverlay !== "fields")
778
+ fieldEditorPopupRef.current?.close();
779
+ if (currentOverlay !== "context-menu")
780
+ contextMenuRef.current?.close({});
781
+ }, [currentOverlay]);
782
+ const toast = (0, react_1.useRef)(null);
783
+ (0, react_1.useEffect)(() => {
784
+ loadItemVersions();
785
+ }, [currentItemDescriptor]);
786
+ const loadItemVersions = (0, react_1.useCallback)(async () => {
787
+ if (!currentItemDescriptorRef.current) {
788
+ setItemVersions([]);
789
+ setItemLanguages([]);
790
+ return;
791
+ }
792
+ const result = await (0, contentService_1.getLanguagesAndVersions)(currentItemDescriptorRef.current);
793
+ if (!result?.data) {
794
+ setItemVersions([]);
795
+ setItemLanguages([]);
796
+ showErrorToast({
797
+ summary: "Error",
798
+ details: "Failed to load item versions",
799
+ });
800
+ return;
801
+ }
802
+ var v = [...result.data.versions].reverse() || [];
803
+ setItemVersions(v);
804
+ setItemLanguages(result.data.languages);
805
+ }, [currentItemDescriptorRef.current, setItemVersions, setItemLanguages]);
806
+ const showErrorToast = (0, react_1.useCallback)(({ summary, details }) => {
807
+ toast.current?.show({
808
+ severity: "error",
809
+ summary: summary || "Error",
810
+ detail: details || "An error occurred",
811
+ life: 3000,
812
+ });
813
+ }, []);
814
+ const showInfoToast = (0, react_1.useCallback)(({ summary, details }) => {
815
+ toast.current?.show({
816
+ severity: "info",
817
+ summary: summary || "Info",
818
+ detail: details || "Information",
819
+ life: 3000,
820
+ });
821
+ }, []);
822
+ const ui = (0, react_1.useMemo)(() => ({
823
+ showErrorToast,
824
+ confirmationDialogRef,
825
+ onOperationExecuted: (op) => {
826
+ // Replace the operation in edit history with the executed operation
827
+ setEditHistory((prev) => {
828
+ const existingOpIndex = prev.findIndex((x) => x.id === op.id);
829
+ if (existingOpIndex >= 0) {
830
+ prev[existingOpIndex] = op;
831
+ }
832
+ return prev;
833
+ });
834
+ if (contentEditorItem?.id === op.mainItem?.id &&
835
+ contentEditorItem?.language === op.mainItem?.language &&
836
+ contentEditorItem?.version === op.mainItem?.version) {
837
+ setInsertMode(false);
838
+ }
839
+ },
840
+ }), [showErrorToast, confirmationDialogRef, currentItemDescriptor]);
841
+ const selectMedia = (0, react_1.useCallback)(({ selectedIdPath, mode, }) => {
842
+ setSelectedMediaIdPath(selectedIdPath);
843
+ setMediaSelectorVisible(true);
844
+ if (mode)
845
+ setMediaSelectorMode(mode);
846
+ return new Promise((resolve) => {
847
+ setMediaResolver(() => resolve);
848
+ });
849
+ }, []);
850
+ const onMediaSelect = (0, react_1.useCallback)((mediaUrl) => {
851
+ mediaResolver?.(mediaUrl);
852
+ setMediaSelectorVisible(false);
853
+ setMediaResolver(undefined);
854
+ }, [mediaResolver]);
855
+ (0, react_1.useEffect)(() => {
856
+ if (!workboxItems || workboxItems.length === 0)
857
+ return;
858
+ const itemsToValidate = workboxItems.map((x) => x.item);
859
+ validate(itemsToValidate);
860
+ }, [workboxItems]);
861
+ async function loadWorkbox(items) {
862
+ if (!items.length) {
863
+ setWorkboxItems([]);
864
+ return;
865
+ }
866
+ const workbox = await (0, contentService_1.getWorkbox)(items);
867
+ const workboxItems = workbox.data || [];
868
+ const sortedWorkboxItems = workboxItems.sort((a, b) => {
869
+ if (a.isPublished === b.isPublished)
870
+ return ((b.workflowCommands?.length || 0) - (a.workflowCommands?.length || 0));
871
+ return !a.isPublished || !a.isPublishable ? -1 : 1;
872
+ });
873
+ setWorkboxItems(sortedWorkboxItems);
874
+ }
875
+ const loadWorkboxDebounced = (0, use_debounce_1.useDebouncedCallback)((items) => loadWorkbox(items), 3000);
876
+ (0, react_1.useEffect)(() => {
877
+ let items = [];
878
+ if (editContext.contentEditorItem) {
879
+ items.push(editContext.contentEditorItem.descriptor);
880
+ }
881
+ if (editContext.page) {
882
+ collectAllItems(editContext.page.rootComponent, items);
883
+ }
884
+ loadWorkboxDebounced(items.filter((x) => x));
885
+ }, [page, contentEditorItem]);
886
+ function collectAllItems(component, items) {
887
+ component.placeholders.forEach((x) => {
888
+ x.components.forEach((y) => {
889
+ if (y.isShared && y.datasourceItem) {
890
+ items.push(y.datasourceItem.descriptor);
891
+ }
892
+ y.datasourceItem?.fields.forEach((z) => {
893
+ if (z.type === "picture") {
894
+ const picture = z.value;
895
+ if (picture.variants) {
896
+ picture.variants.forEach((v) => {
897
+ if (v.mediaId) {
898
+ items.push({
899
+ id: v.mediaId,
900
+ language: y.datasourceItem.descriptor.language,
901
+ version: 0,
902
+ });
903
+ }
904
+ });
905
+ }
906
+ }
907
+ });
908
+ collectAllItems(y, items);
909
+ });
910
+ });
911
+ }
912
+ const switchView = (viewName) => {
913
+ document.startViewTransition(() => {
914
+ (0, react_dom_1.flushSync)(() => {
915
+ setViewName(viewName);
916
+ });
917
+ });
918
+ };
919
+ const operationsContext = (0, operations_1.getOperationsContext)(state, ui);
920
+ const operations = operationsContext.ops;
921
+ //const pageItem = page ? itemsRepository.getItem(page.item) : undefined;
922
+ const isReadOnly = false; //pageItem && (!pageItem.hasLock || !pageItem.canWrite);
923
+ const updateUrl = (0, react_1.useCallback)((params) => {
924
+ const url = new URL(window.location.href);
925
+ Object.entries(params).forEach(([key, value]) => {
926
+ if (value)
927
+ url.searchParams.set(key, value);
928
+ else
929
+ url.searchParams.delete(key);
930
+ });
931
+ router.push(url.toString(), { scroll: false });
932
+ }, []);
933
+ const editContext = (0, react_1.useMemo)(() => {
934
+ return {
935
+ operations: operationsContext.ops,
936
+ itemsRepository,
937
+ configuration,
938
+ updateUrl,
939
+ openSplashScreen: () => {
940
+ router.push("/alpaca/editor");
941
+ },
942
+ item: contentEditorItem || page?.item,
943
+ itemLanguages,
944
+ itemVersions,
945
+ sessionId: sessionId,
946
+ readonly: isReadOnly,
947
+ selection,
948
+ select: (ids) => {
949
+ setSelection(ids);
950
+ },
951
+ selectedForInsertion,
952
+ setSelectedForInsertion,
953
+ dragObject,
954
+ workboxItems,
955
+ requestRefresh,
956
+ refreshCompletedFlag,
957
+ openCreatePageDialog: () => {
958
+ const current = new URLSearchParams(Array.from(searchParams.entries()));
959
+ current.delete("version");
960
+ current.delete("itemid");
961
+ current.delete("view");
962
+ current.set("create", "1");
963
+ const newUrl = `${pathname}?${current.toString()}`;
964
+ router.push(newUrl, { scroll: false });
965
+ },
966
+ selectMedia,
967
+ showToast: (message) => {
968
+ toast.current?.show(message);
969
+ },
970
+ scrollIntoView,
971
+ setScrollIntoView,
972
+ focusedField,
973
+ setFocusedField: async (field, requestLock) => {
974
+ if (field) {
975
+ // if (nonComponentItems.find((x) => x.id == field.item.id))
976
+ // setSelection([field.item.id]);
977
+ setIgnoreBlur(true);
978
+ setTimeout(() => {
979
+ setIgnoreBlur(false);
980
+ }, 20);
981
+ setFocusedField({ ...field });
982
+ if (requestLock) {
983
+ return (await operations.ensureLock(field)) || false;
984
+ }
985
+ }
986
+ else {
987
+ if (!ignoreBlur) {
988
+ setFocusedField(undefined);
989
+ (0, editService_1.releaseFieldLocks)(sessionId);
990
+ }
991
+ }
992
+ return true;
993
+ },
994
+ renderedFields,
995
+ setRenderedFields,
996
+ getComponentCommands: (components) => {
997
+ return (0, componentCommands_1.getComponentCommands)(components, editContext);
998
+ },
999
+ dragStart: (dragObject) => {
1000
+ setDragObject(dragObject);
1001
+ },
1002
+ dragEnd: () => {
1003
+ setDragObject(undefined);
1004
+ },
1005
+ droppedInPlaceholder: async (placeholderKey, index, spotPositionElement, spotPositionAnchor, insertOption) => {
1006
+ if ((!dragObject && !insertOption) || !page)
1007
+ return;
1008
+ setDragObject(undefined);
1009
+ if (spotPositionElement && spotPositionAnchor) {
1010
+ setInserting({
1011
+ positionElement: spotPositionElement,
1012
+ positionAnchor: spotPositionAnchor,
1013
+ });
1014
+ }
1015
+ const placeholderKeyComponents = placeholderKey.split("_");
1016
+ const parentId = placeholderKeyComponents.length === 1
1017
+ ? undefined
1018
+ : placeholderKeyComponents[1];
1019
+ if (parentId)
1020
+ setSelection([parentId]);
1021
+ let op;
1022
+ if (insertOption) {
1023
+ operations.addComponent(insertOption.typeId, placeholderKey, index);
1024
+ return;
1025
+ }
1026
+ if (!dragObject)
1027
+ return;
1028
+ if (dragObject && dragObject.type == "template") {
1029
+ operations.addComponent(dragObject.typeId, placeholderKey, index);
1030
+ return;
1031
+ }
1032
+ if (dragObject.type == "component" ||
1033
+ (dragObject.type == "link-component" && dragObject.component)) {
1034
+ const parentComponent = parentId && page ? (0, componentTreeHelper_1.getComponentById)(parentId, page) : null;
1035
+ if (dragObject.type == "link-component") {
1036
+ op = {
1037
+ type: "link-component",
1038
+ mainItem: page.item.descriptor,
1039
+ parent: parentId && {
1040
+ id: parentId,
1041
+ language: page.item.descriptor.language,
1042
+ version: page.item.descriptor.version,
1043
+ name: parentComponent?.name,
1044
+ },
1045
+ placeholderKey,
1046
+ placeholderIndex: index,
1047
+ date: new Date().toISOString(),
1048
+ id: (0, react_uuid_1.default)(),
1049
+ linkedComponentItem: dragObject.component,
1050
+ description: "Link component",
1051
+ };
1052
+ }
1053
+ else {
1054
+ if (!dragObject.component)
1055
+ return;
1056
+ op = {
1057
+ type: "move-component",
1058
+ mainItem: page.item.descriptor,
1059
+ parent: parentId && {
1060
+ id: parentId,
1061
+ language: page.item.descriptor.language,
1062
+ version: page.item.descriptor.version,
1063
+ },
1064
+ placeholderKey,
1065
+ placeholderIndex: index,
1066
+ componentIds: [dragObject.component.id],
1067
+ date: new Date().toISOString(),
1068
+ id: (0, react_uuid_1.default)(),
1069
+ description: "Move component",
1070
+ };
1071
+ }
1072
+ }
1073
+ if (op)
1074
+ operations.executeEditOperation(op);
1075
+ },
1076
+ page,
1077
+ triggerFieldAction: async (fieldDescriptor, actionButton) => {
1078
+ const field = await itemsRepository.getField(fieldDescriptor);
1079
+ if (!field)
1080
+ return;
1081
+ const op = {
1082
+ field: fieldDescriptor,
1083
+ actionButton,
1084
+ state: "running",
1085
+ };
1086
+ const fieldItem = fieldDescriptor.item;
1087
+ setActiveFieldActions((prevFieldActions) => [
1088
+ ...prevFieldActions.filter((x) => !(x.field.fieldId == fieldDescriptor.fieldId &&
1089
+ x.field.item.id == fieldItem.id &&
1090
+ x.field.item.language == fieldItem.language &&
1091
+ x.field.item.version == fieldItem.version)),
1092
+ op,
1093
+ ]);
1094
+ if ("clientAction" in actionButton) {
1095
+ await actionButton.clientAction({
1096
+ field,
1097
+ editContext,
1098
+ dialogContext,
1099
+ });
1100
+ }
1101
+ if (actionButton.action) {
1102
+ await (0, editService_1.executeFieldAction)(fieldDescriptor.item, fieldDescriptor.fieldId, contentEditorItem.descriptor, actionButton.action, editContext.sessionId, selectedRange?.text || "", (data) => {
1103
+ op.message = data.responseText;
1104
+ setActiveFieldActions((prevFieldActions) => [
1105
+ ...prevFieldActions,
1106
+ ]);
1107
+ });
1108
+ itemsRepository.refreshItems([fieldDescriptor.item]);
1109
+ op.state = "success";
1110
+ requestRefresh("immediate");
1111
+ }
1112
+ },
1113
+ activeFieldActions,
1114
+ showContextMenu: (event, items) => {
1115
+ contextMenuRef.current?.show(event, items);
1116
+ setCurrentOverlay("context-menu");
1117
+ },
1118
+ showAiPopup: (event, aiTerminalOptions) => {
1119
+ setCurrentOverlay("ai");
1120
+ aiPopupRef.current?.show(event, aiTerminalOptions);
1121
+ },
1122
+ showFieldEditorPopup: (fields, sections, ev) => {
1123
+ setCurrentOverlay("fields");
1124
+ fieldEditorPopupRef.current?.show(fields, sections, ev);
1125
+ },
1126
+ inserting,
1127
+ validating,
1128
+ validationResult,
1129
+ contentEditorItem,
1130
+ loadItem,
1131
+ editHistory,
1132
+ isRefreshing,
1133
+ activeSessions,
1134
+ unlockField: async () => {
1135
+ await (0, editService_1.releaseFieldLocks)(sessionId);
1136
+ },
1137
+ isCommandDisabled: ({ command, data, }) => {
1138
+ const props = {
1139
+ editContext,
1140
+ pathname,
1141
+ router,
1142
+ searchParams,
1143
+ data,
1144
+ openDialog: dialogContext.openDialog,
1145
+ };
1146
+ return command.disabled(props);
1147
+ },
1148
+ executeCommand,
1149
+ viewName,
1150
+ switchView,
1151
+ compareMode,
1152
+ setCompareMode,
1153
+ view: currentView,
1154
+ pageView: pageViewContext,
1155
+ componentDesignerComponent,
1156
+ setComponentDesignerComponent,
1157
+ componentDesignerRendering,
1158
+ setComponentDesignerRendering,
1159
+ insertMode,
1160
+ setInsertMode,
1161
+ currentOverlay,
1162
+ setCurrentOverlay,
1163
+ inlineEditingFieldElement,
1164
+ setInlineEditingFieldElement,
1165
+ lockedField,
1166
+ timings,
1167
+ setTimings,
1168
+ selectedRange,
1169
+ setSelectedRange,
1170
+ confirmationDialogRef,
1171
+ confirm: (props) => {
1172
+ confirmationDialogRef.current?.confirm(props);
1173
+ },
1174
+ showMessageDialog: (props) => {
1175
+ confirmationDialogRef.current?.confirm({
1176
+ header: props.header,
1177
+ message: props.message,
1178
+ accept: () => { },
1179
+ acceptLabel: "Ok",
1180
+ });
1181
+ },
1182
+ browseHistory,
1183
+ setCenterPanelView,
1184
+ handleKeyDown,
1185
+ startTour,
1186
+ addSocketMessageListener,
1187
+ currentItemDescriptor,
1188
+ compareTo,
1189
+ setCompareTo,
1190
+ lastEditedFields,
1191
+ revision,
1192
+ selectedComment,
1193
+ setSelectedComment,
1194
+ comments,
1195
+ loadComments,
1196
+ setComments,
1197
+ showComments,
1198
+ setShowComments,
1199
+ addComment: async () => {
1200
+ if (!currentItemDescriptor)
1201
+ return;
1202
+ const itemId = focusedField?.item.id ||
1203
+ (selection.length > 0 ? selection[0] : undefined) ||
1204
+ currentItemDescriptor.id;
1205
+ if (!itemId)
1206
+ return;
1207
+ const language = currentItemDescriptor.language;
1208
+ const version = currentItemDescriptor.version;
1209
+ const getFieldName = async () => {
1210
+ if (!focusedField)
1211
+ return "";
1212
+ const field = await itemsRepository.getField(focusedField);
1213
+ return field?.name;
1214
+ };
1215
+ const getItemName = async () => {
1216
+ const item = await itemsRepository.getItem({
1217
+ id: itemId,
1218
+ language,
1219
+ version,
1220
+ });
1221
+ return item?.name;
1222
+ };
1223
+ const newComment = {
1224
+ id: (0, react_uuid_1.default)(),
1225
+ isNew: true,
1226
+ itemId: focusedField?.item.id || currentItemDescriptor.id,
1227
+ itemName: await getItemName(),
1228
+ fieldId: focusedField?.fieldId,
1229
+ fieldName: await getFieldName(),
1230
+ mainItemId: currentItemDescriptor.id,
1231
+ language,
1232
+ version,
1233
+ position: 0,
1234
+ rangeStart: selectedRange?.startOffset || 0,
1235
+ rangeEnd: selectedRange?.endOffset || 0,
1236
+ author: user?.name,
1237
+ authorDisplayName: user?.displayName,
1238
+ date: new Date().toISOString(),
1239
+ };
1240
+ setComments([newComment, ...comments]);
1241
+ setSelectedComment(newComment);
1242
+ setShowComments(true);
1243
+ },
1244
+ previewMode,
1245
+ setPreviewMode,
1246
+ user,
1247
+ reviews,
1248
+ statusMessage,
1249
+ setStatusMessage,
1250
+ };
1251
+ }, [
1252
+ operations,
1253
+ itemsRepository,
1254
+ configuration,
1255
+ contentEditorItem,
1256
+ page?.item,
1257
+ itemLanguages,
1258
+ itemVersions,
1259
+ sessionId,
1260
+ isReadOnly,
1261
+ selection,
1262
+ selectedForInsertion,
1263
+ dragObject,
1264
+ requestRefresh,
1265
+ refreshCompletedFlag,
1266
+ searchParams,
1267
+ pathname,
1268
+ router,
1269
+ selectMedia,
1270
+ scrollIntoView,
1271
+ focusedField,
1272
+ renderedFields,
1273
+ inserting,
1274
+ page,
1275
+ activeFieldActions,
1276
+ editHistory,
1277
+ isRefreshing,
1278
+ activeSessions,
1279
+ currentView,
1280
+ componentDesignerComponent,
1281
+ componentDesignerRendering,
1282
+ insertMode,
1283
+ currentOverlay,
1284
+ inlineEditingFieldElement,
1285
+ lockedField,
1286
+ selectedRange,
1287
+ pageViewContext,
1288
+ browseHistory,
1289
+ workboxItems,
1290
+ validating,
1291
+ setCenterPanelView,
1292
+ handleKeyDown,
1293
+ setTimings,
1294
+ timings,
1295
+ startTour,
1296
+ viewName,
1297
+ setViewName,
1298
+ compareMode,
1299
+ setCompareMode,
1300
+ addSocketMessageListener,
1301
+ currentItemDescriptor,
1302
+ compareTo,
1303
+ setCompareTo,
1304
+ lastEditedFields,
1305
+ revision,
1306
+ comments,
1307
+ setComments,
1308
+ selectedComment,
1309
+ setSelectedComment,
1310
+ loadComments,
1311
+ previewMode,
1312
+ setPreviewMode,
1313
+ showComments,
1314
+ setShowComments,
1315
+ user,
1316
+ reviews,
1317
+ statusMessage,
1318
+ setStatusMessage,
1319
+ ]);
1320
+ const modifiedFieldsContext = (0, react_1.useMemo)(() => {
1321
+ return {
1322
+ modifiedFields,
1323
+ setModifiedFields,
1324
+ };
1325
+ }, [modifiedFields, setModifiedFields]);
1326
+ (0, react_1.useEffect)(() => {
1327
+ editContextRef.current = editContext;
1328
+ }, [editContext]);
1329
+ if (!currentView)
1330
+ return null;
1331
+ return ((0, jsx_runtime_1.jsx)("div", { className: `${sans_1.GeistSans.className} editor h-full`, children: (0, jsx_runtime_1.jsx)(editContext_1.OperationsContextProvider, { value: operationsContext.context, children: (0, jsx_runtime_1.jsx)(editContext_1.ModifiedFieldsContextProvider, { value: modifiedFieldsContext, children: (0, jsx_runtime_1.jsxs)(editContext_1.EditContextProvider, { value: editContext, children: [pageViewContext.fullscreen ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 flex", children: (0, jsx_runtime_1.jsx)(PageViewerFrame_1.PageViewerFrame, { mode: editContext.previewMode ? "view" : "edit", pageViewContext: pageViewContext }) }), showFullscreenHint && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0", onMouseMoveCapture: () => {
1332
+ setTimeout(() => {
1333
+ setShowFullscreenHint(false);
1334
+ }, 600);
1335
+ }, children: (0, jsx_runtime_1.jsx)("div", { className: "fixed top-3 left-1/2 -translate-x-1/2 transform rounded-sm bg-gray-200 p-12", children: "Press Ctrl + F11 to exit fullscreen mode" }) }))] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(toast_1.Toast, { ref: toast }), (0, jsx_runtime_1.jsx)(ConfirmationDialog_1.default, { ref: confirmationDialogRef }), (0, jsx_runtime_1.jsx)(ContextMenu_1.EditContextMenu, { ref: contextMenuRef }), (0, jsx_runtime_1.jsx)(MainLayout_1.default, { className: className, view: currentView, centerPanelView: centerPanelView, rightSidebar: currentView.rightSidebar && ((0, jsx_runtime_1.jsx)(SidebarView_1.SidebarView, { sidebar: currentView.rightSidebar, editContext: editContext, active: true })), rightSidebarTitle: currentView.rightSidebar?.title }), mediaSelectorVisible && ((0, jsx_runtime_1.jsx)(MediaSelector_1.MediaSelector, { language: editContext.currentItemDescriptor.language, visible: mediaSelectorVisible, onHide: () => setMediaSelectorVisible(false), onMediaSelected: onMediaSelect, selectedIdPath: selectedMediaIdPath, mode: mediaSelectorMode })), (0, jsx_runtime_1.jsx)(AiPopup_1.AiPopup, { ref: aiPopupRef }), (0, jsx_runtime_1.jsx)(FieldEditorPopup_1.FieldEditorPopup, { ref: fieldEditorPopupRef }), isTourActive && ((0, jsx_runtime_1.jsx)(Tour_1.Tour, { tourStopCallback: () => setIsTourActive(false) }))] })), editContext.isRefreshing && ((0, jsx_runtime_1.jsx)("div", { className: "pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center text-gray-600 opacity-50 select-none", children: (0, jsx_runtime_1.jsx)(Spinner_1.Spinner, {}) }))] }) }) }) }));
1336
+ }