@alpaca-editor/core 1.0.3813 → 1.0.3815

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 (117) hide show
  1. package/dist/components/ui/context-menu.d.ts +25 -0
  2. package/dist/components/ui/context-menu.js +51 -0
  3. package/dist/components/ui/context-menu.js.map +1 -0
  4. package/dist/config/config.js +3 -2
  5. package/dist/config/config.js.map +1 -1
  6. package/dist/config/types.d.ts +4 -2
  7. package/dist/editor/ComponentInfo.js +1 -1
  8. package/dist/editor/ComponentInfo.js.map +1 -1
  9. package/dist/editor/ConfirmationDialog.d.ts +1 -1
  10. package/dist/editor/ContextMenu.d.ts +1 -1
  11. package/dist/editor/ContextMenu.js +24 -9
  12. package/dist/editor/ContextMenu.js.map +1 -1
  13. package/dist/editor/ImageEditor.js +2 -2
  14. package/dist/editor/ImageEditor.js.map +1 -1
  15. package/dist/editor/ItemInfo.js +2 -2
  16. package/dist/editor/ItemInfo.js.map +1 -1
  17. package/dist/editor/MainLayout.js +3 -3
  18. package/dist/editor/MainLayout.js.map +1 -1
  19. package/dist/editor/Titlebar.js +1 -1
  20. package/dist/editor/Titlebar.js.map +1 -1
  21. package/dist/editor/ai/AiTerminal.js +19 -12
  22. package/dist/editor/ai/AiTerminal.js.map +1 -1
  23. package/dist/editor/client/EditorClient.js +19 -4
  24. package/dist/editor/client/EditorClient.js.map +1 -1
  25. package/dist/editor/client/editContext.d.ts +1 -1
  26. package/dist/editor/client/operations.js +15 -14
  27. package/dist/editor/client/operations.js.map +1 -1
  28. package/dist/editor/client/pageModelBuilder.js +8 -5
  29. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  30. package/dist/editor/commands/componentCommands.js +15 -13
  31. package/dist/editor/commands/componentCommands.js.map +1 -1
  32. package/dist/editor/componentTreeHelper.js +3 -3
  33. package/dist/editor/componentTreeHelper.js.map +1 -1
  34. package/dist/editor/control-center/ControlCenterMenu.js +3 -3
  35. package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
  36. package/dist/editor/field-types/TreeListEditor.js +4 -4
  37. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  38. package/dist/editor/page-editor-chrome/FrameMenu.js +52 -14
  39. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  40. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +5 -5
  41. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  42. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +114 -45
  43. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  44. package/dist/editor/page-viewer/PageViewerFrame.d.ts +0 -1
  45. package/dist/editor/page-viewer/PageViewerFrame.js +119 -215
  46. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  47. package/dist/editor/page-viewer/pageModelBuilder.d.ts +3 -0
  48. package/dist/editor/page-viewer/pageModelBuilder.js +299 -0
  49. package/dist/editor/page-viewer/pageModelBuilder.js.map +1 -0
  50. package/dist/editor/pageModel.d.ts +5 -0
  51. package/dist/editor/sidebar/ComponentPalette.js +30 -30
  52. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  53. package/dist/editor/sidebar/ComponentTree.js +7 -6
  54. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  55. package/dist/editor/sidebar/MainContentTree.js +1 -1
  56. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  57. package/dist/editor/sidebar/SidebarView.js +3 -3
  58. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  59. package/dist/editor/ui/CopyToClipboardButton.js +2 -1
  60. package/dist/editor/ui/CopyToClipboardButton.js.map +1 -1
  61. package/dist/editor/ui/Icons.d.ts +0 -1
  62. package/dist/editor/ui/Icons.js +0 -3
  63. package/dist/editor/ui/Icons.js.map +1 -1
  64. package/dist/editor/ui/Section.js +1 -1
  65. package/dist/editor/ui/Section.js.map +1 -1
  66. package/dist/editor/ui/SimpleMenu.d.ts +1 -8
  67. package/dist/editor/ui/SimpleMenu.js +1 -1
  68. package/dist/editor/ui/SimpleMenu.js.map +1 -1
  69. package/dist/editor/utils.d.ts +2 -2
  70. package/dist/editor/utils.js +57 -9
  71. package/dist/editor/utils.js.map +1 -1
  72. package/dist/lib/safelist.js +1 -1
  73. package/dist/lib/safelist.js.map +1 -1
  74. package/dist/splash-screen/SplashScreen.js +0 -1
  75. package/dist/splash-screen/SplashScreen.js.map +1 -1
  76. package/dist/styles.css +242 -59
  77. package/dist/types.d.ts +2 -2
  78. package/package.json +3 -2
  79. package/src/components/ui/context-menu.tsx +250 -0
  80. package/src/config/config.tsx +2 -2
  81. package/src/config/types.ts +4 -2
  82. package/src/editor/ComponentInfo.tsx +3 -5
  83. package/src/editor/ConfirmationDialog.tsx +1 -1
  84. package/src/editor/ContextMenu.tsx +68 -19
  85. package/src/editor/ImageEditor.tsx +2 -2
  86. package/src/editor/ItemInfo.tsx +4 -4
  87. package/src/editor/MainLayout.tsx +3 -4
  88. package/src/editor/Titlebar.tsx +1 -1
  89. package/src/editor/ai/AiTerminal.tsx +31 -24
  90. package/src/editor/client/EditorClient.tsx +23 -6
  91. package/src/editor/client/editContext.ts +1 -1
  92. package/src/editor/client/operations.ts +16 -14
  93. package/src/editor/client/pageModelBuilder.ts +26 -18
  94. package/src/editor/commands/componentCommands.tsx +58 -39
  95. package/src/editor/componentTreeHelper.tsx +3 -2
  96. package/src/editor/control-center/ControlCenterMenu.tsx +4 -4
  97. package/src/editor/field-types/TreeListEditor.tsx +11 -11
  98. package/src/editor/page-editor-chrome/FrameMenu.tsx +81 -17
  99. package/src/editor/page-editor-chrome/InlineEditor.tsx +5 -5
  100. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +12 -15
  101. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +159 -68
  102. package/src/editor/page-viewer/PageViewerFrame.tsx +131 -300
  103. package/src/editor/page-viewer/pageModelBuilder.ts +412 -0
  104. package/src/editor/pageModel.ts +5 -0
  105. package/src/editor/sidebar/ComponentPalette.tsx +108 -106
  106. package/src/editor/sidebar/ComponentTree.tsx +10 -5
  107. package/src/editor/sidebar/MainContentTree.tsx +1 -1
  108. package/src/editor/sidebar/SidebarView.tsx +9 -9
  109. package/src/editor/ui/CopyToClipboardButton.tsx +2 -1
  110. package/src/editor/ui/Icons.tsx +0 -18
  111. package/src/editor/ui/Section.tsx +4 -4
  112. package/src/editor/ui/SimpleMenu.tsx +5 -13
  113. package/src/editor/utils.ts +74 -17
  114. package/src/lib/safelist.tsx +2 -0
  115. package/src/splash-screen/SplashScreen.tsx +0 -1
  116. package/src/types.ts +2 -4
  117. package/styles.css +58 -17
@@ -99,7 +99,7 @@ export function AiTerminal({
99
99
  setProfiles(profiles);
100
100
  if (!activeProfile)
101
101
  setActiveProfile(
102
- profiles.find((x) => x.name == defaultProfile) || profiles[0]
102
+ profiles.find((x) => x.name == defaultProfile) || profiles[0],
103
103
  );
104
104
  }
105
105
  fetchProfiles();
@@ -116,7 +116,7 @@ export function AiTerminal({
116
116
 
117
117
  async function commandHandler(
118
118
  text: string,
119
- callback: (text: React.ReactNode, finished: boolean) => void
119
+ callback: (text: React.ReactNode, finished: boolean) => void,
120
120
  ) {
121
121
  const newMessages = [
122
122
  ...messagesRef.current,
@@ -180,18 +180,25 @@ export function AiTerminal({
180
180
  if (isEditTextFieldOp(op)) {
181
181
  const editFieldOp = op as EditFieldOperation;
182
182
 
183
- if (editFieldOp.item) {
183
+ if (editFieldOp.itemId) {
184
+ const fieldDescriptor = {
185
+ item: {
186
+ ...editFieldOp.mainItem,
187
+ id: editFieldOp.itemId,
188
+ },
189
+ fieldId: editFieldOp.fieldId,
190
+ };
184
191
  editContext.itemsRepository.updateFieldValue(
185
- editFieldOp,
192
+ fieldDescriptor,
186
193
  editFieldOp.user ?? { name: "unknown", ai: false },
187
194
  false,
188
- editFieldOp.value
195
+ editFieldOp.value,
189
196
  );
190
197
 
191
- editContext.select([editFieldOp.item.id]);
192
- editContext.setScrollIntoView(editFieldOp.item.id);
198
+ editContext.select([editFieldOp.itemId]);
199
+ editContext.setScrollIntoView(editFieldOp.itemId);
193
200
 
194
- editContext?.setFocusedField(editFieldOp, false);
201
+ editContext?.setFocusedField(fieldDescriptor, false);
195
202
  }
196
203
  } else {
197
204
  const addOp = op as AddComponentOperation;
@@ -203,7 +210,7 @@ export function AiTerminal({
203
210
  }
204
211
  });
205
212
  }
206
- }
213
+ },
207
214
  );
208
215
 
209
216
  if (response) {
@@ -233,11 +240,11 @@ export function AiTerminal({
233
240
 
234
241
  return (
235
242
  <div
236
- className="h-full flex flex-col relative flex-1 pl-1.5"
243
+ className="relative flex h-full flex-1 flex-col pl-1.5"
237
244
  data-testid="ai-terminal"
238
245
  >
239
- <div className="flex-1 relative">
240
- <div className="inset-0 absolute tour-ai-terminal">
246
+ <div className="relative flex-1">
247
+ <div className="tour-ai-terminal absolute inset-0">
241
248
  <Terminal
242
249
  disabled={!model}
243
250
  ref={terminalRef}
@@ -248,7 +255,7 @@ export function AiTerminal({
248
255
  infobar={
249
256
  response?.numInputTokens && (
250
257
  <div
251
- className="text-gray-400 text-right"
258
+ className="text-right text-gray-400"
252
259
  style={{ fontSize: "10px" }}
253
260
  >
254
261
  Tokens in: {response?.numInputTokens?.toLocaleString()} out:{" "}
@@ -262,18 +269,18 @@ export function AiTerminal({
262
269
  }
263
270
  prompt={prompt}
264
271
  setPrompt={setPrompt}
265
- statusbar=<div className="flex items-center justify-between gap-1 flex-1">
272
+ statusbar=<div className="flex flex-1 items-center justify-between gap-1">
266
273
  <a
267
- className="text-xs text-blue-300 cursor-pointer flex items-center gap-1 ml-1"
274
+ className="ml-1 flex cursor-pointer items-center gap-1 text-xs text-blue-300"
268
275
  onClick={() => {
269
276
  setShowPredefined(!showPredefined);
270
277
  }}
271
278
  >
272
- <WizardIcon className="w-5 h-5" />
279
+ <WizardIcon className="h-5 w-5" />
273
280
  Predefined prompts
274
281
  </a>
275
282
  {editContext.selection?.length > 0 && (
276
- <div className="text-xs text-red-400 flex items-center mr-2">
283
+ <div className="mr-2 flex items-center text-xs text-red-400">
277
284
  {editContext.selection.length} items selected
278
285
  <SimpleIconButton
279
286
  icon="pi pi-times"
@@ -285,12 +292,12 @@ export function AiTerminal({
285
292
  </div>
286
293
  )}
287
294
  {showPredefined && (
288
- <div className="absolute right-0 left-0 bottom-8 text-sm overflow-y-auto bg-white p-3 pb-1 flex flex-col gap-1 ">
295
+ <div className="absolute right-0 bottom-8 left-0 flex flex-col gap-1 overflow-y-auto bg-white p-3 pb-1 text-sm">
289
296
  {activeProfile &&
290
297
  activeProfile.prompts.map((p, index) => (
291
298
  <div
292
299
  key={index}
293
- className="p-1.5 mb-1 border border-gray-200 rounded-lg cursor-pointer text-gray-700 text-xs"
300
+ className="mb-1 cursor-pointer rounded-lg border border-gray-200 p-1.5 text-xs text-gray-700"
294
301
  onClick={() => {
295
302
  setPrompt(p.prompt);
296
303
  setShowPredefined(false);
@@ -326,12 +333,12 @@ export function AiTerminal({
326
333
  />
327
334
  </div>
328
335
  {activeProfile?.errorMessage && (
329
- <div className="text-red-500 text-sm p-2 inset-0 absolute grid items-center justify-center">
336
+ <div className="absolute inset-0 grid items-center justify-center p-2 text-sm text-red-500">
330
337
  {activeProfile?.errorMessage}
331
338
  </div>
332
339
  )}
333
340
  {!model && (
334
- <div className="inset-0 absolute grid items-center justify-center text-gray-400 text-sm">
341
+ <div className="absolute inset-0 grid items-center justify-center text-sm text-gray-400">
335
342
  {!activeProfile ? "No profile selected" : "No model selected"}
336
343
  </div>
337
344
  )}
@@ -348,7 +355,7 @@ async function executePrompt(
348
355
  model: string | null,
349
356
  selectedText: string | null,
350
357
  context: AiContext,
351
- callback: (response: any) => void
358
+ callback: (response: any) => void,
352
359
  ): Promise<Response | null> {
353
360
  const response = await fetch(context.endpoint, {
354
361
  method: "POST",
@@ -421,7 +428,7 @@ async function executePrompt(
421
428
  function handleResponse(
422
429
  response: any,
423
430
  terminalCallback: (text: React.ReactNode, finished: boolean) => void,
424
- isFinished: boolean
431
+ isFinished: boolean,
425
432
  ) {
426
433
  const toolcalls: [] =
427
434
  response?.toolCalls?.map((tool_call: any) => {
@@ -445,6 +452,6 @@ function handleResponse(
445
452
  editOperations={response.editOperations}
446
453
  finished={isFinished}
447
454
  />,
448
- isFinished
455
+ isFinished,
449
456
  );
450
457
  }
@@ -23,7 +23,7 @@ import {
23
23
  SelectionRange,
24
24
  } from "./editContext";
25
25
 
26
- import { EditorConfiguration } from "../../config/types";
26
+ import { EditorConfiguration, MenuItem } from "../../config/types";
27
27
  import { useRouter, useSearchParams, usePathname } from "next/navigation";
28
28
  import { getComponentById } from "../componentTreeHelper";
29
29
 
@@ -60,7 +60,7 @@ import MainLayout from "../MainLayout";
60
60
  import { useEventListenerExt } from "../utils";
61
61
 
62
62
  import { EditContextMenu, EditContextMenuRef } from "../ContextMenu";
63
- import { MenuItem } from "primereact/menuitem";
63
+
64
64
  import { FieldEditorPopup, FieldEditorPopupRef } from "../FieldEditorPopup";
65
65
 
66
66
  import { Command, CommandData } from "../commands/commands";
@@ -437,7 +437,13 @@ export function EditorClient({
437
437
  if (op.type === "edit-field") {
438
438
  const editFieldOperation = op as EditFieldOperation;
439
439
 
440
- const field = await itemsRepository.getField(editFieldOperation);
440
+ const field = await itemsRepository.getField({
441
+ item: {
442
+ ...editFieldOperation.mainItem,
443
+ id: editFieldOperation.itemId,
444
+ },
445
+ fieldId: editFieldOperation.fieldId,
446
+ });
441
447
 
442
448
  if (
443
449
  !field ||
@@ -445,7 +451,12 @@ export function EditorClient({
445
451
  field.type !== "multi-line text" &&
446
452
  field.type !== "rich text")
447
453
  ) {
448
- itemsRepository.refreshItems([editFieldOperation.item]);
454
+ itemsRepository.refreshItems([
455
+ {
456
+ ...editFieldOperation.mainItem,
457
+ id: editFieldOperation.itemId,
458
+ },
459
+ ]);
449
460
  requestRefresh("immediate");
450
461
  }
451
462
  //TODO: field value changes that require rerender
@@ -453,7 +464,10 @@ export function EditorClient({
453
464
  itemsRepository.updateFieldValue(
454
465
  {
455
466
  fieldId: editFieldOperation.fieldId,
456
- item: editFieldOperation.item,
467
+ item: {
468
+ ...editFieldOperation.mainItem,
469
+ id: editFieldOperation.itemId,
470
+ },
457
471
  },
458
472
  editFieldOperation.user ?? { name: "unknown", ai: false },
459
473
  false,
@@ -834,7 +848,10 @@ export function EditorClient({
834
848
  return undefined;
835
849
  }
836
850
 
837
- if (!item.hasLayout && viewName === "page-editor") {
851
+ if (
852
+ (!item.hasLayout && viewName === "page-editor") ||
853
+ viewName == "splash-screen"
854
+ ) {
838
855
  setViewName("content-editor");
839
856
  }
840
857
 
@@ -291,7 +291,7 @@ export function useEditContextRef() {
291
291
  export type EditButton = {
292
292
  id: string;
293
293
  icon: React.ReactNode;
294
- onClick: (ev: MouseEvent<HTMLButtonElement>) => void;
294
+ onClick: (ev: MouseEvent) => void;
295
295
  label: string;
296
296
  };
297
297
 
@@ -368,20 +368,15 @@ export function getOperationsContext(
368
368
  !op ||
369
369
  op.undone ||
370
370
  op.type !== "edit-field" ||
371
- !op.item ||
372
- op.item.id !== item.id ||
371
+ !op.itemId ||
372
+ op.itemId !== item.id ||
373
373
  op.fieldId !== field.fieldId ||
374
- op.item.language !== item.language ||
375
- op.item.version !== item.version
374
+ op.mainItem.language !== item.language ||
375
+ op.mainItem.version !== item.version
376
376
  ) {
377
377
  op = {
378
378
  type: "edit-field",
379
- item: {
380
- id: item.id,
381
- version: item.version,
382
- language: item.language,
383
- name: item.name,
384
- },
379
+ itemId: item.id,
385
380
  fieldId: field.fieldId,
386
381
  fieldName: fieldItem.name,
387
382
  date: new Date().toISOString(),
@@ -398,10 +393,10 @@ export function getOperationsContext(
398
393
 
399
394
  const firstEditInheritedComponent =
400
395
  item.isInheritedFromMasterLanguage &&
401
- op.item.language != state.page?.item.language;
396
+ op.mainItem.language != state.page?.item.language;
402
397
 
403
398
  if (firstEditInheritedComponent)
404
- op.item.language = state.page!.item.language;
399
+ op.mainItem.language = state.page!.item.language;
405
400
 
406
401
  lastOp.current = op;
407
402
  return op;
@@ -440,7 +435,10 @@ export function getOperationsContext(
440
435
  const itemsToRefresh = result.data
441
436
  .map((x: EditOperation) => {
442
437
  if (x.type === "edit-field")
443
- return (x as EditFieldOperation).item;
438
+ return {
439
+ ...(x as EditFieldOperation).mainItem,
440
+ id: (x as EditFieldOperation).itemId,
441
+ };
444
442
  if (x.type === "add-component")
445
443
  return {
446
444
  id: (x as AddComponentOperation).componentId,
@@ -492,7 +490,11 @@ export function getOperationsContext(
492
490
  if (result.type === "success") {
493
491
  const itemsToRefresh = result.data
494
492
  .map((x: EditOperation) => {
495
- if (x.type === "edit-field") return (x as EditFieldOperation).item;
493
+ if (x.type === "edit-field")
494
+ return {
495
+ ...(x as EditFieldOperation).mainItem,
496
+ id: (x as EditFieldOperation).itemId,
497
+ };
496
498
  if (x.type === "add-component")
497
499
  return {
498
500
  id: (x as AddComponentOperation).componentId,
@@ -11,15 +11,20 @@ import {
11
11
  } from "../pageModel";
12
12
 
13
13
  import { ItemsRepository } from "./itemsRepository";
14
- import { loadPlaceholderInsertOptions, PlaceholderInsertOptions } from "../services/editService";
14
+ import {
15
+ loadPlaceholderInsertOptions,
16
+ PlaceholderInsertOptions,
17
+ } from "../services/editService";
15
18
 
16
19
  export function usePageModel(
17
20
  itemsRepository: ItemsRepository | undefined,
18
- pageItemDescriptor?: ItemDescriptor
21
+ pageItemDescriptor?: ItemDescriptor,
19
22
  ) {
20
23
  const [page, setPage] = useState<Page>();
21
24
  const [pageSkeleton, setPageSkeleton] = useState<PageSkeleton>();
22
- const [insertOptions, setInsertOptions] = useState<PlaceholderInsertOptions[]>([]);
25
+ const [insertOptions, setInsertOptions] = useState<
26
+ PlaceholderInsertOptions[]
27
+ >([]);
23
28
 
24
29
  useEffect(() => {
25
30
  setPage(undefined);
@@ -29,13 +34,13 @@ export function usePageModel(
29
34
  useEffect(() => {
30
35
  const loadInsertOptions = async () => {
31
36
  if (!pageSkeleton) return;
32
-
37
+
33
38
  const collectPlaceholderKeys = (skeleton: PageSkeleton): string[] => {
34
39
  const keys: string[] = [];
35
40
  const collectFromComponent = (component: ComponentSkeleton) => {
36
- component.placeholders.forEach(placeholder => {
41
+ component.placeholders.forEach((placeholder) => {
37
42
  keys.push(placeholder.key);
38
- placeholder.components.forEach(c => collectFromComponent(c));
43
+ placeholder.components.forEach((c) => collectFromComponent(c));
39
44
  });
40
45
  };
41
46
  collectFromComponent(skeleton.rootComponent);
@@ -43,7 +48,10 @@ export function usePageModel(
43
48
  };
44
49
 
45
50
  const placeholderKeys = collectPlaceholderKeys(pageSkeleton);
46
- const options = await loadPlaceholderInsertOptions(pageSkeleton.item, placeholderKeys);
51
+ const options = await loadPlaceholderInsertOptions(
52
+ pageSkeleton.item,
53
+ placeholderKeys,
54
+ );
47
55
  setInsertOptions(options);
48
56
  };
49
57
  loadInsertOptions();
@@ -76,7 +84,6 @@ export function usePageModel(
76
84
 
77
85
  collectItems(pageSkeleton.rootComponent);
78
86
 
79
-
80
87
  const fullItems = await itemsRepository.getItems(itemsToFetch);
81
88
 
82
89
  const getItem = (descriptor: ItemDescriptor) =>
@@ -84,7 +91,7 @@ export function usePageModel(
84
91
  (x) =>
85
92
  x.id === descriptor.id &&
86
93
  x.language === descriptor.language &&
87
- x.version === descriptor.version
94
+ x.version === descriptor.version,
88
95
  );
89
96
 
90
97
  const pageItem = await itemsRepository.getItem(pageSkeleton.item);
@@ -96,9 +103,8 @@ export function usePageModel(
96
103
 
97
104
  const buildModel = (
98
105
  skeleton: ComponentSkeleton,
99
- parentPlaceholder?: Placeholder
106
+ parentPlaceholder?: Placeholder,
100
107
  ): Component | undefined => {
101
-
102
108
  const datasourceItemTemp = skeleton.datasourceItem
103
109
  ? getItem(skeleton.datasourceItem)
104
110
  : undefined;
@@ -127,11 +133,14 @@ export function usePageModel(
127
133
  datasourceItem,
128
134
  items,
129
135
  placeholders,
130
- isShared: skeleton.id !== skeleton.datasourceItem?.id,
131
- parentPlaceholder
136
+ isShared: !(datasourceItem?.path.startsWith(pageItem.path) || true),
137
+ parentPlaceholder,
138
+ typeId: skeleton.typeId || datasourceItem?.templateId || "",
139
+ canBeMoved:
140
+ !datasourceItem ||
141
+ datasourceItem?.id !== parentPlaceholder?.parentComponent?.id,
132
142
  };
133
143
 
134
-
135
144
  component.placeholders = skeleton.placeholders.map((x) => {
136
145
  const insOpts =
137
146
  insertOptions.find((y) => y.key === x.key)?.insertOptions ?? [];
@@ -154,7 +163,7 @@ export function usePageModel(
154
163
  };
155
164
 
156
165
  const rootComponent = buildModel(pageSkeleton.rootComponent);
157
-
166
+
158
167
  if (!rootComponent) {
159
168
  setPage(undefined);
160
169
  return;
@@ -165,13 +174,12 @@ export function usePageModel(
165
174
  // revision: itemsRepository.revision,
166
175
  editRevision: pageSkeleton.editRevision,
167
176
  };
168
-
177
+
169
178
  //console.log("Page model updated", performance.now() - start);
170
179
  setPage(page);
171
180
  };
172
181
 
173
-
174
- useEffect(() => {
182
+ useEffect(() => {
175
183
  updatePageModel();
176
184
  }, [pageSkeleton, itemsRepository, insertOptions]);
177
185