@alpaca-editor/core 1.0.3848 → 1.0.3849

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 (48) hide show
  1. package/dist/editor/ComponentInfo.js +14 -2
  2. package/dist/editor/ComponentInfo.js.map +1 -1
  3. package/dist/editor/ContextMenu.d.ts +1 -1
  4. package/dist/editor/ContextMenu.js +4 -4
  5. package/dist/editor/ContextMenu.js.map +1 -1
  6. package/dist/editor/client/EditorClient.js +34 -30
  7. package/dist/editor/client/EditorClient.js.map +1 -1
  8. package/dist/editor/client/editContext.d.ts +1 -1
  9. package/dist/editor/client/itemsRepository.d.ts +2 -1
  10. package/dist/editor/client/itemsRepository.js +107 -4
  11. package/dist/editor/client/itemsRepository.js.map +1 -1
  12. package/dist/editor/client/pageModelBuilder.js +1 -1
  13. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  14. package/dist/editor/commands/componentCommands.d.ts +1 -2
  15. package/dist/editor/commands/componentCommands.js +39 -35
  16. package/dist/editor/commands/componentCommands.js.map +1 -1
  17. package/dist/editor/page-editor-chrome/FrameMenu.js +9 -1
  18. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  19. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +27 -23
  20. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
  21. package/dist/editor/page-viewer/EditorForm.js +18 -8
  22. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  23. package/dist/editor/page-viewer/PageViewerFrame.js +3 -2
  24. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  25. package/dist/editor/pageModel.d.ts +8 -1
  26. package/dist/editor/services/contentService.d.ts +2 -1
  27. package/dist/editor/services/contentService.js +5 -0
  28. package/dist/editor/services/contentService.js.map +1 -1
  29. package/dist/editor/sidebar/ComponentTree.js +2 -2
  30. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  31. package/dist/revision.d.ts +2 -2
  32. package/dist/revision.js +2 -2
  33. package/package.json +1 -1
  34. package/src/editor/ComponentInfo.tsx +17 -2
  35. package/src/editor/ContextMenu.tsx +5 -5
  36. package/src/editor/client/EditorClient.tsx +38 -35
  37. package/src/editor/client/editContext.ts +1 -1
  38. package/src/editor/client/itemsRepository.ts +163 -32
  39. package/src/editor/client/pageModelBuilder.ts +1 -1
  40. package/src/editor/commands/componentCommands.tsx +51 -53
  41. package/src/editor/page-editor-chrome/FrameMenu.tsx +14 -2
  42. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +41 -34
  43. package/src/editor/page-viewer/EditorForm.tsx +22 -10
  44. package/src/editor/page-viewer/PageViewerFrame.tsx +7 -9
  45. package/src/editor/pageModel.ts +9 -1
  46. package/src/editor/services/contentService.ts +15 -6
  47. package/src/editor/sidebar/ComponentTree.tsx +2 -2
  48. package/src/revision.ts +2 -2
@@ -32,40 +32,47 @@ export function PictureEditorOverlay() {
32
32
 
33
33
  setElement(pictureElement || undefined);
34
34
  },
35
- [iframe, editContext]
35
+ [iframe, editContext],
36
36
  );
37
37
 
38
38
  useEffect(() => {
39
- if (element) {
40
- const itemId = element.getAttribute("data-itemid");
41
- const language = element.getAttribute("data-language");
42
- const version = element.getAttribute("data-version");
43
- const fieldId = element.getAttribute("data-fieldid");
44
-
45
- if (
46
- !itemId ||
47
- !language ||
48
- !version ||
49
- !fieldId ||
50
- !pageViewContext?.page ||
51
- !iframe?.contentWindow
52
- )
53
- return;
54
-
55
- const component = getComponentById(itemId, pageViewContext.page!);
56
-
57
- if (component == null) return;
58
-
59
- const pictureField = component.datasourceItem?.fields.find(
60
- (f) => f.id === fieldId
61
- ) as PictureField;
62
-
63
- if (!pictureField) return;
64
-
65
- setField(pictureField);
66
- } else {
67
- setField(undefined);
68
- }
39
+ const loadField = async () => {
40
+ if (element) {
41
+ const itemId = element.getAttribute("data-itemid");
42
+ const language = element.getAttribute("data-language");
43
+ const version = element.getAttribute("data-version");
44
+ const fieldId = element.getAttribute("data-fieldid");
45
+
46
+ if (
47
+ !itemId ||
48
+ !language ||
49
+ !version ||
50
+ !fieldId ||
51
+ !pageViewContext?.page ||
52
+ !iframe?.contentWindow
53
+ )
54
+ return;
55
+
56
+ const component = getComponentById(itemId, pageViewContext.page!);
57
+
58
+ if (component == null) return;
59
+
60
+ const item = await editContext!.itemsRepository.getItem(
61
+ component.datasourceItem!,
62
+ );
63
+
64
+ const pictureField = item?.fields.find(
65
+ (f) => f.id === fieldId,
66
+ ) as PictureField;
67
+
68
+ if (!pictureField) return;
69
+
70
+ setField(pictureField);
71
+ } else {
72
+ setField(undefined);
73
+ }
74
+ };
75
+ loadField();
69
76
  }, [element, pageViewContext?.page]);
70
77
 
71
78
  useEffect(() => {
@@ -73,7 +80,7 @@ export function PictureEditorOverlay() {
73
80
 
74
81
  const sourceELement = getCurrentPictureSource(
75
82
  element,
76
- iframe.contentWindow
83
+ iframe.contentWindow,
77
84
  );
78
85
 
79
86
  if (sourceELement) {
@@ -100,7 +107,7 @@ export function PictureEditorOverlay() {
100
107
  if (iframe?.contentDocument) {
101
108
  iframe?.contentDocument.removeEventListener(
102
109
  "mouseenter",
103
- onMouseEnter
110
+ onMouseEnter,
104
111
  );
105
112
  }
106
113
 
@@ -135,7 +142,7 @@ export function PictureEditorOverlay() {
135
142
 
136
143
  function getCurrentPictureSource(
137
144
  pictureElement: HTMLElement,
138
- iframeWindow: Window
145
+ iframeWindow: Window,
139
146
  ): HTMLElement | null {
140
147
  if (pictureElement.tagName === "IMG") return pictureElement;
141
148
 
@@ -7,7 +7,7 @@ import { Insert } from "../sidebar/Insert";
7
7
  import { useEffect, useState } from "react";
8
8
 
9
9
  import { SimpleIconButton } from "../ui/SimpleIconButton";
10
- import { Component, Field, RenderedItem } from "../pageModel";
10
+ import { Component, Field, FullItem, RenderedItem } from "../pageModel";
11
11
  import { Spinner } from "../ui/Spinner";
12
12
  import { PageViewContext } from "./pageViewContext";
13
13
  import { SimpleTabs, Tab } from "../ui/SimpleTabs";
@@ -30,6 +30,7 @@ export function EditorForm({
30
30
  const [activeTabKey, setActiveTabKey] = useState("content");
31
31
  const [item, setItem] = useState<RenderedItem>();
32
32
  const [component, setComponent] = useState<Component>();
33
+ const [fullItem, setFullItem] = useState<FullItem>();
33
34
 
34
35
  const toggleInsertMode = () => {
35
36
  if (insertMode) {
@@ -39,6 +40,15 @@ export function EditorForm({
39
40
  }
40
41
  };
41
42
 
43
+ useEffect(() => {
44
+ async function loadFullItem() {
45
+ if (!item) return;
46
+ const fullItem = await editContext!.itemsRepository.getItem(item);
47
+ setFullItem(fullItem);
48
+ }
49
+ loadFullItem();
50
+ }, [item]);
51
+
42
52
  useEffect(() => {
43
53
  if (editContext.selectedForInsertion) setInsertMode(true);
44
54
  }, [editContext.selectedForInsertion]);
@@ -83,7 +93,7 @@ export function EditorForm({
83
93
  pageViewContext.pageItemDescriptor,
84
94
  ]);
85
95
 
86
- if (!item)
96
+ if (!fullItem || !item)
87
97
  return (
88
98
  <div className="grid h-full w-full items-center justify-center">
89
99
  <Spinner />
@@ -98,7 +108,7 @@ export function EditorForm({
98
108
  x.item.version === item?.version,
99
109
  )?.results || [];
100
110
 
101
- let designFields = Object.values(item?.fields).filter(
111
+ let designFields = Object.values(fullItem?.fields || []).filter(
102
112
  (x) => x.section === "Design" || x.section === "Rendering",
103
113
  );
104
114
 
@@ -106,7 +116,7 @@ export function EditorForm({
106
116
 
107
117
  if (editorFields && editorFields["Design"]) {
108
118
  editorFields["Design"]?.addFields.forEach((fieldName) => {
109
- const field = item?.fields.find((x) => x.name === fieldName);
119
+ const field = fullItem?.fields.find((x) => x.name === fieldName);
110
120
  if (field) designFields.push(field);
111
121
  });
112
122
  editorFields["Design"]?.removeFields.forEach((fieldName) => {
@@ -116,7 +126,7 @@ export function EditorForm({
116
126
 
117
127
  const itemFields: ItemFields[] = [];
118
128
 
119
- const contentFields = Object.values(item?.fields).filter(
129
+ const contentFields = Object.values(fullItem?.fields || []).filter(
120
130
  (x) =>
121
131
  ((editorFields && editorFields["Content"]?.addFields.includes(x.name!)) ||
122
132
  item.renderedFieldIds.indexOf(x.id) >= 0) &&
@@ -131,7 +141,9 @@ export function EditorForm({
131
141
  .forEach((i) => {
132
142
  const fields: Field[] = [];
133
143
  i.renderedFieldIds.forEach((id) => {
134
- const field = Object.values(i?.fields).find((x) => x.id === id);
144
+ const field = Object.values(fullItem?.fields || []).find(
145
+ (x) => x.id === id,
146
+ );
135
147
  if (field) fields.push(field);
136
148
  });
137
149
  if (fields.length > 0) itemFields.push({ headline: i.name, fields });
@@ -164,7 +176,7 @@ export function EditorForm({
164
176
  if (editorFields) {
165
177
  Object.keys(editorFields).forEach((key) => {
166
178
  if (key !== "Content" && key !== "Design") {
167
- const fields = item?.fields.filter((x) =>
179
+ const fields = fullItem?.fields.filter((x) =>
168
180
  editorFields[key]?.addFields.includes(x.name!),
169
181
  );
170
182
  if (fields?.length)
@@ -183,9 +195,9 @@ export function EditorForm({
183
195
  content: (
184
196
  <div className="relative h-full">
185
197
  <div className="absolute inset-0 overflow-auto">
186
- <ItemInfo item={item} />
198
+ <ItemInfo item={fullItem} />
187
199
  <FieldList
188
- fields={[{ fields: item.fields }]}
200
+ fields={[{ fields: fullItem?.fields || [] }]}
189
201
  validators={validators}
190
202
  showStandardFieldsEnabled={true}
191
203
  readonly={readonly}
@@ -231,7 +243,7 @@ export function EditorForm({
231
243
  size="large"
232
244
  disabled={
233
245
  !editContext.page?.item.canWriteItem ||
234
- !item?.canWriteItem ||
246
+ !fullItem?.canWriteItem ||
235
247
  editContext.mode !== "edit" ||
236
248
  compareView
237
249
  }
@@ -511,15 +511,13 @@ export function PageViewerFrame({
511
511
 
512
512
  const fieldButtons = field ? await loadFieldButtons(field) : [];
513
513
 
514
- if (
515
- showComponentContextMenu(
516
- selectedComponents,
517
- editContextRef.current!,
518
- field,
519
- fieldButtons,
520
- )(adjustedEvent)
521
- ) {
522
- }
514
+ const showMenu = await showComponentContextMenu(
515
+ selectedComponents,
516
+ editContextRef.current!,
517
+ field,
518
+ fieldButtons,
519
+ );
520
+ if (showMenu) showMenu(adjustedEvent);
523
521
  };
524
522
 
525
523
  const handleLoad = () => {
@@ -110,6 +110,14 @@ export type Timings = {
110
110
  [key: string]: number;
111
111
  };
112
112
 
113
+ export type ItemStub = ItemDescriptor & {
114
+ name: string;
115
+ templateId: string;
116
+ templateName: string;
117
+ icon: string;
118
+ path: string;
119
+ };
120
+
113
121
  export type FullItem = ItemDescriptor & {
114
122
  descriptor: ItemDescriptor;
115
123
  name: string;
@@ -144,7 +152,7 @@ export type Page = {
144
152
  rootComponent: Component;
145
153
  };
146
154
 
147
- export type RenderedItem = RenderedItemSkeleton & FullItem;
155
+ export type RenderedItem = RenderedItemSkeleton & ItemStub;
148
156
 
149
157
  type EditorFields = {
150
158
  [group: string]: {
@@ -7,7 +7,7 @@ import {
7
7
  Site,
8
8
  WorkboxItem,
9
9
  } from "../../types";
10
- import { FullItem, ItemDescriptor } from "../pageModel";
10
+ import { FullItem, ItemDescriptor, ItemStub } from "../pageModel";
11
11
 
12
12
  export type ItemTreeNodeData = {
13
13
  id: string;
@@ -34,7 +34,7 @@ export async function getChildren(
34
34
  templateIds: string[] = [],
35
35
  includeEmbeddedItems: boolean,
36
36
  language: string,
37
- include?: string
37
+ include?: string,
38
38
  ): Promise<ItemTreeNodeData[]> {
39
39
  let url =
40
40
  // configuration.services.editorService.baseUrl +
@@ -91,7 +91,7 @@ export async function getChildren(
91
91
  // }
92
92
 
93
93
  export async function fetchItems(
94
- itemDescriptors: ItemDescriptor[]
94
+ itemDescriptors: ItemDescriptor[],
95
95
  ): Promise<FullItem[] | undefined> {
96
96
  let url = "/alpaca/editor/items";
97
97
 
@@ -99,6 +99,15 @@ export async function fetchItems(
99
99
  return response.data || [];
100
100
  }
101
101
 
102
+ export async function fetchItemStubs(
103
+ itemDescriptors: ItemDescriptor[],
104
+ ): Promise<ItemStub[] | undefined> {
105
+ let url = "/alpaca/editor/itemstubs";
106
+
107
+ const response = await post<ItemStub[]>(url, itemDescriptors);
108
+ return response.data || [];
109
+ }
110
+
102
111
  export async function getSites() {
103
112
  return await get<Site[]>("/alpaca/editor/sites");
104
113
  }
@@ -106,7 +115,7 @@ export async function getSites() {
106
115
  export async function resolvePageAndSite(
107
116
  itemId: string,
108
117
  language: string,
109
- version: number
118
+ version: number,
110
119
  ): Promise<
111
120
  | { pageItem: ItemDescriptor; site: { name: string }; isHeadless: boolean }
112
121
  | undefined
@@ -130,7 +139,7 @@ export async function resolvePageAndSite(
130
139
  export async function getLanguagesAndVersions(item: ItemDescriptor) {
131
140
  return await post<LanguagesAndVersions>(
132
141
  "/alpaca/editor/getLanguagesAndVersions",
133
- item
142
+ item,
134
143
  );
135
144
  }
136
145
 
@@ -149,7 +158,7 @@ export async function getDictionary(siteName: string, language: string) {
149
158
  "/alpaca/editor/dictionary/index?siteName=" +
150
159
  siteName +
151
160
  "&language=" +
152
- language
161
+ language,
153
162
  );
154
163
  return response.data as EditableDictionary;
155
164
  }
@@ -277,7 +277,7 @@ export function ComponentTree({}) {
277
277
  );
278
278
 
279
279
  // Handle tree context menu
280
- const handleTreeContextMenu = (
280
+ const handleTreeContextMenu = async (
281
281
  node: TreeNode<Component>,
282
282
  event: React.MouseEvent,
283
283
  ) => {
@@ -308,7 +308,7 @@ export function ComponentTree({}) {
308
308
  selectedEntities = [nodeDictionary[node.key]!.data as Component];
309
309
  }
310
310
 
311
- let commands = getComponentCommands(
311
+ let commands = await getComponentCommands(
312
312
  selectedEntities,
313
313
  editContextRef.current!,
314
314
  );
package/src/revision.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = "1.0.3848";
2
- export const buildDate = "2025-04-26 20:59:41";
1
+ export const version = "1.0.3849";
2
+ export const buildDate = "2025-04-27 12:30:47";