@alpaca-editor/core 1.0.4009 → 1.0.4011

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 (40) hide show
  1. package/dist/config/config.js +4 -16
  2. package/dist/config/config.js.map +1 -1
  3. package/dist/editor/ScrollingContentTree.d.ts +2 -1
  4. package/dist/editor/ScrollingContentTree.js +7 -3
  5. package/dist/editor/ScrollingContentTree.js.map +1 -1
  6. package/dist/editor/client/EditorClient.js +185 -64
  7. package/dist/editor/client/EditorClient.js.map +1 -1
  8. package/dist/editor/client/editContext.d.ts +3 -21
  9. package/dist/editor/client/editContext.js.map +1 -1
  10. package/dist/editor/field-types/InternalLinkFieldEditor.js +18 -78
  11. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  12. package/dist/editor/field-types/TreeListEditor.js +51 -48
  13. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  14. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +2 -2
  15. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +1 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/page-wizard/PageWizard.js +50 -75
  20. package/dist/page-wizard/PageWizard.js.map +1 -1
  21. package/dist/page-wizard/WizardSteps.js +19 -34
  22. package/dist/page-wizard/WizardSteps.js.map +1 -1
  23. package/dist/page-wizard/startPageWizardCommand.js +2 -3
  24. package/dist/page-wizard/startPageWizardCommand.js.map +1 -1
  25. package/dist/revision.d.ts +2 -2
  26. package/dist/revision.js +2 -2
  27. package/dist/styles.css +0 -3
  28. package/package.json +1 -1
  29. package/src/config/config.tsx +6 -18
  30. package/src/editor/ScrollingContentTree.tsx +10 -4
  31. package/src/editor/client/EditorClient.tsx +228 -76
  32. package/src/editor/client/editContext.ts +29 -27
  33. package/src/editor/field-types/InternalLinkFieldEditor.tsx +71 -144
  34. package/src/editor/field-types/TreeListEditor.tsx +95 -84
  35. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +2 -2
  36. package/src/index.ts +1 -0
  37. package/src/page-wizard/PageWizard.tsx +69 -93
  38. package/src/page-wizard/WizardSteps.tsx +25 -38
  39. package/src/page-wizard/startPageWizardCommand.ts +2 -3
  40. package/src/revision.ts +2 -2
@@ -1,9 +1,10 @@
1
- import { useEffect, useRef } from "react";
1
+ import { useEffect, useRef, useState } from "react";
2
2
  import { useEditContext } from "../editor/client/editContext";
3
3
  import { getWizards } from "./service";
4
4
 
5
5
  import { WizardSteps } from "./WizardSteps";
6
6
  import { Thumbnail } from "../editor/services/contentService";
7
+ import { Spinner } from "../editor/ui/Spinner";
7
8
 
8
9
  export type Wizard = {
9
10
  id: string;
@@ -92,108 +93,83 @@ export type WizardField = {
92
93
 
93
94
  export function PageWizard() {
94
95
  const editContext = useEditContext();
95
- const hasProcessedUrl = useRef(false);
96
- const isLoadingFromUrl = useRef(false);
97
- const urlWizardId = useRef<string | null>(null);
96
+ const [wizard, setWizard] = useState<Wizard | null>(null);
97
+ const [parentItem, setParentItem] = useState<any>(null);
98
+ const [isLoading, setIsLoading] = useState(true);
98
99
 
99
- const { wizard, parentItem } = editContext?.pageWizard || {};
100
-
101
- // Load all wizards and check URL param on mount
102
100
  useEffect(() => {
103
- if (!editContext?.currentItemDescriptor || hasProcessedUrl.current) return;
104
-
105
- const params = new URLSearchParams(window.location.search);
106
- const wizardId = params.get("wizardId");
107
- urlWizardId.current = wizardId;
108
-
109
- if (wizardId && !wizard) {
110
- isLoadingFromUrl.current = true;
111
-
112
- getWizards(editContext.currentItemDescriptor)
113
- .then((availableWizards) => {
114
- // Find wizard by ID from the loaded wizards
115
- const foundWizard = availableWizards.find((w) => w.id === wizardId);
116
-
117
- if (foundWizard) {
118
- editContext.pageWizard.setWizard(foundWizard);
119
- editContext.pageWizard.setParentItem(
120
- editContext.currentItemDescriptor,
121
- );
122
- } else {
123
- // Remove invalid wizardId from URL
124
- const newParams = new URLSearchParams(window.location.search);
125
- newParams.delete("wizardId");
126
- const newUrl = newParams.toString()
127
- ? `${window.location.pathname}?${newParams.toString()}`
128
- : window.location.pathname;
129
- window.history.pushState({}, "", newUrl);
130
- }
131
-
132
- isLoadingFromUrl.current = false;
133
- hasProcessedUrl.current = true;
134
- })
135
- .catch((error) => {
136
- console.error("PageWizard: Error loading wizards:", error);
137
- isLoadingFromUrl.current = false;
138
- hasProcessedUrl.current = true;
139
- });
140
- } else {
141
- hasProcessedUrl.current = true;
142
- }
143
- }, [editContext?.currentItemDescriptor]);
144
-
145
- // Update URL when wizard is set programmatically (not from URL)
146
- useEffect(() => {
147
- // Don't update URL if we're loading from URL or haven't processed URL yet
148
- if (isLoadingFromUrl.current || !hasProcessedUrl.current) {
149
- return;
150
- }
101
+ const wizardId = editContext?.currentWizardId;
102
+
103
+ async function loadWizard() {
104
+ if (wizard) return;
105
+ if (!wizardId) {
106
+ // If no wizard ID, we can't proceed
107
+ console.log("PageWizard - No wizard ID, cannot load wizard");
108
+ setIsLoading(false);
109
+ return;
110
+ }
151
111
 
152
- const params = new URLSearchParams(window.location.search);
153
- const currentWizardParam = params.get("wizardId");
112
+ // If no content editor item yet, keep waiting (don't give up)
113
+ if (!editContext?.contentEditorItem) {
114
+ setIsLoading(true);
115
+ return;
116
+ }
154
117
 
155
- if (wizard && currentWizardParam !== wizard.id) {
156
- // Add wizard to URL (only if it wasn't the original URL wizard)
157
- if (urlWizardId.current !== wizard.id) {
158
- params.set("wizardId", wizard.id);
159
- const newUrl = `${window.location.pathname}?${params.toString()}`;
160
- window.history.pushState({}, "", newUrl);
118
+ setIsLoading(true);
119
+ try {
120
+ const availableWizards = await getWizards(
121
+ editContext.contentEditorItem.descriptor,
122
+ );
123
+ const foundWizard = availableWizards.find((w) => w.id === wizardId);
124
+ if (foundWizard) {
125
+ setWizard(foundWizard);
126
+ setParentItem(editContext.contentEditorItem.descriptor);
127
+ } else {
128
+ console.log("PageWizard - Wizard not found:", wizardId);
129
+ // Only switch away if we actually looked for the wizard and didn't find it
130
+ editContext?.switchView("content-editor", { skipConfirmation: true });
131
+ }
132
+ } catch (error) {
133
+ console.error("PageWizard: Error loading wizards:", error);
134
+ editContext?.switchView("content-editor", { skipConfirmation: true });
135
+ } finally {
136
+ setIsLoading(false);
161
137
  }
162
- } else if (
163
- !wizard &&
164
- currentWizardParam &&
165
- urlWizardId.current !== currentWizardParam
166
- ) {
167
- // Only remove wizard from URL if it's different from the original URL wizard
168
- params.delete("wizardId");
169
- const newUrl = params.toString()
170
- ? `${window.location.pathname}?${params.toString()}`
171
- : window.location.pathname;
172
- window.history.pushState({}, "", newUrl);
173
138
  }
174
- }, [wizard]);
175
139
 
176
- if (!editContext?.currentItemDescriptor) {
177
- return <div>Loading...</div>;
140
+ loadWizard();
141
+ }, [editContext?.contentEditorItem, editContext?.currentWizardId]);
142
+
143
+ // Show loading spinner while waiting for item to load or wizard to load
144
+ if (
145
+ isLoading ||
146
+ (!editContext?.contentEditorItem && editContext?.currentWizardId)
147
+ ) {
148
+ return (
149
+ <div className="flex h-full items-center justify-center">
150
+ <Spinner />
151
+ </div>
152
+ );
178
153
  }
179
154
 
180
- // Check if we're loading from URL - don't switch back to content-editor in that case
181
- const params = new URLSearchParams(window.location.search);
182
- const currentUrlWizardId = params.get("wizardId");
183
-
184
- if (!parentItem || !wizard) {
185
- // If we have a wizardId in URL but wizard hasn't loaded yet, show loading
186
- if (currentUrlWizardId && !wizard) {
187
- return (
188
- <div className="flex h-full items-center justify-center">
189
- Loading wizard...
190
- </div>
191
- );
192
- }
193
- // Otherwise switch back to content-editor
194
- editContext.switchView("content-editor", { skipConfirmation: true });
155
+ // Only switch away if we have no wizard AND no wizard ID (i.e., we're not supposed to be here)
156
+ if (!wizard && !editContext?.currentWizardId) {
157
+ console.log(
158
+ "PageWizard - No wizard and no wizard ID, switching to content-editor",
159
+ );
160
+ editContext?.switchView("content-editor", { skipConfirmation: true });
195
161
  return null;
196
162
  }
197
163
 
198
- return <WizardSteps wizard={wizard} parentItem={parentItem} />;
164
+ // If we have a wizard, render it
165
+ if (wizard && parentItem) {
166
+ return <WizardSteps wizard={wizard} parentItem={parentItem} />;
167
+ }
168
+
169
+ // Still waiting for wizard to load
170
+ return (
171
+ <div className="flex h-full items-center justify-center">
172
+ <Spinner />
173
+ </div>
174
+ );
199
175
  }
@@ -4,14 +4,13 @@ import { Wizard, WizardData, WizardPageModel, WizardStep } from "./PageWizard";
4
4
  import { ItemDescriptor } from "../editor/pageModel";
5
5
  import { Logo } from "../editor/ui/Icons";
6
6
 
7
- import { flushSync } from "react-dom";
8
7
  import { useEditContext } from "../editor/client/editContext";
9
8
  import { classNames } from "primereact/utils";
10
9
  import { ChevronLeft, ChevronRight, X } from "lucide-react";
11
10
 
12
11
  import { Button } from "../components/ui/button";
13
12
  import { cn } from "../lib/utils";
14
- import { useRef, useEffect } from "react";
13
+ import { useRef, useEffect, useState } from "react";
15
14
 
16
15
  interface WizardStepsProps {
17
16
  wizard: Wizard;
@@ -318,6 +317,21 @@ function MobileNavigationButtons({
318
317
  }
319
318
 
320
319
  export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
320
+ // Local state management instead of pageWizard context
321
+ const [currentStepIndex, setCurrentStepIndex] = useState(0);
322
+ const [data, setData] = useState<WizardData>({});
323
+ const [pageModel, setPageModel] = useState<WizardPageModel>({
324
+ components: [],
325
+ name: "",
326
+ metaDescription: "",
327
+ metaKeywords: "",
328
+ fields: [],
329
+ });
330
+ const [internalState, setInternalState] = useState<any>({});
331
+ const [stepCompleted, setStepCompleted] = useState(-1);
332
+
333
+ const beforeNextCallbackRef = useRef<(() => Promise<boolean>) | null>(null);
334
+
321
335
  useEffect(() => {
322
336
  const handleBeforeUnload = (e: BeforeUnloadEvent) => {
323
337
  e.preventDefault();
@@ -332,36 +346,10 @@ export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
332
346
  }, []);
333
347
 
334
348
  const editContext = useEditContext();
335
- const pageWizard = editContext?.pageWizard;
336
-
337
- // Use state from pageWizard context instead of local state
338
- const currentStepIndex = pageWizard?.currentStepIndex ?? 0;
339
- const setCurrentStepIndex = pageWizard?.setCurrentStepIndex ?? (() => {});
340
- const data = pageWizard?.data ?? {};
341
- const setData = pageWizard?.setData ?? (() => {});
342
- const pageModel = pageWizard?.pageModel ?? {
343
- components: [],
344
- name: "",
345
- metaDescription: "",
346
- metaKeywords: "",
347
- fields: [],
348
- };
349
- const setPageModel = pageWizard?.setPageModel ?? (() => {});
350
- const internalState = pageWizard?.internalState ?? {};
351
- const setInternalState = pageWizard?.setInternalState ?? (() => {});
352
- const stepCompleted = pageWizard?.stepCompleted ?? -1;
353
- const setStepCompleted = pageWizard?.setStepCompleted ?? (() => {});
354
-
355
- const beforeNextCallbackRef = pageWizard?.beforeNextCallbackRef ?? {
356
- current: null,
357
- };
358
-
359
349
  const isMobile = editContext?.isMobile ?? false;
360
350
 
361
351
  const setBeforeNextCallback = (callback: (() => Promise<boolean>) | null) => {
362
- if (beforeNextCallbackRef) {
363
- beforeNextCallbackRef.current = callback;
364
- }
352
+ beforeNextCallbackRef.current = callback;
365
353
  };
366
354
 
367
355
  const getCurrentStep = () => {
@@ -393,7 +381,9 @@ export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
393
381
  wizard={wizard}
394
382
  setStepCompleted={(completed) => {
395
383
  if (completed) {
396
- setStepCompleted((prev) => Math.max(prev, currentStepIndex));
384
+ setStepCompleted((prev: number) =>
385
+ Math.max(prev, currentStepIndex),
386
+ );
397
387
  } else {
398
388
  setStepCompleted(currentStepIndex - 1);
399
389
  }
@@ -410,18 +400,14 @@ export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
410
400
  };
411
401
 
412
402
  const switchStep = (index: number) => {
403
+ beforeNextCallbackRef.current = null; // Clear callback when switching steps
404
+
413
405
  if (typeof document.startViewTransition === "function") {
414
406
  document.startViewTransition(() => {
415
- flushSync(() => {
416
- setCurrentStepIndex(index);
417
- beforeNextCallbackRef.current = null; // Clear callback when switching steps
418
- });
419
- });
420
- } else {
421
- flushSync(() => {
422
407
  setCurrentStepIndex(index);
423
- beforeNextCallbackRef.current = null; // Clear callback when switching steps
424
408
  });
409
+ } else {
410
+ setCurrentStepIndex(index);
425
411
  }
426
412
  };
427
413
 
@@ -447,6 +433,7 @@ export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
447
433
  };
448
434
 
449
435
  const handleClose = () => {
436
+ editContext?.setCurrentWizardId(null);
450
437
  editContext?.switchView("content-editor");
451
438
  };
452
439
 
@@ -13,10 +13,9 @@ export const startPageWizardCommand = {
13
13
 
14
14
  await context.editContext.loadItem(context.data.item);
15
15
 
16
- // Add wizard name to URL
16
+ // Set wizard state (URL will be synced automatically)
17
17
  if (context.data?.wizard) {
18
- context.editContext.pageWizard.setWizard(context.data.wizard);
19
- context.editContext.pageWizard.setParentItem(context.data.item);
18
+ context.editContext.setCurrentWizardId(context.data.wizard.id);
20
19
  context.editContext.switchView("page-wizard");
21
20
  }
22
21
  },
package/src/revision.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = "1.0.4009";
2
- export const buildDate = "2025-07-21 01:46:16";
1
+ export const version = "1.0.4011";
2
+ export const buildDate = "2025-07-22 15:34:03";