@alpaca-headless/alpaca-headless-nextjs 0.0.4 → 1.0.13

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 (139) hide show
  1. package/dist/cjs/components/Image.js +36 -0
  2. package/dist/cjs/components/Link.js +22 -0
  3. package/dist/cjs/components/Picture.js +119 -0
  4. package/dist/cjs/components/PictureEditor.js +43 -0
  5. package/dist/cjs/components/Placeholder.js +40 -4
  6. package/dist/cjs/components/RichText.js +44 -0
  7. package/dist/cjs/components/RichTextEditor.js +82 -0
  8. package/dist/cjs/components/Slot.js +8 -0
  9. package/dist/cjs/components/Text.js +24 -4
  10. package/dist/cjs/components/TextEditor.js +68 -0
  11. package/dist/cjs/components/Translate.js +14 -0
  12. package/dist/cjs/components/index.js +5 -0
  13. package/dist/cjs/editor/AiTerminal.js +150 -0
  14. package/dist/cjs/editor/ComponentInfo.js +14 -0
  15. package/dist/cjs/editor/ComponentPalette.js +78 -0
  16. package/dist/cjs/editor/ComponentTree.js +200 -0
  17. package/dist/cjs/editor/ContentTree.js +120 -0
  18. package/dist/cjs/editor/Debug.js +16 -0
  19. package/dist/cjs/editor/DictionaryEditor.js +35 -0
  20. package/dist/cjs/editor/EditFrame.js +61 -0
  21. package/dist/cjs/editor/EditHistory.js +30 -0
  22. package/dist/cjs/editor/Editor.js +27 -0
  23. package/dist/cjs/editor/EditorClient.js +457 -0
  24. package/dist/cjs/editor/EditorClientHost.js +37 -0
  25. package/dist/cjs/editor/FieldList.js +59 -0
  26. package/dist/cjs/editor/GraphQL.js +90 -0
  27. package/dist/cjs/editor/LanguageSelector.js +21 -0
  28. package/dist/cjs/editor/MediaSelector.js +61 -0
  29. package/dist/cjs/editor/PageInfo.js +12 -0
  30. package/dist/cjs/editor/PlaceholderDropZone.js +54 -0
  31. package/dist/cjs/editor/PlaceholderDropZoneHost.js +37 -0
  32. package/dist/cjs/editor/Terminal.js +51 -0
  33. package/dist/cjs/editor/TranslateEditor.js +25 -0
  34. package/dist/cjs/editor/VersionSelector.js +21 -0
  35. package/dist/cjs/editor/componentTreeHelper.js +18 -0
  36. package/dist/cjs/editor/contentService.js +38 -0
  37. package/dist/cjs/editor/editContext.js +35 -0
  38. package/dist/cjs/editor/editService.js +150 -0
  39. package/dist/cjs/editor/fieldTypes/RichTextEditor.js +19 -0
  40. package/dist/cjs/editor/fieldTypes/SingleLineText.js +17 -0
  41. package/dist/cjs/editor/index.js +18 -0
  42. package/dist/cjs/graphQLTypes.js +2 -0
  43. package/dist/cjs/index.js +15 -0
  44. package/dist/cjs/loadRouteData.js +98 -40
  45. package/dist/cjs/mediaProtection.js +56 -0
  46. package/dist/editor.css +120 -0
  47. package/dist/esm/components/Image.js +32 -0
  48. package/dist/esm/components/Link.js +18 -0
  49. package/dist/esm/components/Picture.js +115 -0
  50. package/dist/esm/components/PictureEditor.js +39 -0
  51. package/dist/esm/components/Placeholder.js +38 -5
  52. package/dist/esm/components/RichText.js +37 -0
  53. package/dist/esm/components/RichTextEditor.js +55 -0
  54. package/dist/esm/components/Slot.js +5 -0
  55. package/dist/esm/components/Text.js +24 -4
  56. package/dist/esm/components/TextEditor.js +41 -0
  57. package/dist/esm/components/Translate.js +10 -0
  58. package/dist/esm/components/index.js +5 -0
  59. package/dist/esm/editor/AiTerminal.js +146 -0
  60. package/dist/esm/editor/ComponentInfo.js +10 -0
  61. package/dist/esm/editor/ComponentPalette.js +71 -0
  62. package/dist/esm/editor/ComponentTree.js +196 -0
  63. package/dist/esm/editor/ContentTree.js +117 -0
  64. package/dist/esm/editor/Debug.js +9 -0
  65. package/dist/esm/editor/DictionaryEditor.js +31 -0
  66. package/dist/esm/editor/EditFrame.js +57 -0
  67. package/dist/esm/editor/EditHistory.js +26 -0
  68. package/dist/esm/editor/Editor.js +23 -0
  69. package/dist/esm/editor/EditorClient.js +450 -0
  70. package/dist/esm/editor/EditorClientHost.js +7 -0
  71. package/dist/esm/editor/FieldList.js +55 -0
  72. package/dist/esm/editor/GraphQL.js +83 -0
  73. package/dist/esm/editor/LanguageSelector.js +17 -0
  74. package/dist/esm/editor/MediaSelector.js +54 -0
  75. package/dist/esm/editor/PageInfo.js +8 -0
  76. package/dist/esm/editor/PlaceholderDropZone.js +50 -0
  77. package/dist/esm/editor/PlaceholderDropZoneHost.js +7 -0
  78. package/dist/esm/editor/Terminal.js +47 -0
  79. package/dist/esm/editor/TranslateEditor.js +21 -0
  80. package/dist/esm/editor/VersionSelector.js +17 -0
  81. package/dist/esm/editor/componentTreeHelper.js +14 -0
  82. package/dist/esm/editor/contentService.js +31 -0
  83. package/dist/esm/editor/editContext.js +5 -0
  84. package/dist/esm/editor/editService.js +139 -0
  85. package/dist/esm/editor/fieldTypes/RichTextEditor.js +15 -0
  86. package/dist/esm/editor/fieldTypes/SingleLineText.js +13 -0
  87. package/dist/esm/editor/index.js +2 -0
  88. package/dist/esm/graphQLTypes.js +1 -0
  89. package/dist/esm/index.js +2 -0
  90. package/dist/esm/loadRouteData.js +97 -39
  91. package/dist/esm/mediaProtection.js +49 -0
  92. package/package.json +16 -4
  93. package/types/alpacaContext.d.ts +11 -0
  94. package/types/components/Image.d.ts +10 -0
  95. package/types/components/Link.d.ts +6 -0
  96. package/types/components/Picture.d.ts +20 -0
  97. package/types/components/PictureEditor.d.ts +3 -0
  98. package/types/components/RichText.d.ts +7 -0
  99. package/types/components/RichTextEditor.d.ts +296 -0
  100. package/types/components/Slot.d.ts +4 -0
  101. package/types/components/Text.d.ts +3 -2
  102. package/types/components/TextEditor.d.ts +296 -0
  103. package/types/components/Translate.d.ts +3 -0
  104. package/types/components/index.d.ts +5 -0
  105. package/types/editor/AiTerminal.d.ts +4 -0
  106. package/types/editor/ComponentInfo.d.ts +4 -0
  107. package/types/editor/ComponentPalette.d.ts +7 -0
  108. package/types/editor/ComponentTree.d.ts +5 -0
  109. package/types/editor/ContentTree.d.ts +13 -0
  110. package/types/editor/Debug.d.ts +6 -0
  111. package/types/editor/DictionaryEditor.d.ts +3 -0
  112. package/types/editor/EditFrame.d.ts +6 -0
  113. package/types/editor/EditHistory.d.ts +4 -0
  114. package/types/editor/Editor.d.ts +6 -0
  115. package/types/editor/EditorClient.d.ts +9 -0
  116. package/types/editor/EditorClientHost.d.ts +8 -0
  117. package/types/editor/FieldList.d.ts +4 -0
  118. package/types/editor/GraphQL.d.ts +5 -0
  119. package/types/editor/LanguageSelector.d.ts +5 -0
  120. package/types/editor/MediaSelector.d.ts +5 -0
  121. package/types/editor/PageInfo.d.ts +4 -0
  122. package/types/editor/PlaceholderDropZone.d.ts +6 -0
  123. package/types/editor/PlaceholderDropZoneHost.d.ts +6 -0
  124. package/types/editor/Terminal.d.ts +4 -0
  125. package/types/editor/TranslateEditor.d.ts +3 -0
  126. package/types/editor/VersionSelector.d.ts +5 -0
  127. package/types/editor/componentTreeHelper.d.ts +2 -0
  128. package/types/editor/contentService.d.ts +14 -0
  129. package/types/editor/editContext.d.ts +81 -0
  130. package/types/editor/editService.d.ts +12 -0
  131. package/types/editor/fieldTypes/RichTextEditor.d.ts +4 -0
  132. package/types/editor/fieldTypes/SingleLineText.d.ts +4 -0
  133. package/types/editor/index.d.ts +2 -0
  134. package/types/fieldTypes.d.ts +63 -1
  135. package/types/graphQLTypes.d.ts +24 -0
  136. package/types/index.d.ts +2 -0
  137. package/types/layoutData.d.ts +56 -1
  138. package/types/loadRouteData.d.ts +30 -1
  139. package/types/mediaProtection.d.ts +2 -0
@@ -0,0 +1,450 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { useState, useEffect, useRef } from "react";
13
+ import uuid from "react-uuid";
14
+ import { PrimeReactProvider } from "primereact/api";
15
+ import { Menubar } from "primereact/menubar";
16
+ import { ProgressSpinner } from "primereact/progressspinner";
17
+ import { TabView, TabPanel } from "primereact/tabview";
18
+ import { Toast } from "primereact/toast";
19
+ import { Splitter, SplitterPanel } from "primereact/splitter";
20
+ import { BlockUI } from "primereact/blockui";
21
+ import { ConfirmDialog, confirmDialog } from "primereact/confirmdialog";
22
+ import { Sidebar } from "primereact/sidebar";
23
+ import { EditContextProvider, } from "..";
24
+ import { useRouter, useSearchParams, usePathname } from "next/navigation";
25
+ import { FieldList } from "./FieldList";
26
+ import { GraphQL } from "./GraphQL";
27
+ import { ComponentTree } from "./ComponentTree";
28
+ import { ComponentInfo } from "./ComponentInfo";
29
+ import { LanguageSelector } from "./LanguageSelector";
30
+ import { findComponent } from "./componentTreeHelper";
31
+ import { ComponentPalette } from "./ComponentPalette";
32
+ import { DictionaryEditor } from "./DictionaryEditor";
33
+ import { AiTerminal } from "./AiTerminal";
34
+ import { EditHistory } from "./EditHistory";
35
+ import { Debug } from "./Debug";
36
+ import { PageInfo } from "./PageInfo";
37
+ import { VersionSelector } from "./VersionSelector";
38
+ import { commitChanges, currentOperation, executeRedo, executeUndo, executeEditOperation, setCurrentOperation, } from "./editService";
39
+ import "../../editor.css";
40
+ // Hook
41
+ function useEventListener(eventName, handler, element) {
42
+ // Create a ref that stores handler
43
+ const savedHandler = useRef();
44
+ // Update ref.current value if handler changes.
45
+ // This allows our effect below to always get latest handler ...
46
+ // ... without us needing to pass it in effect deps array ...
47
+ // ... and potentially cause effect to re-run every render.
48
+ useEffect(() => {
49
+ savedHandler.current = handler;
50
+ }, [handler]);
51
+ useEffect(() => {
52
+ // Make sure element supports addEventListener
53
+ // On
54
+ const isSupported = element && element.addEventListener;
55
+ if (!isSupported)
56
+ return;
57
+ // Create event listener that calls handler function stored in ref
58
+ const eventListener = (event) => savedHandler.current(event);
59
+ // Add event listener
60
+ element.addEventListener(eventName, eventListener);
61
+ // Remove event listener on cleanup
62
+ return () => {
63
+ element.removeEventListener(eventName, eventListener);
64
+ };
65
+ }, [eventName, element] // Re-run if eventName or element changes
66
+ );
67
+ }
68
+ export function EditorClient({ content, dictionaryObject, edit, children, }) {
69
+ const router = useRouter();
70
+ const pathname = usePathname();
71
+ const searchParams = useSearchParams();
72
+ const [selection, setSelection] = useState([]);
73
+ const [selectedForInsertion, setSelectedForInsertion] = useState("");
74
+ const [currentEditOperation, setCurrentEditOperation] = useState();
75
+ const [dictionary, setDictionary] = useState(dictionaryObject);
76
+ const [unresolvedDictionaryKeys, setUnresolvedDictionaryKeys] = useState([]);
77
+ const [editData, setEditData] = useState(edit);
78
+ const [refreshCompletedFlag, setRefreshCompletedFlag] = useState(false);
79
+ const [updateContentEditingFields, setUpdateContentEditingFields] = useState(false);
80
+ const [page, setPageData] = useState(null);
81
+ const [uiBlocked, setUiBlocked] = useState(false);
82
+ const [componentsPaletteVisible, setComponentsPaletteVisible] = useState(false);
83
+ const [dragObject, setDragObject] = useState();
84
+ const [hidePalette, setHidePalette] = useState(false);
85
+ const [refreshTimer, setRefreshTimer] = useState();
86
+ const sessionId = searchParams.get("session");
87
+ if (!sessionId)
88
+ return;
89
+ function switchLanguage(language) {
90
+ const current = new URLSearchParams(Array.from(searchParams.entries()));
91
+ current.set("language", language);
92
+ const newUrl = `${pathname}?${current.toString()}`;
93
+ router.replace(newUrl, { scroll: false });
94
+ }
95
+ function switchVersion(version) {
96
+ const current = new URLSearchParams(Array.from(searchParams.entries()));
97
+ current.set("version", version.toString());
98
+ const newUrl = `${pathname}?${current.toString()}`;
99
+ router.replace(newUrl, { scroll: false });
100
+ }
101
+ function handleErrorResult(result) {
102
+ if (result.type === "error") {
103
+ showErrorToast(result);
104
+ return true;
105
+ }
106
+ if (result.type === "unauthenticated") {
107
+ confirmDialog({
108
+ header: "Not logged in",
109
+ message: "You are not logged in anymore. Proceed to login page?",
110
+ accept: () => {
111
+ window.location.href = edit.loginUrl;
112
+ },
113
+ });
114
+ showErrorToast(result);
115
+ return true;
116
+ }
117
+ }
118
+ useEffect(() => {
119
+ if (selection.length)
120
+ setSelectedForInsertion("");
121
+ }, [selection]);
122
+ useEffect(() => {
123
+ const sync = () => __awaiter(this, void 0, void 0, function* () {
124
+ if (currentEditOperation) {
125
+ const result = yield executeEditOperation(currentEditOperation, sessionId);
126
+ if (handleErrorResult(result))
127
+ return;
128
+ if ((result.id && edit.operations.length == 0) ||
129
+ edit.operations[edit.operations.length - 1].id !=
130
+ result.id) {
131
+ edit.operations = edit.operations.filter((x) => !x.undone);
132
+ edit.operations.push(result);
133
+ setEditData(Object.assign({}, edit));
134
+ }
135
+ if (result.type === "add-component" ||
136
+ result.type === "link-component") {
137
+ console.log("CURRENT: " + JSON.stringify(result));
138
+ setSelection([result.componentId]);
139
+ }
140
+ if (!currentEditOperation.noRefresh)
141
+ requestRefresh(currentEditOperation.refreshAfterQuietPeriod);
142
+ }
143
+ });
144
+ sync();
145
+ }, [currentEditOperation]);
146
+ const requestRefresh = (waitForQuietPeriod) => {
147
+ console.log("request refresh with " + waitForQuietPeriod);
148
+ if (waitForQuietPeriod && refreshTimer) {
149
+ clearTimeout(refreshTimer);
150
+ }
151
+ if (!refreshTimer || waitForQuietPeriod) {
152
+ setRefreshTimer(setTimeout(() => {
153
+ console.log("refreshing");
154
+ router.refresh();
155
+ setRefreshCompletedFlag(!refreshCompletedFlag);
156
+ setRefreshTimer(undefined);
157
+ }, waitForQuietPeriod ? 2000 : 1000));
158
+ }
159
+ };
160
+ const saveAndRefresh = (callback) => __awaiter(this, void 0, void 0, function* () {
161
+ if (!edit.operations.length) {
162
+ if (callback)
163
+ callback();
164
+ return;
165
+ }
166
+ setUiBlocked(true);
167
+ if (!(yield commitChanges(sessionId))) {
168
+ setUiBlocked(false);
169
+ return;
170
+ }
171
+ router.refresh();
172
+ //setEditOperations([]);
173
+ setUiBlocked(false);
174
+ toast.current.show({
175
+ severity: "success",
176
+ summary: "Saved",
177
+ detail: "Your changes were saved successfully.",
178
+ life: 3000,
179
+ });
180
+ if (callback)
181
+ callback();
182
+ });
183
+ // function ensureSaved(callback: () => void) {
184
+ // if (!edit.operations.length) {
185
+ // callback();
186
+ // return;
187
+ // }
188
+ // confirmDialog({
189
+ // message: "Save changes?",
190
+ // header: "Save changes?",
191
+ // icon: "pi pi-exclamation-triangle",
192
+ // accept: () => saveAndRefresh(callback),
193
+ // reject: callback,
194
+ // });
195
+ // }
196
+ function handleKeyDown(event) {
197
+ return __awaiter(this, void 0, void 0, function* () {
198
+ if (event.ctrlKey && event.key === "s") {
199
+ event.preventDefault();
200
+ yield saveAndRefresh();
201
+ }
202
+ if (event.ctrlKey && event.key === "z") {
203
+ event.preventDefault();
204
+ yield undo();
205
+ }
206
+ if (event.ctrlKey && event.key === "y") {
207
+ event.preventDefault();
208
+ yield redo();
209
+ }
210
+ });
211
+ }
212
+ if (typeof window !== "undefined")
213
+ useEventListener("keydown", handleKeyDown, window);
214
+ const toast = useRef();
215
+ useEffect(() => {
216
+ setPageData(content);
217
+ }, [content]);
218
+ useEffect(() => {
219
+ setEditData(edit);
220
+ }, [edit]);
221
+ function getComponentById(id) {
222
+ if (!page)
223
+ return null;
224
+ return findComponent(id, page.placeholders);
225
+ }
226
+ function redo() {
227
+ return __awaiter(this, void 0, void 0, function* () {
228
+ setUpdateContentEditingFields(!updateContentEditingFields);
229
+ let result = yield executeRedo(sessionId);
230
+ if (result.type === "success") {
231
+ router.refresh();
232
+ return true;
233
+ }
234
+ else {
235
+ showErrorToast(result);
236
+ return false;
237
+ }
238
+ });
239
+ }
240
+ function showErrorToast(result) {
241
+ toast.current.show({
242
+ severity: "error",
243
+ summary: result.summary,
244
+ detail: result.details,
245
+ life: 3000,
246
+ });
247
+ }
248
+ function undo() {
249
+ return __awaiter(this, void 0, void 0, function* () {
250
+ setUpdateContentEditingFields(!updateContentEditingFields);
251
+ let result = yield executeUndo(sessionId);
252
+ if (result.type === "success") {
253
+ router.refresh();
254
+ return true;
255
+ }
256
+ else {
257
+ showErrorToast(result);
258
+ return false;
259
+ }
260
+ });
261
+ }
262
+ const selectedComponent = selection.length === 1 && page ? getComponentById(selection[0]) : null;
263
+ const editField = (field, value, noRefresh = true) => {
264
+ var _a;
265
+ if (!page)
266
+ return;
267
+ const component = findComponent(field.itemId, page.placeholders);
268
+ let op = currentOperation;
269
+ if (!op ||
270
+ op.type !== "edit-field" ||
271
+ op.itemId !== field.itemId ||
272
+ op.fieldId !== field.id ||
273
+ op.language !== field.language ||
274
+ op.version !== field.version) {
275
+ op = {
276
+ type: "edit-field",
277
+ itemId: field.itemId,
278
+ fieldId: field.id,
279
+ version: field.version,
280
+ language: field.language,
281
+ fieldName: field.name,
282
+ itemName: field.itemId == page.id ? "Page" : (_a = component === null || component === void 0 ? void 0 : component.name) !== null && _a !== void 0 ? _a : "<unknown>",
283
+ pageItemId: page.id,
284
+ pageItemLanguage: page.language,
285
+ pageItemVersion: page.version,
286
+ date: new Date(),
287
+ id: uuid(),
288
+ };
289
+ }
290
+ op.date = new Date();
291
+ op.noRefresh = noRefresh;
292
+ op.refreshAfterQuietPeriod = !noRefresh;
293
+ op.value = value;
294
+ function getField(fields, id) {
295
+ return Object.values(fields).find((f) => f.id === id);
296
+ }
297
+ if (component) {
298
+ const f = getField(component.fields, field.id);
299
+ if (f && f.value != value) {
300
+ f.value = value;
301
+ }
302
+ }
303
+ else {
304
+ const f = getField(page.fields, field.id);
305
+ if (f && f.value != value)
306
+ f.value = value;
307
+ }
308
+ setCurrentOperation(op);
309
+ setCurrentEditOperation(Object.assign({}, op));
310
+ };
311
+ const menuItems = [
312
+ {
313
+ label: "Save",
314
+ icon: "pi pi-fw pi-save text-red",
315
+ command: () => saveAndRefresh(),
316
+ },
317
+ {
318
+ label: "Insert",
319
+ icon: "pi pi-fw pi-sitemap",
320
+ command: () => setComponentsPaletteVisible(true),
321
+ },
322
+ ];
323
+ const spinner = _jsx(ProgressSpinner, {});
324
+ const endContent = (_jsxs(_Fragment, { children: [_jsx(LanguageSelector, { page: page, onLanguageSelected: (language) => {
325
+ if (!language)
326
+ return;
327
+ //ensureSaved(() => switchLanguage(language));
328
+ switchLanguage(language);
329
+ } }), _jsx(VersionSelector, { page: page, onVersionSelected: (version) => {
330
+ switchVersion(version);
331
+ } })] }));
332
+ return (_jsxs(EditContextProvider, { value: {
333
+ sessionId: sessionId,
334
+ selection,
335
+ setSelection,
336
+ selectedForInsertion,
337
+ setSelectedForInsertion,
338
+ editField,
339
+ getComponentById,
340
+ dragObject,
341
+ dictionary,
342
+ setDictionary,
343
+ refreshCompletedFlag,
344
+ unresolvedDictionaryKeys,
345
+ setUnresolvedDictionaryKeys,
346
+ updateContentEditingFields,
347
+ showToast: () => { },
348
+ removeComponent: (componentId, callback) => {
349
+ confirmDialog({
350
+ message: "Are you sure you want to remove this component?",
351
+ header: "Remove component",
352
+ icon: "pi pi-exclamation-triangle",
353
+ accept: () => {
354
+ var _a;
355
+ const op = {
356
+ type: "remove-component",
357
+ date: new Date(),
358
+ id: uuid(),
359
+ pageItemId: page.id,
360
+ pageItemLanguage: page.language,
361
+ pageItemVersion: page.version,
362
+ componentId,
363
+ componentName: (_a = getComponentById(componentId)) === null || _a === void 0 ? void 0 : _a.name,
364
+ };
365
+ setCurrentEditOperation(op);
366
+ callback(true);
367
+ },
368
+ });
369
+ },
370
+ openComponentPalette: () => setComponentsPaletteVisible(true),
371
+ dragStart: (dragObject) => {
372
+ console.log("dragging " + JSON.stringify(dragObject));
373
+ setDragObject(dragObject);
374
+ },
375
+ droppedInPlaceholder: (placeholderKey, index) => __awaiter(this, void 0, void 0, function* () {
376
+ if (!dragObject)
377
+ return;
378
+ console.log(dragObject.templateId +
379
+ " dropped in " +
380
+ placeholderKey +
381
+ " " +
382
+ index);
383
+ // console.log(JSON.stringify(page));
384
+ const placeholderKeyComponents = placeholderKey.split("_");
385
+ const parentId = placeholderKeyComponents.length === 1
386
+ ? null
387
+ : placeholderKeyComponents[0];
388
+ const placeholderName = placeholderKeyComponents.length === 1
389
+ ? placeholderKeyComponents[0]
390
+ : placeholderKeyComponents[1];
391
+ let op;
392
+ if (dragObject.type == "template") {
393
+ op = {
394
+ type: "add-component",
395
+ pageItemId: page.id,
396
+ pageItemLanguage: page.language,
397
+ pageItemVersion: page.version,
398
+ parentItemId: parentId,
399
+ placeholderName: placeholderName,
400
+ placeholderIndex: index,
401
+ templateId: dragObject === null || dragObject === void 0 ? void 0 : dragObject.templateId,
402
+ date: new Date(),
403
+ id: uuid(),
404
+ };
405
+ }
406
+ if (dragObject.type == "component" ||
407
+ (dragObject.type == "link-component" && dragObject.componentId)) {
408
+ op = {
409
+ type: dragObject.type == "link-component"
410
+ ? "link-component"
411
+ : "move-component",
412
+ pageItemId: page.id,
413
+ pageItemLanguage: page.language,
414
+ pageItemVersion: page.version,
415
+ parentItemId: parentId,
416
+ placeholderName: placeholderName,
417
+ placeholderIndex: index,
418
+ componentId: dragObject.componentId,
419
+ date: new Date(),
420
+ id: uuid(),
421
+ };
422
+ }
423
+ //const newOps = [...editOperations, op];
424
+ //setEditOperations();
425
+ // await sendEditOperationsToServer(newOps as EditOperation[]);
426
+ // router.refresh();
427
+ //setEditOperations(newOps);
428
+ if (op)
429
+ setCurrentEditOperation(op);
430
+ setDragObject(undefined);
431
+ }),
432
+ }, children: [_jsx(Toast, { ref: toast }), _jsxs(PrimeReactProvider, { children: [_jsx(ConfirmDialog, {}), _jsx(Sidebar, { style: { width: "40%" }, visible: componentsPaletteVisible, position: "right", onHide: () => setComponentsPaletteVisible(false), pt: {
433
+ mask: {
434
+ onDragOver: () => setHidePalette(true),
435
+ style: {
436
+ left: hidePalette || !componentsPaletteVisible ? "100vw" : 0,
437
+ },
438
+ },
439
+ }, children: page && (_jsx(ComponentPalette, { page: page, selection: selection, dragStart: (dragObject) => {
440
+ //console.log("dragging " + JSON.stringify(dragObject));
441
+ setDragObject(dragObject);
442
+ }, dragEnd: () => {
443
+ setDragObject(undefined);
444
+ if (hidePalette) {
445
+ setComponentsPaletteVisible(false);
446
+ setHidePalette(false);
447
+ }
448
+ setSelectedForInsertion("");
449
+ } })) }), _jsxs(BlockUI, { blocked: uiBlocked, template: spinner, children: [_jsx(Menubar, { model: menuItems, end: endContent }), _jsxs(Splitter, { children: [_jsx(SplitterPanel, { size: 25, className: "alpaca-overflow-scroll", children: _jsxs(Splitter, { layout: "vertical", children: [_jsx(SplitterPanel, { className: "overflow-hidden relative", children: _jsx("div", { className: "inset-0 absolute overflow-y-auto", children: _jsx(ComponentTree, { page: page, selection: selection }) }) }), _jsx(SplitterPanel, { className: "alpaca-editor-tabs", children: _jsxs(TabView, { className: "inset-0 absolute", scrollable: true, children: [selectedComponent && (_jsxs(TabPanel, { header: "Fields", children: [_jsx(ComponentInfo, { component: selectedComponent }), _jsx(FieldList, { fields: selectedComponent.fields })] })), selectedComponent && (_jsx(TabPanel, { header: "GraphQL", style: { height: "100%" }, children: _jsx(GraphQL, { component: selectedComponent }) })), _jsxs(TabPanel, { header: "Page", children: [page && _jsx(PageInfo, { page: page }), page && _jsx(FieldList, { fields: page.fields })] }), _jsx(TabPanel, { header: "Dictionary", children: _jsx(DictionaryEditor, { dictionary: dictionary }) }), _jsx(TabPanel, { header: "Debug", children: _jsx(Debug, { component: selectedComponent, page: page }) })] }) })] }) }), _jsx(SplitterPanel, { size: 55, className: "alpaca-overflow-scroll alpaca-editor-content", children: _jsx("div", { onDragEndCapture: () => setDragObject(undefined), children: children }) }), _jsx(SplitterPanel, { size: 20, children: _jsxs(Splitter, { layout: "vertical", className: "alpaca-editor", children: [_jsx(SplitterPanel, { className: "overflow-hidden relative", children: _jsx(EditHistory, { operations: editData === null || editData === void 0 ? void 0 : editData.operations }) }), _jsx(SplitterPanel, { className: "overflow-hidden relative", children: _jsx(AiTerminal, { selection: selection, requestRefresh: requestRefresh }) })] }) })] })] })] })] }));
450
+ }
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import dynamic from "next/dynamic";
4
+ const EditorClient = dynamic(() => import("./EditorClient").then((dnd) => dnd.EditorClient), { ssr: false });
5
+ export function EditorClientHost({ content, dictionaryObject, children, edit, }) {
6
+ return (_jsx(EditorClient, { content: content, dictionaryObject: dictionaryObject, edit: edit, children: children }));
7
+ }
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { InputText } from "primereact/inputtext";
4
+ import { Checkbox } from "primereact/checkbox";
5
+ import { SingleLineText } from "./fieldTypes/SingleLineText";
6
+ import { RichTextEditor } from "./fieldTypes/RichTextEditor";
7
+ export function FieldList({ fields }) {
8
+ if (!fields)
9
+ return;
10
+ if (!Array.isArray(fields))
11
+ fields = Object.values(fields);
12
+ const sections = fields.reduce((acc, value) => {
13
+ // Group initialization
14
+ if (!acc[value.section || "Default"]) {
15
+ acc[value.section || "Default"] = [];
16
+ }
17
+ // Grouping
18
+ acc[value.section || "Default"].push(value);
19
+ return acc;
20
+ }, {});
21
+ const sectionList = Object.values(sections);
22
+ sectionList.sort((a, b) => b[0].sortOrder - a[0].sortOrder);
23
+ return (_jsx("div", { className: "p-1", children: Object.keys(sections).map((section) => (_jsxs("div", { children: [_jsx("div", { className: "alpaca-fields-section-headline", children: section }), getSectionFields(sections[section])] }, section))) }));
24
+ }
25
+ function getSectionFields(fields) {
26
+ return fields.map((field) => (_jsxs("div", { children: [_jsx("label", { className: "alpaca-field-label", children: field.name }), !field.containsFallbackValue ? (_jsx("button", { className: "text-xs p-0 m-1", children: "Reset " })) : (_jsx("button", { children: "Fallback" })), _jsx("div", { children: getFieldEditor(field) })] }, field.id)));
27
+ }
28
+ function getFieldEditor(field) {
29
+ switch (field.type) {
30
+ case "checkbox":
31
+ return checkbox(field);
32
+ case "picture":
33
+ return picture(field);
34
+ case "image":
35
+ return image(field);
36
+ case "rich text":
37
+ return _jsx(RichTextEditor, { field: field });
38
+ default:
39
+ return _jsx(SingleLineText, { field: field });
40
+ }
41
+ }
42
+ function checkbox(field) {
43
+ return _jsx(Checkbox, { checked: field.value === "1" });
44
+ }
45
+ // function singleLineText(field: Field) {
46
+ // return <InputText value={field.value as string} />;
47
+ // }
48
+ function picture(field) {
49
+ var _a, _b;
50
+ return (_jsxs(_Fragment, { children: [_jsx("label", { className: "alpaca-minor-label", children: "Alt" }), _jsx(InputText, { value: (_b = (_a = field.value) === null || _a === void 0 ? void 0 : _a.alt) !== null && _b !== void 0 ? _b : "" })] }));
51
+ }
52
+ function image(field) {
53
+ var _a, _b;
54
+ return (_jsxs(_Fragment, { children: [_jsx("label", { className: "alpaca-minor-label", children: "Alt" }), _jsx(InputText, { value: (_b = (_a = field.value) === null || _a === void 0 ? void 0 : _a.altText) !== null && _b !== void 0 ? _b : "" })] }));
55
+ }
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEditContext } from "..";
3
+ import JSONPretty from "react-json-pretty";
4
+ import "react-json-pretty/themes/monikai.css";
5
+ import { TabView, TabPanel } from "primereact/tabview";
6
+ import { FieldList } from "./FieldList";
7
+ import { Splitter, SplitterPanel } from "primereact/splitter";
8
+ import { InputTextarea } from "primereact/inputtextarea";
9
+ import { Button } from "primereact/button";
10
+ import { useEffect, useState } from "react";
11
+ import { format } from "graphql-formatter";
12
+ export function GraphQL({ component }) {
13
+ const editContext = useEditContext();
14
+ const [query, setQuery] = useState("");
15
+ const [showSpinner, setShowSpinner] = useState(false);
16
+ if (!(component === null || component === void 0 ? void 0 : component.graphql))
17
+ return;
18
+ useEffect(() => {
19
+ setQuery(component.graphql_query);
20
+ }, [component.graphql_query]);
21
+ useEffect(() => {
22
+ setShowSpinner(false);
23
+ }, [editContext === null || editContext === void 0 ? void 0 : editContext.refreshCompletedFlag]);
24
+ function findFields(json) {
25
+ let result = {};
26
+ for (let key in json) {
27
+ if (typeof json[key] === "object" && json[key] !== null) {
28
+ let subResult = findFields(json[key]);
29
+ for (let subKey in subResult) {
30
+ if (result[subKey]) {
31
+ result[subKey] = result[subKey].concat(subResult[subKey]);
32
+ }
33
+ else {
34
+ result[subKey] = subResult[subKey];
35
+ }
36
+ }
37
+ }
38
+ if (key === "jsonValue") {
39
+ let groupKey = `${json[key].itemId}_${json[key].language}_${json[key].version}`;
40
+ if (result[groupKey]) {
41
+ result[groupKey].push(json[key]);
42
+ }
43
+ else {
44
+ result[groupKey] = [json[key]];
45
+ }
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ const fieldsjsonValues = findFields(component.graphql);
51
+ function renderItem(fields) {
52
+ const first = fields[0];
53
+ return (_jsxs("div", { children: ["Item: ", first.path, " ", first.id, " ", first.language, " ", first.version, _jsx(FieldList, { fields: fields })] }, first.path + first.id + first.language + first.version));
54
+ }
55
+ function refresh() {
56
+ var _a, _b;
57
+ if (!component)
58
+ return;
59
+ let language = ((_a = component.hostingPageItem) === null || _a === void 0 ? void 0 : _a.language) || "en";
60
+ let version = ((_b = component.hostingPageItem) === null || _b === void 0 ? void 0 : _b.version) || 0;
61
+ if (component.linkedComponentItem) {
62
+ language = component.linkedComponentItem.language;
63
+ version = component.linkedComponentItem.version;
64
+ }
65
+ const field = {
66
+ name: "_GraphQL",
67
+ itemId: component === null || component === void 0 ? void 0 : component.id,
68
+ language: language,
69
+ version: version,
70
+ path: "graphql",
71
+ id: "3622F861-ECA9-45D7-8DA7-2CDA35235002",
72
+ value: query,
73
+ type: "jsonValue",
74
+ };
75
+ const prettyQuery = format(query);
76
+ console.log(query);
77
+ console.log(prettyQuery);
78
+ setQuery(prettyQuery);
79
+ editContext === null || editContext === void 0 ? void 0 : editContext.editField(field, prettyQuery, false);
80
+ setShowSpinner(true);
81
+ }
82
+ return (_jsxs(Splitter, { layout: "vertical", style: { height: "100%" }, children: [_jsx(SplitterPanel, { size: 50, className: "relative", children: _jsxs("div", { className: "absolute inset-0 flex", children: [_jsx(InputTextarea, { value: query, onChange: (e) => setQuery(e.target.value), className: "flex-1", style: { height: "100%" } }), _jsx(Button, { icon: "pi pi-refresh" + (showSpinner ? " pi-spin" : ""), onClick: refresh, disabled: showSpinner })] }) }), _jsx(SplitterPanel, { className: "alpaca-editor-tabs", children: _jsxs(TabView, { className: "inset-0 absolute", children: [_jsx(TabPanel, { header: "Data", style: { height: "100%" }, className: "relative", children: _jsx("div", { className: "m-1", children: Object.values(fieldsjsonValues).map((x) => renderItem(x)) }) }), _jsx(TabPanel, { header: "JSON", className: "relative", style: { height: "100%" }, children: _jsx("div", { className: "inset-0 absolute overflow-y-auto", children: _jsx(JSONPretty, { data: component.graphql }) }) })] }) })] }));
83
+ }
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Dropdown } from "primereact/dropdown";
4
+ export function LanguageSelector({ page, onLanguageSelected, }) {
5
+ if (page == null)
6
+ return;
7
+ const selectedCountryTemplate = (option, props) => {
8
+ if (option) {
9
+ return _jsx("div", { children: option.name });
10
+ }
11
+ return _jsx("span", { children: props.placeholder });
12
+ };
13
+ const countryOptionTemplate = (option) => {
14
+ return (_jsxs("div", { children: [option.name, " (", option.versions, ")"] }));
15
+ };
16
+ return (_jsx(_Fragment, { children: _jsx(Dropdown, { value: page.language, onChange: (e) => onLanguageSelected(e.value), options: page.languages, optionValue: "languageCode", optionLabel: "name", placeholder: "Select a language", filter: true, valueTemplate: selectedCountryTemplate, itemTemplate: countryOptionTemplate }) }));
17
+ }
@@ -0,0 +1,54 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import { Sidebar } from "primereact/sidebar";
12
+ import ContentTree from "./ContentTree";
13
+ import { Splitter, SplitterPanel } from "primereact/splitter";
14
+ import { useEffect, useState } from "react";
15
+ import { getChildren } from "./contentService";
16
+ import { useEditContext } from "./editContext";
17
+ import { Button } from "primereact/button";
18
+ export const MediaSelector = ({ visible, onHide, onMediaSelected, }) => {
19
+ const [selectedFolderId, setSelectedFolderId] = useState();
20
+ const [images, setImages] = useState();
21
+ const [selectedImage, setSelectedImage] = useState();
22
+ const selection = selectedFolderId ? [selectedFolderId] : [];
23
+ const editContext = useEditContext();
24
+ useEffect(() => {
25
+ loadThumbnails(selectedFolderId);
26
+ }, [selectedFolderId]);
27
+ function loadThumbnails(selectedFolderId) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ if (!selectedFolderId)
30
+ setImages([]);
31
+ else {
32
+ const children = yield getChildren(selectedFolderId, editContext.sessionId, [
33
+ "C97BA923-8009-4858-BDD5-D8BE5FCCECF7",
34
+ "F1828A2C-7E5D-4BBD-98CA-320474871548",
35
+ ]);
36
+ setImages(children);
37
+ }
38
+ });
39
+ }
40
+ return (_jsx(Sidebar, { style: { width: "60%" }, position: "right", visible: visible, onHide: onHide, children: _jsxs("div", { className: "flex flex-col h-full", children: [_jsxs(Splitter, { className: "flex-1 border-0", children: [_jsx(SplitterPanel, { size: 35, className: "alpaca-overflow-scroll", children: _jsxs(Splitter, { layout: "vertical", children: [_jsx(SplitterPanel, { size: 70, children: _jsx(ContentTree, { rootItemId: "3D6658D8-A0BF-4E75-B3E2-D050FABCF4E1", selectionMode: "single", selectedItemIds: selection, templateIds: ["FE5DD826-48C6-436D-B87A-7C4210C7413B"], expandIdPath: "3D6658D8-A0BF-4E75-B3E2-D050FABCF4E1", onSelectionChange: (selection) => {
41
+ if (selection.length)
42
+ setSelectedFolderId(selection[0]);
43
+ else
44
+ setSelectedFolderId(undefined);
45
+ } }) }), _jsx(SplitterPanel, { children: selectedImage === null || selectedImage === void 0 ? void 0 : selectedImage.name })] }) }), _jsx(SplitterPanel, { className: "alpaca-overflow-scroll relative", children: _jsx("div", { className: "grid grid-cols-3 gap-2 absolute inset-0", children: images === null || images === void 0 ? void 0 : images.map((t) => {
46
+ return (_jsxs("div", { className: "flex flex-col justify-between hover:shadow-md cursor-pointer p-1", onDoubleClick: () => {
47
+ onMediaSelected(t.id);
48
+ onHide();
49
+ }, onClick: () => setSelectedImage(t), children: [_jsx("img", { src: t.imageUrl }), _jsx("div", { className: "text-xs break-all", children: t.name })] }));
50
+ }) }) })] }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx(Button, { onClick: () => onHide(), children: "Cancel" }), _jsx(Button, { disabled: !selectedImage, onClick: () => {
51
+ onMediaSelected(selectedImage.id);
52
+ onHide();
53
+ }, children: "Select" })] })] }) }));
54
+ };