@alpaca-editor/core 1.0.3938 → 1.0.3941

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 (357) hide show
  1. package/dist/components/ActionButton.d.ts +1 -0
  2. package/dist/components/ActionButton.js +2 -2
  3. package/dist/components/ActionButton.js.map +1 -1
  4. package/dist/editor/ContentTree.js +12 -8
  5. package/dist/editor/ContentTree.js.map +1 -1
  6. package/dist/editor/ContextMenu.d.ts +1 -1
  7. package/dist/editor/ContextMenu.js +17 -3
  8. package/dist/editor/ContextMenu.js.map +1 -1
  9. package/dist/editor/FieldActionsOverlay.d.ts +18 -0
  10. package/dist/editor/FieldActionsOverlay.js +139 -0
  11. package/dist/editor/FieldActionsOverlay.js.map +1 -0
  12. package/dist/editor/FieldHistory.d.ts +2 -1
  13. package/dist/editor/FieldHistory.js +11 -8
  14. package/dist/editor/FieldHistory.js.map +1 -1
  15. package/dist/editor/FieldListField.js +14 -17
  16. package/dist/editor/FieldListField.js.map +1 -1
  17. package/dist/editor/PictureCropper.js +65 -23
  18. package/dist/editor/PictureCropper.js.map +1 -1
  19. package/dist/editor/PictureEditor.js +43 -3
  20. package/dist/editor/PictureEditor.js.map +1 -1
  21. package/dist/editor/Titlebar.js +19 -10
  22. package/dist/editor/Titlebar.js.map +1 -1
  23. package/dist/editor/ai/AiTerminal.js +27 -41
  24. package/dist/editor/ai/AiTerminal.js.map +1 -1
  25. package/dist/editor/ai/GhostWriter.js +21 -2
  26. package/dist/editor/ai/GhostWriter.js.map +1 -1
  27. package/dist/editor/client/EditorClient.js +48 -18
  28. package/dist/editor/client/EditorClient.js.map +1 -1
  29. package/dist/editor/client/editContext.d.ts +1 -1
  30. package/dist/editor/client/editContext.js.map +1 -1
  31. package/dist/editor/client/itemsRepository.js +126 -90
  32. package/dist/editor/client/itemsRepository.js.map +1 -1
  33. package/dist/editor/commands/componentCommands.js +7 -3
  34. package/dist/editor/commands/componentCommands.js.map +1 -1
  35. package/dist/editor/media-selector/MediaFolderBrowser.d.ts +5 -0
  36. package/dist/editor/media-selector/MediaFolderBrowser.js +77 -0
  37. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -0
  38. package/dist/editor/media-selector/MediaSelector.js +1 -1
  39. package/dist/editor/media-selector/MediaSelector.js.map +1 -1
  40. package/dist/editor/media-selector/Thumbnails.js +2 -2
  41. package/dist/editor/media-selector/index.d.ts +8 -0
  42. package/dist/editor/media-selector/index.js +9 -0
  43. package/dist/editor/media-selector/index.js.map +1 -0
  44. package/dist/editor/menubar/BrowseHistory.js +3 -4
  45. package/dist/editor/menubar/BrowseHistory.js.map +1 -1
  46. package/dist/editor/menubar/PageSelector.js +62 -10
  47. package/dist/editor/menubar/PageSelector.js.map +1 -1
  48. package/dist/editor/page-editor-chrome/FieldActionIndicator.js +1 -1
  49. package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
  50. package/dist/editor/page-editor-chrome/useInlineAICompletion.js +37 -11
  51. package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
  52. package/dist/editor/page-viewer/PageViewerFrame.js +98 -2
  53. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  54. package/dist/editor/pageModel.d.ts +14 -0
  55. package/dist/editor/reviews/Comment.js +3 -2
  56. package/dist/editor/reviews/Comment.js.map +1 -1
  57. package/dist/editor/services/aiService.js +0 -1
  58. package/dist/editor/services/aiService.js.map +1 -1
  59. package/dist/editor/services/editService.d.ts +1 -1
  60. package/dist/editor/services/editService.js +2 -1
  61. package/dist/editor/services/editService.js.map +1 -1
  62. package/dist/editor/sidebar/ComponentTree.js +3 -4
  63. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  64. package/dist/editor/ui/Icons.js +1 -1
  65. package/dist/editor/ui/Icons.js.map +1 -1
  66. package/dist/editor/ui/ItemList.d.ts +16 -0
  67. package/dist/editor/ui/ItemList.js +19 -0
  68. package/dist/editor/ui/ItemList.js.map +1 -0
  69. package/dist/editor/ui/ItemSearch.js +2 -12
  70. package/dist/editor/ui/ItemSearch.js.map +1 -1
  71. package/dist/editor/ui/SimpleTabs.d.ts +1 -0
  72. package/dist/editor/ui/SimpleTabs.js +3 -3
  73. package/dist/editor/ui/SimpleTabs.js.map +1 -1
  74. package/dist/editor/ui/Splitter.js +61 -6
  75. package/dist/editor/ui/Splitter.js.map +1 -1
  76. package/dist/editor/views/MediaFolderEditView.d.ts +4 -0
  77. package/dist/editor/views/MediaFolderEditView.js +40 -0
  78. package/dist/editor/views/MediaFolderEditView.js.map +1 -0
  79. package/dist/editor/views/SingleEditView.js +9 -1
  80. package/dist/editor/views/SingleEditView.js.map +1 -1
  81. package/dist/revision.d.ts +2 -2
  82. package/dist/revision.js +2 -2
  83. package/dist/styles.css +64 -13
  84. package/package.json +8 -2
  85. package/.prettierrc +0 -3
  86. package/build.css +0 -3
  87. package/components.json +0 -21
  88. package/eslint.config.mjs +0 -4
  89. package/images/bg-shape-black.webp +0 -0
  90. package/images/wizard-bg.png +0 -0
  91. package/images/wizard-tour.png +0 -0
  92. package/images/wizard.png +0 -0
  93. package/src/client-components/api.ts +0 -6
  94. package/src/client-components/index.ts +0 -19
  95. package/src/components/ActionButton.tsx +0 -41
  96. package/src/components/Error.tsx +0 -57
  97. package/src/components/ui/CardConnector.tsx +0 -56
  98. package/src/components/ui/button.tsx +0 -62
  99. package/src/components/ui/card.tsx +0 -372
  100. package/src/components/ui/context-menu.tsx +0 -250
  101. package/src/config/config.tsx +0 -917
  102. package/src/config/types.ts +0 -286
  103. package/src/editor/ComponentInfo.tsx +0 -90
  104. package/src/editor/ConfirmationDialog.tsx +0 -103
  105. package/src/editor/ContentTree.tsx +0 -727
  106. package/src/editor/ContextMenu.tsx +0 -212
  107. package/src/editor/Editor.tsx +0 -90
  108. package/src/editor/EditorWarning.tsx +0 -34
  109. package/src/editor/EditorWarnings.tsx +0 -33
  110. package/src/editor/FieldEditorPopup.tsx +0 -65
  111. package/src/editor/FieldHistory.tsx +0 -74
  112. package/src/editor/FieldList.tsx +0 -190
  113. package/src/editor/FieldListField.tsx +0 -391
  114. package/src/editor/FieldListFieldWithFallbacks.tsx +0 -217
  115. package/src/editor/FloatingToolbar.tsx +0 -163
  116. package/src/editor/ImageEditor.tsx +0 -128
  117. package/src/editor/ItemInfo.tsx +0 -90
  118. package/src/editor/LinkEditorDialog.tsx +0 -196
  119. package/src/editor/MainLayout.tsx +0 -95
  120. package/src/editor/MobileLayout.tsx +0 -68
  121. package/src/editor/NewEditorClient.tsx +0 -11
  122. package/src/editor/PictureCropper.tsx +0 -503
  123. package/src/editor/PictureEditor.tsx +0 -212
  124. package/src/editor/PictureEditorDialog.tsx +0 -381
  125. package/src/editor/PublishDialog.ignore +0 -74
  126. package/src/editor/ScrollingContentTree.tsx +0 -67
  127. package/src/editor/Terminal.tsx +0 -227
  128. package/src/editor/Titlebar.tsx +0 -93
  129. package/src/editor/ai/AiPopup.tsx +0 -59
  130. package/src/editor/ai/AiResponseMessage.tsx +0 -106
  131. package/src/editor/ai/AiTerminal.tsx +0 -514
  132. package/src/editor/ai/AiToolCall.tsx +0 -61
  133. package/src/editor/ai/EditorAiTerminal.tsx +0 -20
  134. package/src/editor/ai/GhostWriter.tsx +0 -432
  135. package/src/editor/ai/aiPageModel.ts +0 -108
  136. package/src/editor/ai/editorAiContext.ts +0 -18
  137. package/src/editor/client/AboutDialog.tsx +0 -44
  138. package/src/editor/client/EditorClient.tsx +0 -2197
  139. package/src/editor/client/GenericDialog.tsx +0 -50
  140. package/src/editor/client/editContext.ts +0 -412
  141. package/src/editor/client/helpers.ts +0 -44
  142. package/src/editor/client/itemsRepository.ts +0 -538
  143. package/src/editor/client/operations.ts +0 -768
  144. package/src/editor/client/pageModelBuilder.ts +0 -219
  145. package/src/editor/commands/commands.ts +0 -22
  146. package/src/editor/commands/componentCommands.tsx +0 -424
  147. package/src/editor/commands/createVersionCommand.ts +0 -33
  148. package/src/editor/commands/deleteVersionCommand.ts +0 -71
  149. package/src/editor/commands/itemCommands.tsx +0 -351
  150. package/src/editor/commands/localizeItem/LocalizeItemDialog.tsx +0 -201
  151. package/src/editor/commands/localizeItem/LocalizeItemUtils.ts +0 -27
  152. package/src/editor/commands/undo.ts +0 -39
  153. package/src/editor/component-designer/ComponentDesigner.tsx +0 -70
  154. package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx +0 -11
  155. package/src/editor/component-designer/ComponentDesignerMenu.tsx +0 -91
  156. package/src/editor/component-designer/ComponentEditor.tsx +0 -97
  157. package/src/editor/component-designer/ComponentRenderingCodeEditor.tsx +0 -31
  158. package/src/editor/component-designer/ComponentRenderingEditor.tsx +0 -104
  159. package/src/editor/component-designer/ComponentsDropdown.tsx +0 -39
  160. package/src/editor/component-designer/PlaceholdersEditor.tsx +0 -179
  161. package/src/editor/component-designer/RenderingsDropdown.tsx +0 -36
  162. package/src/editor/component-designer/TemplateEditor.tsx +0 -236
  163. package/src/editor/component-designer/aiContext.ts +0 -23
  164. package/src/editor/componentTreeHelper.tsx +0 -116
  165. package/src/editor/context-menu/CopyMoveMenu.tsx +0 -103
  166. package/src/editor/context-menu/InsertMenu.tsx +0 -347
  167. package/src/editor/control-center/About.tsx +0 -342
  168. package/src/editor/control-center/ControlCenterMenu.tsx +0 -76
  169. package/src/editor/control-center/IndexOverview.tsx +0 -50
  170. package/src/editor/control-center/IndexSettings.tsx +0 -266
  171. package/src/editor/control-center/Info.tsx +0 -104
  172. package/src/editor/control-center/QuotaInfo.tsx +0 -301
  173. package/src/editor/control-center/Status.tsx +0 -113
  174. package/src/editor/control-center/WebSocketMessages.tsx +0 -155
  175. package/src/editor/editor-warnings/ItemLocked.tsx +0 -63
  176. package/src/editor/editor-warnings/NoLanguageWriteAccess.tsx +0 -22
  177. package/src/editor/editor-warnings/NoWorkflowWriteAccess.tsx +0 -23
  178. package/src/editor/editor-warnings/NoWriteAccess.tsx +0 -16
  179. package/src/editor/editor-warnings/ValidationErrors.tsx +0 -54
  180. package/src/editor/field-types/AttachmentEditor.tsx +0 -9
  181. package/src/editor/field-types/CheckboxEditor.tsx +0 -47
  182. package/src/editor/field-types/DropLinkEditor.tsx +0 -80
  183. package/src/editor/field-types/DropListEditor.tsx +0 -84
  184. package/src/editor/field-types/ImageFieldEditor.tsx +0 -65
  185. package/src/editor/field-types/InternalLinkFieldEditor.tsx +0 -117
  186. package/src/editor/field-types/LinkFieldEditor.tsx +0 -85
  187. package/src/editor/field-types/MultiLineText.tsx +0 -82
  188. package/src/editor/field-types/PictureFieldEditor.tsx +0 -121
  189. package/src/editor/field-types/RawEditor.tsx +0 -53
  190. package/src/editor/field-types/ReactQuill.tsx +0 -580
  191. package/src/editor/field-types/RichTextEditor.tsx +0 -22
  192. package/src/editor/field-types/RichTextEditorComponent.tsx +0 -127
  193. package/src/editor/field-types/SingleLineText.tsx +0 -174
  194. package/src/editor/field-types/TreeListEditor.tsx +0 -261
  195. package/src/editor/fieldTypes.ts +0 -140
  196. package/src/editor/media-selector/AiImageSearch.tsx +0 -185
  197. package/src/editor/media-selector/AiImageSearchPrompt.tsx +0 -94
  198. package/src/editor/media-selector/MediaSelector.tsx +0 -42
  199. package/src/editor/media-selector/Preview.tsx +0 -14
  200. package/src/editor/media-selector/Thumbnails.tsx +0 -48
  201. package/src/editor/media-selector/TreeSelector.tsx +0 -292
  202. package/src/editor/media-selector/UploadZone.tsx +0 -137
  203. package/src/editor/menubar/ActionsMenu.tsx +0 -94
  204. package/src/editor/menubar/ActiveUsers.tsx +0 -17
  205. package/src/editor/menubar/ApproveAndPublish.tsx +0 -18
  206. package/src/editor/menubar/BrowseHistory.tsx +0 -37
  207. package/src/editor/menubar/ItemLanguageVersion.tsx +0 -76
  208. package/src/editor/menubar/LanguageSelector.tsx +0 -226
  209. package/src/editor/menubar/Menu.tsx +0 -83
  210. package/src/editor/menubar/NavButtons.tsx +0 -74
  211. package/src/editor/menubar/PageSelector.tsx +0 -141
  212. package/src/editor/menubar/PageViewerControls.tsx +0 -120
  213. package/src/editor/menubar/PreviewSecondaryControls.tsx +0 -18
  214. package/src/editor/menubar/SecondaryControls.tsx +0 -45
  215. package/src/editor/menubar/Separator.tsx +0 -12
  216. package/src/editor/menubar/SiteInfo.tsx +0 -53
  217. package/src/editor/menubar/User.tsx +0 -27
  218. package/src/editor/menubar/VersionSelector.tsx +0 -142
  219. package/src/editor/page-editor-chrome/CommentHighlighting.tsx +0 -307
  220. package/src/editor/page-editor-chrome/CommentHighlightings.tsx +0 -35
  221. package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +0 -59
  222. package/src/editor/page-editor-chrome/FieldActionIndicators.tsx +0 -23
  223. package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +0 -64
  224. package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +0 -35
  225. package/src/editor/page-editor-chrome/FrameMenu.tsx +0 -338
  226. package/src/editor/page-editor-chrome/FrameMenus.tsx +0 -48
  227. package/src/editor/page-editor-chrome/InlineEditor.tsx +0 -765
  228. package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +0 -61
  229. package/src/editor/page-editor-chrome/NoLayout.tsx +0 -36
  230. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +0 -122
  231. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +0 -161
  232. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +0 -169
  233. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +0 -315
  234. package/src/editor/page-editor-chrome/SuggestionHighlighting.tsx +0 -300
  235. package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +0 -40
  236. package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +0 -791
  237. package/src/editor/page-viewer/DeviceToolbar.tsx +0 -70
  238. package/src/editor/page-viewer/EditorForm.tsx +0 -258
  239. package/src/editor/page-viewer/MiniMap.tsx +0 -362
  240. package/src/editor/page-viewer/PageViewer.tsx +0 -169
  241. package/src/editor/page-viewer/PageViewerFrame.tsx +0 -879
  242. package/src/editor/page-viewer/pageModelSkeletonBuilder.ts +0 -412
  243. package/src/editor/page-viewer/pageViewContext.ts +0 -186
  244. package/src/editor/pageModel.ts +0 -208
  245. package/src/editor/picture-shared.tsx +0 -53
  246. package/src/editor/reviews/Comment.tsx +0 -308
  247. package/src/editor/reviews/Comments.tsx +0 -125
  248. package/src/editor/reviews/DiffView.tsx +0 -109
  249. package/src/editor/reviews/PreviewInfo.tsx +0 -35
  250. package/src/editor/reviews/Reviews.tsx +0 -280
  251. package/src/editor/reviews/SuggestedEdit.tsx +0 -316
  252. package/src/editor/reviews/reviewCommands.tsx +0 -47
  253. package/src/editor/reviews/useReviews.tsx +0 -70
  254. package/src/editor/services/aiService.ts +0 -174
  255. package/src/editor/services/componentDesignerService.ts +0 -151
  256. package/src/editor/services/contentService.ts +0 -180
  257. package/src/editor/services/editService.ts +0 -486
  258. package/src/editor/services/indexService.ts +0 -24
  259. package/src/editor/services/reviewsService.ts +0 -53
  260. package/src/editor/services/serviceHelper.ts +0 -95
  261. package/src/editor/services/suggestedEditsService.ts +0 -39
  262. package/src/editor/services/systemService.ts +0 -5
  263. package/src/editor/services/translationService.ts +0 -21
  264. package/src/editor/services-server/api.ts +0 -150
  265. package/src/editor/services-server/graphQL.ts +0 -106
  266. package/src/editor/sidebar/ComponentPalette.tsx +0 -161
  267. package/src/editor/sidebar/ComponentTree.tsx +0 -548
  268. package/src/editor/sidebar/ComponentTree2.tsxx +0 -490
  269. package/src/editor/sidebar/Debug.tsx +0 -111
  270. package/src/editor/sidebar/DictionaryEditor.tsx +0 -261
  271. package/src/editor/sidebar/EditHistory.tsx +0 -134
  272. package/src/editor/sidebar/GraphQL.tsx +0 -164
  273. package/src/editor/sidebar/Insert.tsx +0 -35
  274. package/src/editor/sidebar/MainContentTree.tsx +0 -102
  275. package/src/editor/sidebar/Performance.tsx +0 -53
  276. package/src/editor/sidebar/Sessions.tsx +0 -35
  277. package/src/editor/sidebar/Sidebar.tsx +0 -20
  278. package/src/editor/sidebar/SidebarView.tsx +0 -152
  279. package/src/editor/sidebar/Translations.tsx +0 -295
  280. package/src/editor/sidebar/Validation.tsx +0 -102
  281. package/src/editor/sidebar/ViewSelector.tsx +0 -60
  282. package/src/editor/sidebar/Workbox.tsx +0 -209
  283. package/src/editor/ui/CenteredMessage.tsx +0 -7
  284. package/src/editor/ui/CopyMoveTargetSelectorDialog.tsx +0 -81
  285. package/src/editor/ui/CopyToClipboardButton.tsx +0 -24
  286. package/src/editor/ui/DialogButtons.tsx +0 -11
  287. package/src/editor/ui/Icons.tsx +0 -708
  288. package/src/editor/ui/ItemNameDialogNew.tsx +0 -118
  289. package/src/editor/ui/ItemSearch.tsx +0 -190
  290. package/src/editor/ui/PerfectTree.tsx +0 -571
  291. package/src/editor/ui/Section.tsx +0 -35
  292. package/src/editor/ui/SimpleIconButton.tsx +0 -54
  293. package/src/editor/ui/SimpleMenu.tsx +0 -40
  294. package/src/editor/ui/SimpleTable.tsx +0 -60
  295. package/src/editor/ui/SimpleTabs.tsx +0 -55
  296. package/src/editor/ui/SimpleToolbar.tsx +0 -7
  297. package/src/editor/ui/Spinner.tsx +0 -9
  298. package/src/editor/ui/Splitter.tsx +0 -314
  299. package/src/editor/ui/StackedPanels.tsx +0 -134
  300. package/src/editor/ui/Toolbar.tsx +0 -7
  301. package/src/editor/utils/id-helper.ts +0 -3
  302. package/src/editor/utils/insertOptions.ts +0 -69
  303. package/src/editor/utils/itemutils.ts +0 -29
  304. package/src/editor/utils/useMemoDebug.ts +0 -28
  305. package/src/editor/utils.ts +0 -486
  306. package/src/editor/views/CompareView.tsx +0 -245
  307. package/src/editor/views/EditView.tsx +0 -27
  308. package/src/editor/views/ItemEditor.tsx +0 -58
  309. package/src/editor/views/SingleEditView.tsx +0 -46
  310. package/src/fonts/Geist-Black.woff2 +0 -0
  311. package/src/fonts/Geist-Bold.woff2 +0 -0
  312. package/src/fonts/Geist-ExtraBold.woff2 +0 -0
  313. package/src/fonts/Geist-ExtraLight.woff2 +0 -0
  314. package/src/fonts/Geist-Light.woff2 +0 -0
  315. package/src/fonts/Geist-Medium.woff2 +0 -0
  316. package/src/fonts/Geist-Regular.woff2 +0 -0
  317. package/src/fonts/Geist-SemiBold.woff2 +0 -0
  318. package/src/fonts/Geist-Thin.woff2 +0 -0
  319. package/src/fonts/Geist[wght].woff2 +0 -0
  320. package/src/fonts/index.ts +0 -10
  321. package/src/index.ts +0 -23
  322. package/src/lib/safelist.tsx +0 -16
  323. package/src/lib/utils.ts +0 -6
  324. package/src/page-wizard/PageWizard.tsx +0 -139
  325. package/src/page-wizard/WizardBox.tsx +0 -4
  326. package/src/page-wizard/WizardBoxConnector.tsx +0 -56
  327. package/src/page-wizard/WizardSteps.tsx +0 -458
  328. package/src/page-wizard/service.ts +0 -35
  329. package/src/page-wizard/startPageWizardCommand.ts +0 -26
  330. package/src/page-wizard/steps/BuildPageStep.tsx +0 -259
  331. package/src/page-wizard/steps/CollectStep.tsx +0 -296
  332. package/src/page-wizard/steps/ComponentTypesSelector.tsx +0 -454
  333. package/src/page-wizard/steps/Components.tsx +0 -193
  334. package/src/page-wizard/steps/ContentStep.tsx +0 -890
  335. package/src/page-wizard/steps/EditButton.tsx +0 -34
  336. package/src/page-wizard/steps/FieldEditor.tsx +0 -102
  337. package/src/page-wizard/steps/Generate.tsx +0 -60
  338. package/src/page-wizard/steps/ImagesStep.tsx +0 -382
  339. package/src/page-wizard/steps/LayoutStep.tsx +0 -227
  340. package/src/page-wizard/steps/MetaDataStep.tsx +0 -173
  341. package/src/page-wizard/steps/SelectStep.tsx +0 -281
  342. package/src/page-wizard/steps/schema.ts +0 -180
  343. package/src/page-wizard/steps/usePageCreator.ts +0 -325
  344. package/src/page-wizard/usePageWizard.ts +0 -79
  345. package/src/revision.ts +0 -2
  346. package/src/splash-screen/NewPage.tsx +0 -294
  347. package/src/splash-screen/OpenPage.tsx +0 -113
  348. package/src/splash-screen/RecentPages.tsx +0 -123
  349. package/src/splash-screen/SectionHeadline.tsx +0 -21
  350. package/src/splash-screen/SplashScreen.tsx +0 -195
  351. package/src/tour/Tour.tsx +0 -566
  352. package/src/tour/default-tour.tsx +0 -301
  353. package/src/tour/preview-tour.tsx +0 -128
  354. package/src/types.ts +0 -335
  355. package/styles.css +0 -765
  356. package/tsconfig.build.json +0 -31
  357. package/tsconfig.json +0 -14
@@ -1,890 +0,0 @@
1
- import { StepComponentProps } from "../../config/types";
2
-
3
- import { useEffect, useState, useCallback, useRef } from "react";
4
- import { getChildren } from "../../editor/services/contentService";
5
- import { getItemDescriptor } from "../../editor/utils";
6
- import { PageViewer } from "../../editor/page-viewer/PageViewer";
7
- import {
8
- useEditContext,
9
- useEditContextRef,
10
- useModifiedFieldsContext,
11
- } from "../../editor/client/editContext";
12
- import { ExecutionResult } from "../../editor/services/serviceHelper";
13
-
14
- import {
15
- ComponentTypeSelector,
16
- getComponentTypeSelectorSummary,
17
- } from "./ComponentTypesSelector";
18
- import { ActionButton } from "../../components/ActionButton";
19
- import { convertPageSchemaToWizardComponents } from "./schema";
20
- import { WizardPageModel } from "../PageWizard";
21
- import { createWizardAiContext, wipeComponents } from "../service";
22
-
23
- import { executePrompt } from "../../editor/services/aiService";
24
- import { usePageCreator } from "./usePageCreator";
25
- import { useThrottledCallback } from "use-debounce";
26
- import { InputTextarea } from "primereact/inputtextarea";
27
- import { InputText } from "primereact/inputtext";
28
- import { LanguageSelector } from "../../editor/menubar/LanguageSelector";
29
-
30
- import { convertToAiPageModel } from "../../editor/ai/aiPageModel";
31
- import { WizardBox } from "../WizardBox";
32
- import { Wand2, PanelsTopLeft, Settings, FileText } from "lucide-react";
33
- import { cn } from "../../lib/utils";
34
- import { WizardBoxConnector } from "../WizardBoxConnector";
35
- import { ItemDescriptor, FullItem } from "../../editor/pageModel";
36
- import Generate from "./Generate";
37
-
38
- export function ContentStep({
39
- wizard,
40
- step,
41
- parentItem,
42
- pageModel,
43
- setPageModel,
44
- data,
45
- setData,
46
- internalState,
47
- setInternalState,
48
- setStepCompleted,
49
- }: StepComponentProps) {
50
- const [pageLoaded, setPageLoaded] = useState(false);
51
- const pageLoadedRef = useRef(false);
52
- const [isLoading, setIsLoading] = useState(false);
53
- const [availableComponentTypes, setAvailableComponentTypes] = useState<
54
- string[]
55
- >([]);
56
-
57
- const editContext = useEditContext();
58
- const editContextRef = useEditContextRef();
59
- const [abortController, setAbortController] = useState<AbortController>();
60
- const [message, setMessage] = useState<string>();
61
- const [isCreatingComponents, setIsCreatingComponents] = useState(false);
62
- const [pageItem, setPageItem] = useState<ItemDescriptor>();
63
-
64
- // New state for name and language functionality
65
- const [isGenerating, setIsGenerating] = useState(false);
66
- const [language, setLanguage] = useState<string>(
67
- parentItem?.language || "en",
68
- );
69
- const [fullParentItem, setFullParentItem] = useState<FullItem>();
70
- const [nameValidation, setNameValidation] = useState<{
71
- isValid: boolean;
72
- message?: string;
73
- }>({ isValid: false });
74
-
75
- const modifiedFieldsContext = useModifiedFieldsContext();
76
-
77
- const pageCreator = usePageCreator(pageItem, wizard, setPageModel);
78
-
79
- if (!parentItem) return "No parent item";
80
-
81
- const checkPageName = useCallback(async () => {
82
- if (!parentItem) {
83
- setNameValidation({ isValid: false, message: "No parent item" });
84
- return false;
85
- }
86
-
87
- // Check if page name is valid
88
- if (!pageModel.name || pageModel.name.trim().length < 3) {
89
- setNameValidation({
90
- isValid: false,
91
- message: "Page name must be at least 3 characters long",
92
- });
93
- return false;
94
- }
95
-
96
- try {
97
- // Check if page with same name already exists
98
- const children = await getChildren(
99
- parentItem.id,
100
- editContext?.sessionId ?? "",
101
- [],
102
- false,
103
- editContext?.contentEditorItem?.language || "en",
104
- );
105
-
106
- if (
107
- children.find(
108
- (x) =>
109
- x.name.toLocaleLowerCase() ===
110
- pageModel.name.trim().toLocaleLowerCase(),
111
- )
112
- ) {
113
- setNameValidation({
114
- isValid: false,
115
- message: "A page with this name already exists",
116
- });
117
- return false;
118
- }
119
-
120
- setNameValidation({ isValid: true });
121
- return true;
122
- } catch (error) {
123
- setNameValidation({
124
- isValid: false,
125
- message: "Error checking page name",
126
- });
127
- return false;
128
- }
129
- }, [
130
- parentItem,
131
- pageModel.name,
132
- editContext?.sessionId,
133
- editContext?.contentEditorItem?.language,
134
- ]);
135
-
136
- const handleInputChange = (field: keyof typeof pageModel, value: string) => {
137
- const updatedPageModel = {
138
- ...pageModel,
139
- [field]: value,
140
- };
141
-
142
- setPageModel(updatedPageModel);
143
- };
144
-
145
- const createPageIfNeeded = useCallback(async (): Promise<boolean> => {
146
- if (!editContext || !parentItem || pageItem) return true; // Page already exists
147
-
148
- try {
149
- if (!(await checkPageName())) {
150
- console.error("Page name validation failed");
151
- return false;
152
- }
153
-
154
- const result = await editContext.operations.createItem(
155
- {
156
- ...getItemDescriptor(parentItem),
157
- language: parentItem.language || "en",
158
- },
159
- wizard.templateId,
160
- pageModel.name,
161
- );
162
-
163
- if (result) {
164
- editContext?.loadItem(result, { addToBrowseHistory: true });
165
- const item = await editContext?.itemsRepository.getItem(result);
166
- if (item && setPageItem) {
167
- setPageItem(item);
168
- return true;
169
- } else {
170
- console.error("Failed to load newly created item", result);
171
- return false;
172
- }
173
- }
174
- return false;
175
- } catch (error) {
176
- console.error("Error creating page", error);
177
- return false;
178
- }
179
- }, [
180
- editContext,
181
- parentItem,
182
- pageItem,
183
- checkPageName,
184
- wizard.templateId,
185
- pageModel.name,
186
- setPageItem,
187
- ]);
188
-
189
- useEffect(() => {
190
- editContext?.setMode("edit");
191
- if (!internalState.layoutInstructions) {
192
- setInternalState({
193
- ...internalState,
194
- layoutInstructions: step.fields.instructions,
195
- });
196
- }
197
-
198
- // Extract available component types from schema
199
- if (wizard.schema) {
200
- try {
201
- const schema =
202
- typeof wizard.schema === "string"
203
- ? JSON.parse(wizard.schema)
204
- : wizard.schema;
205
-
206
- // Extract component types (reusing logic from ComponentTypeSelector)
207
- const extractComponentTypes = (items: any): string[] => {
208
- if (!items || !Array.isArray(items)) return [];
209
- let types: string[] = [];
210
- for (const item of items) {
211
- if ("type" in item) {
212
- types.push(item.type);
213
- }
214
- if ("placeholders" in item && Array.isArray(item.placeholders)) {
215
- for (const placeholder of item.placeholders) {
216
- if (
217
- placeholder.components &&
218
- Array.isArray(placeholder.components)
219
- ) {
220
- types = [
221
- ...types,
222
- ...extractComponentTypes(placeholder.components),
223
- ];
224
- }
225
- }
226
- }
227
- if ("components" in item && Array.isArray(item.components)) {
228
- types = [...types, ...extractComponentTypes(item.components)];
229
- }
230
- }
231
- return types;
232
- };
233
-
234
- const componentTypes = extractComponentTypes(schema);
235
- const uniqueTypes = Array.from(new Set(componentTypes)).sort();
236
- setAvailableComponentTypes(uniqueTypes);
237
-
238
- // Initialize selected component types if not already set
239
- if (
240
- !data.selectedComponentTypes ||
241
- !Array.isArray(data.selectedComponentTypes)
242
- ) {
243
- // Parse preselected components from step if available
244
- let stepPreselectedTypes: string[] = [];
245
- if (step.fields["preselectedComponents"]) {
246
- stepPreselectedTypes = step.fields["preselectedComponents"]
247
- .split(/[,\n\r]+/)
248
- .map((type: string) => type.trim())
249
- .filter((type: string) => type && uniqueTypes.includes(type));
250
- }
251
-
252
- // Set initial selection
253
- const initialSelection =
254
- stepPreselectedTypes.length > 0
255
- ? stepPreselectedTypes
256
- : uniqueTypes;
257
-
258
- setData({
259
- ...data,
260
- selectedComponentTypes: initialSelection,
261
- });
262
- }
263
- } catch (error) {
264
- console.error("Error extracting component types:", error);
265
- }
266
- }
267
- }, []);
268
-
269
- // Check page name whenever it changes
270
- useEffect(() => {
271
- if (pageModel.name && !pageItem) {
272
- checkPageName();
273
- }
274
- }, [pageModel.name, checkPageName]);
275
-
276
- // Load parent item details
277
- useEffect(() => {
278
- const loadParentItem = async () => {
279
- if (!parentItem) return;
280
- const item = await editContext?.itemsRepository.getItem(parentItem);
281
- setFullParentItem(item);
282
- };
283
- loadParentItem();
284
- }, [parentItem]);
285
-
286
- // Auto-generate page name and meta description if not set
287
- useEffect(() => {
288
- if (!editContext) return;
289
-
290
- const generatePageName = async () => {
291
- const metaInstructions =
292
- step.fields["Instructions for generating item name and meta fields"];
293
-
294
- setIsGenerating(true);
295
-
296
- try {
297
- const abortController = new AbortController();
298
-
299
- const result = await executePrompt(
300
- [
301
- {
302
- content: `${metaInstructions?.trim()} Reply with a json object of type PageModel = { name: string; };
303
- The item name should be a valid sitecore item name. Spaces are allowed but no special characters or Umlaute.
304
- The language of the page is ${language}.
305
- Input data: ${JSON.stringify(data)}`,
306
- name: "system",
307
- role: "system",
308
- },
309
- ],
310
- editContext,
311
- createWizardAiContext,
312
- {},
313
- { signal: abortController.signal },
314
- "gpt-4.1",
315
- (response) => {
316
- try {
317
- const newLayout = JSON.parse(response.content) as WizardPageModel;
318
-
319
- setPageModel({
320
- ...pageModel,
321
- name: newLayout.name,
322
- });
323
- } catch (parseError: unknown) {}
324
- },
325
- );
326
-
327
- const pageModelResult = JSON.parse(result.content) as WizardPageModel;
328
- setPageModel({
329
- ...pageModel,
330
- name: pageModelResult.name,
331
- });
332
- } catch (error) {
333
- console.error("Error generating page name", error);
334
- } finally {
335
- setIsGenerating(false);
336
- }
337
- };
338
-
339
- if (!pageModel.name) generatePageName();
340
- }, []);
341
-
342
- const createComponents = async () => {
343
- if (!pageLoaded) return;
344
- if (pageModel?.components && !isCreatingComponents) {
345
- try {
346
- setIsCreatingComponents(true);
347
-
348
- await pageCreator.createComponentsRecursively(
349
- pageModel.components,
350
- "root",
351
- );
352
- setInternalState((prev: any) => ({
353
- ...prev,
354
- componentsCreated: true,
355
- }));
356
- } finally {
357
- setIsCreatingComponents(false);
358
- }
359
- }
360
- };
361
-
362
- useEffect(() => {
363
- if (
364
- internalState.componentsCreated &&
365
- !isCreatingComponents &&
366
- !isLoading
367
- ) {
368
- editContext?.requestRefresh("immediate");
369
- }
370
- }, [isCreatingComponents, isLoading]);
371
-
372
- const createComponentsThrottled = useThrottledCallback(createComponents, 300);
373
-
374
- useEffect(() => {
375
- createComponentsThrottled();
376
- }, [pageModel]);
377
-
378
- // useEffect(() => {
379
- // if (!pageItem) {
380
- // setPageItem(pageItem);
381
- // }
382
- // }, [pageItem]);
383
-
384
- useEffect(() => {
385
- //console.log("$$$$ Active field actions: ", editContext?.activeFieldActions);
386
- if (
387
- editContext &&
388
- editContext.activeFieldActions &&
389
- !editContext.activeFieldActions.find((x) => x.state === "running")
390
- ) {
391
- console.log("$$$ Refreshing!");
392
- editContext.requestRefresh("immediate");
393
- }
394
- }, [editContext?.activeFieldActions]);
395
-
396
- useEffect(() => {
397
- if (
398
- editContext &&
399
- editContext.page &&
400
- editContext.page.item &&
401
- pageItem &&
402
- pageItem.id === editContext.page.item.descriptor.id
403
- ) {
404
- if (!pageLoaded) {
405
- setTimeout(() => {
406
- setPageLoaded(true);
407
- pageLoadedRef.current = true;
408
- }, 1000);
409
- }
410
- }
411
- }, [editContext?.page, pageItem]);
412
-
413
- const createLayout = async () => {
414
- try {
415
- if (!editContext) return;
416
- setMessage("");
417
- setIsLoading(true);
418
- setStepCompleted(false);
419
-
420
- // Create page if it doesn't exist yet
421
- let currentPageItem = pageItem;
422
- // Wait for pageLoaded to become true before continuing
423
- const waitForPageLoaded = async (): Promise<boolean> => {
424
- const maxWaitTime = 10000; // 10 seconds max wait
425
- const pollInterval = 100; // Check every 100ms
426
- let elapsed = 0;
427
-
428
- while (elapsed < maxWaitTime) {
429
- // Check if page is loaded using the ref which gets updated by the useEffect
430
- if (pageLoadedRef.current) {
431
- return true;
432
- }
433
-
434
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
435
- elapsed += pollInterval;
436
- }
437
-
438
- return false;
439
- };
440
-
441
- if (!currentPageItem) {
442
- const pageCreated = await createPageIfNeeded();
443
- if (!pageCreated) {
444
- setMessage(
445
- "Failed to create page. Please check the page name and try again.",
446
- );
447
- setIsLoading(false);
448
- return;
449
- }
450
-
451
- const isPageLoaded = await waitForPageLoaded();
452
- if (!isPageLoaded) {
453
- setMessage("Page creation timed out. Please try again.");
454
- setIsLoading(false);
455
- return;
456
- }
457
- }
458
-
459
- if (internalState.componentsCreated) {
460
- console.log("Wiping components");
461
- if (currentPageItem) {
462
- const wipeResult: ExecutionResult<any> = await wipeComponents(
463
- getItemDescriptor(currentPageItem),
464
- );
465
- if (wipeResult.type !== "success") {
466
- console.error("Failed to wipe components:", wipeResult);
467
- setMessage(
468
- wipeResult.summary ||
469
- "Failed to clear existing components. Please try again.",
470
- );
471
- setIsLoading(false);
472
- return;
473
- }
474
- }
475
- console.log("Wiping components 2");
476
- editContextRef.current?.itemsRepository.clear();
477
- modifiedFieldsContext?.clear();
478
- setInternalState((prev: any) => ({
479
- ...prev,
480
- componentsCreated: false,
481
- }));
482
-
483
- setPageModel((prev) => ({
484
- ...prev,
485
- components: [],
486
- message: "",
487
- }));
488
-
489
- pageLoadedRef.current = false;
490
-
491
- console.log("Wiping components 3");
492
- editContextRef.current?.requestRefresh("immediate");
493
- await waitForPageLoaded();
494
- console.log("Wiping components 4");
495
- }
496
-
497
- // Parse schema if it's a string
498
- const schema =
499
- typeof wizard.schema === "string"
500
- ? JSON.parse(wizard.schema)
501
- : wizard.schema;
502
-
503
- // Filter the schema based on selected component types and placeholders
504
- const filteredSchema = convertPageSchemaToWizardComponents(
505
- schema,
506
- data.selectedComponentTypes,
507
- );
508
-
509
- const localAbortController = new AbortController();
510
- setAbortController(localAbortController);
511
-
512
- // Get the existing page model
513
- const existingPageModel = await convertToAiPageModel(
514
- editContextRef.current?.page!,
515
- editContextRef.current!,
516
- );
517
-
518
- console.log("Existing page model: ", existingPageModel);
519
-
520
- const prompt = [
521
- {
522
- content: `${internalState.layoutInstructions ? internalState.layoutInstructions?.trim() : ""} Reply with a json object of type PageModel = { components: Component[]; message: string; };
523
- Component = { id: string | undefined, name: string, type: string; fields: Field[]; placeholder?: string; children?: Component[]; };
524
- Field = { name: string; value: string; type: string; };
525
- Generate a descriptive name for each component including the topic.
526
- Only use component types that are in the page schema.
527
- Keep existing components with their ids. Leave id field empty for new components.
528
- Existing page model: ${JSON.stringify(existingPageModel)}
529
- Fill empty fields of existing components before you insert new components.
530
- Component types: ${JSON.stringify(
531
- filteredSchema,
532
- )} Root level component types ${filteredSchema
533
- .filter((c) => c.allowedOnRoot)
534
- .map((c) => c.type)
535
- .join(", ")}
536
- Tell the user your reasoning in the message field.
537
- If the user provided image ids, fill them into picture / image fields with an "id:" prefix. The image id needs to be guid.
538
- If you dont have a matching image id, provide a description of a picture that you would like to use with a "generate:" prefix instead.
539
- In any case the field value must start with "id:" or "generate:", nothing else. Do not inject json into picture fields even if the existing value is json.
540
- The language of the page is ${editContextRef.current!.page!.item!.language}.
541
- Input data: ${JSON.stringify(data)}`,
542
-
543
- name: "system",
544
- role: "system",
545
- },
546
- ];
547
-
548
- console.log("PAGE WIZARD PROMPT: ", prompt);
549
-
550
- const result = await executePrompt(
551
- prompt,
552
- editContextRef.current!,
553
- createWizardAiContext,
554
- { allowedFunctions: [] },
555
- { signal: localAbortController.signal },
556
- step.fields.aiModel || "gpt-4.1",
557
- (response) => {
558
- try {
559
- const newLayout = JSON.parse(response.content) as WizardPageModel;
560
-
561
- if (newLayout) {
562
- setPageModel((prev) => mergeLayout(prev, newLayout));
563
- }
564
-
565
- setMessage(newLayout.message);
566
- } catch (parseError: unknown) {}
567
- },
568
- );
569
-
570
- const pageModel = result;
571
-
572
- const finalLayout = JSON.parse(pageModel.content);
573
- console.log("RESULT LAYOUT: ", pageModel, finalLayout);
574
- setPageModel((prev) => mergeLayout(prev, finalLayout));
575
- setStepCompleted(true);
576
- } catch (error) {
577
- console.error(error);
578
- } finally {
579
- setIsLoading(false);
580
- }
581
- };
582
-
583
- // Custom instructions panel
584
- const customInstructionsPanel = () => {
585
- return (
586
- <InputTextarea
587
- value={internalState.layoutInstructions}
588
- onChange={(e) =>
589
- setInternalState({
590
- ...internalState,
591
- layoutInstructions: e.target.value,
592
- })
593
- }
594
- placeholder="Example: Make it modern and minimalist. Focus on images. Include a hero section at the top."
595
- className="h-48 w-full rounded border border-gray-300 px-3 py-2 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none"
596
- />
597
- );
598
- };
599
-
600
- return (
601
- <div className="flex h-full flex-col md:flex-row">
602
- <div className="flex flex-col items-stretch overflow-y-auto md:h-full">
603
- <WizardBox
604
- title="Page Setup"
605
- icon={<Settings />}
606
- description="Configure the page name, target location and language for your new page"
607
- collapsible="yes"
608
- summary={
609
- <div className="text-xs text-gray-500">
610
- Folder: {fullParentItem?.path}, Language: {language}, Name:{" "}
611
- {pageModel.name || "Not set"}
612
- </div>
613
- }
614
- className="w-full md:w-96"
615
- >
616
- <div className="flex flex-col items-stretch">
617
- <div className="relative flex-1">
618
- {isGenerating ? (
619
- <div className="flex h-full items-center justify-center">
620
- <Generate title="Generating page name..." />
621
- </div>
622
- ) : (
623
- <>
624
- <div className="mb-4">
625
- <label
626
- htmlFor="pageName"
627
- className="mb-1 block text-sm font-medium"
628
- >
629
- Page Name
630
- </label>
631
- <InputText
632
- id="pageName"
633
- type="text"
634
- disabled={!!pageItem}
635
- className={`w-full rounded border p-2 text-sm ${
636
- !nameValidation.isValid
637
- ? "border-red-500"
638
- : nameValidation.isValid && pageModel.name
639
- ? "border-green-500"
640
- : ""
641
- }`}
642
- value={pageModel.name}
643
- onChange={(e) =>
644
- handleInputChange("name", e.target.value)
645
- }
646
- placeholder="Enter page name"
647
- />
648
- {nameValidation.message && !nameValidation.isValid && (
649
- <div className="mt-1 text-xs text-red-600">
650
- {nameValidation.message}
651
- </div>
652
- )}
653
- {nameValidation.isValid && pageModel.name && (
654
- <div className="mt-1 text-xs text-green-600">
655
- ✓ Page name is available
656
- </div>
657
- )}
658
- </div>
659
-
660
- <div className="mb-4">
661
- <div className="mb-1 text-sm font-medium">
662
- Target Parent Item
663
- </div>
664
- <div className="mb-4 break-after-all text-xs text-gray-600">
665
- {fullParentItem?.path || "Loading..."}
666
- </div>
667
- </div>
668
-
669
- <div className="relative mb-4">
670
- <label
671
- htmlFor="language"
672
- className="mb-1 block text-sm font-medium"
673
- >
674
- Language
675
- </label>
676
- <div className="w-fit">
677
- <LanguageSelector
678
- selectedLanguage={language}
679
- darkMode={true}
680
- disabled={isGenerating}
681
- onLanguageSelected={(language) =>
682
- setLanguage(language.languageCode)
683
- }
684
- showAllLanguages={true}
685
- />
686
- </div>
687
- </div>
688
- </>
689
- )}
690
- </div>
691
- </div>
692
- </WizardBox>
693
- <WizardBoxConnector direction="vertical" />
694
- <WizardBox
695
- title="Content modules"
696
- icon={<Wand2 />}
697
- description="Select the component types the AI can choose from"
698
- className="w-full md:w-96"
699
- collapsible="yes"
700
- defaultCollapsed="yes"
701
- summary=<div className="text-xs text-gray-500">
702
- {getComponentTypeSelectorSummary(
703
- data.selectedComponentTypes,
704
- availableComponentTypes,
705
- )}
706
- </div>
707
- >
708
- <ComponentTypeSelector
709
- selectedComponentTypes={data.selectedComponentTypes}
710
- setSelectedComponentTypes={(selectedTypes) => {
711
- setData({
712
- ...data,
713
- selectedComponentTypes: selectedTypes,
714
- });
715
- }}
716
- schema={wizard.schema}
717
- data={data}
718
- setData={setData}
719
- step={step}
720
- />
721
- </WizardBox>
722
- <WizardBoxConnector direction="vertical" />
723
- <WizardBox
724
- title="Generate content"
725
- icon={<Wand2 />}
726
- collapsible="yes"
727
- defaultCollapsed="mobileOnly"
728
- description="Refine instructions and generate content"
729
- className="w-full md:w-96"
730
- footer={
731
- <div>
732
- <div className="flex w-full gap-2">
733
- <ActionButton
734
- onClick={createLayout}
735
- disabled={
736
- isLoading ||
737
- isCreatingComponents ||
738
- !data.selectedComponentTypes ||
739
- data.selectedComponentTypes.length === 0 ||
740
- (!pageItem &&
741
- (!pageModel.name ||
742
- pageModel.name.trim().length < 3 ||
743
- !nameValidation.isValid))
744
- }
745
- isLoading={
746
- isLoading ||
747
- isCreatingComponents ||
748
- !!editContext?.activeFieldActions.find(
749
- (action) => action.state === "running",
750
- )
751
- }
752
- loadingText={"Working"}
753
- className="w-full flex-1"
754
- >
755
- {!pageItem ? "Create page" : "Delete & Regenerate content"}
756
- </ActionButton>
757
-
758
- {isLoading && (
759
- <ActionButton
760
- isLoading={false}
761
- onClick={() => abortController?.abort("User aborted")}
762
- >
763
- Abort
764
- </ActionButton>
765
- )}
766
- </div>
767
- {message && <div className="mt-2 text-xs">{message}</div>}
768
- </div>
769
- }
770
- >
771
- <div>{customInstructionsPanel()}</div>
772
- </WizardBox>
773
- </div>
774
- {pageItem && (
775
- <>
776
- <WizardBoxConnector />
777
- <WizardBox
778
- title="Page preview"
779
- icon={<PanelsTopLeft />}
780
- description="After finalizing the page, you can edit, further enhance the content and share the page with your team for collaboration."
781
- noPadding={true}
782
- className="flex-1"
783
- showFullscreenButton={true}
784
- >
785
- <div
786
- className={cn(
787
- "min-h-[300px] border-t border-gray-200",
788
- pageLoaded ? "h-full" : "h-0",
789
- )}
790
- >
791
- <PageViewer
792
- name="single"
793
- compareView={false}
794
- showFormEditor={false}
795
- followEditsDefault={true}
796
- pageViewContext={editContext!.pageView}
797
- />
798
- </div>
799
- </WizardBox>
800
- </>
801
- )}
802
- </div>
803
- );
804
- }
805
-
806
- /**
807
- * Merges a new layout with the previous layout
808
- * - Keeps all previous components
809
- * - Adds new components
810
- * - Updates existing fields with new values
811
- * - Adds new fields
812
- */
813
- const mergeLayout = (
814
- prev: WizardPageModel | null,
815
- newLayout: WizardPageModel,
816
- ): WizardPageModel => {
817
- if (!prev) return newLayout;
818
-
819
- // Merge top-level properties
820
- const result: WizardPageModel = {
821
- name: newLayout.name || prev.name,
822
- message: newLayout.message,
823
- metaDescription: prev.metaDescription,
824
- metaKeywords: prev.metaKeywords,
825
- components: [...(prev.components || [])],
826
- };
827
-
828
- // Function to merge components recursively
829
- const mergeComponents = (
830
- existingComponents: any[],
831
- newComponents: any[],
832
- ): any[] => {
833
- if (!newComponents?.length) return existingComponents;
834
-
835
- const result = [...existingComponents];
836
-
837
- for (const newComp of newComponents) {
838
- // Try to find a matching component by type and name
839
- const existingIndex = result.findIndex(
840
- (comp) => comp.type === newComp.type && comp.name === newComp.name,
841
- );
842
-
843
- if (existingIndex >= 0) {
844
- // Update existing component
845
- const existing = result[existingIndex];
846
-
847
- // Merge fields - update existing fields and add new ones
848
- const mergedFields = [...(existing.fields || [])];
849
- for (const newField of newComp.fields || []) {
850
- const fieldIndex = mergedFields.findIndex(
851
- (f) => f.name === newField.name,
852
- );
853
- if (fieldIndex >= 0) {
854
- mergedFields[fieldIndex].value = newField.value; // Update existing field
855
- mergedFields[fieldIndex].type = newField.type;
856
- } else {
857
- mergedFields.push(newField); // Add new field
858
- }
859
- }
860
-
861
- // Recursive merge of children components
862
- const mergedChildren = mergeComponents(
863
- existing.children || [],
864
- newComp.children || [],
865
- );
866
-
867
- // Create updated component
868
- result[existingIndex] = {
869
- ...existing,
870
- fields: mergedFields,
871
- children: mergedChildren,
872
- placeholder: newComp.placeholder || existing.placeholder,
873
- };
874
- } else {
875
- // Add new component
876
- result.push(newComp);
877
- }
878
- }
879
-
880
- return result;
881
- };
882
-
883
- // Merge components recursively
884
- result.components = mergeComponents(
885
- result.components,
886
- newLayout.components || [],
887
- );
888
-
889
- return result;
890
- };