@orion-studios/payload-studio 0.6.0-beta.120 → 0.6.0-beta.121

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.
@@ -2115,6 +2115,7 @@ function GrapesPageEditor({
2115
2115
  }
2116
2116
  return null;
2117
2117
  };
2118
+ const isOrionBlockComponent = (component) => Object.keys(parseOrionBlockAttribute(component?.getAttributes?.()?.["data-orion-block"])).length > 0;
2118
2119
  const findSelectedCanvasOrionBlock = () => {
2119
2120
  const editor = editorRef.current;
2120
2121
  const wrapper = editor?.DomComponents?.getWrapper?.() || null;
@@ -2597,9 +2598,14 @@ function GrapesPageEditor({
2597
2598
  if (!component) {
2598
2599
  return null;
2599
2600
  }
2601
+ const parent = component.parent?.();
2602
+ const collection = parent?.components?.();
2603
+ const index = typeof collection?.indexOf === "function" ? collection.indexOf(component) : void 0;
2600
2604
  return {
2601
2605
  attributes: { ...component.getAttributes?.() || {} },
2602
2606
  component,
2607
+ index,
2608
+ parent,
2603
2609
  style: { ...component.getStyle?.() || {} }
2604
2610
  };
2605
2611
  };
@@ -2611,12 +2617,31 @@ function GrapesPageEditor({
2611
2617
  return snapshot;
2612
2618
  };
2613
2619
  const getPreviousComponentSnapshot = (component) => component ? lastComponentSnapshotRef.current.get(component) || snapshotComponent(component) : null;
2620
+ const isComponentAttached = (component) => Boolean(component.parent?.());
2621
+ const addComponentFromSnapshot = (snapshot) => {
2622
+ const parent = snapshot.parent;
2623
+ if (isComponentAttached(snapshot.component) || !parent?.components) {
2624
+ return;
2625
+ }
2626
+ parent.components?.().add?.(snapshot.component, { at: snapshot.index });
2627
+ };
2628
+ const removeComponentFromSnapshot = (snapshot) => {
2629
+ ;
2630
+ snapshot.component.remove?.();
2631
+ };
2614
2632
  const restoreComponentSnapshot = (snapshot) => {
2633
+ addComponentFromSnapshot(snapshot);
2615
2634
  const currentStyle = snapshot.component.getStyle?.() || {};
2635
+ const currentAttributes = snapshot.component.getAttributes?.() || {};
2636
+ const staleAttributes = Object.keys(currentAttributes).filter((key) => !(key in snapshot.attributes));
2616
2637
  snapshot.component.addStyle?.({
2617
2638
  ...Object.fromEntries(Object.keys(currentStyle).map((key) => [key, ""])),
2618
2639
  ...Object.fromEntries(Object.entries(snapshot.style).map(([key, value]) => [key, String(value)]))
2619
2640
  });
2641
+ if (staleAttributes.length > 0) {
2642
+ ;
2643
+ snapshot.component.removeAttributes?.(staleAttributes);
2644
+ }
2620
2645
  snapshot.component.addAttributes?.({ ...snapshot.attributes });
2621
2646
  selectedComponentRef.current = snapshot.component;
2622
2647
  lastSelectedComponentRef.current = snapshot.component;
@@ -2625,16 +2650,33 @@ function GrapesPageEditor({
2625
2650
  lastComponentSnapshotRef.current.set(snapshot.component, snapshot);
2626
2651
  refreshSelectedState(snapshot.component);
2627
2652
  };
2653
+ const restoreCustomHistoryEntry = (entry, target) => {
2654
+ const snapshot = entry[target];
2655
+ const otherSnapshot = target === "before" ? entry.after : entry.before;
2656
+ if (!snapshot) {
2657
+ if (otherSnapshot) {
2658
+ removeComponentFromSnapshot(otherSnapshot);
2659
+ }
2660
+ refreshSelectedState(null);
2661
+ return;
2662
+ }
2663
+ restoreComponentSnapshot(snapshot);
2664
+ };
2628
2665
  const pushCustomHistoryEntry = (before, after) => {
2629
- if (!before || !after || before.component !== after.component) {
2666
+ if (!before && !after) {
2667
+ return;
2668
+ }
2669
+ if (before && after && before.component !== after.component) {
2630
2670
  return;
2631
2671
  }
2632
- if (JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2672
+ if (before && after && JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2633
2673
  return;
2634
2674
  }
2635
2675
  customUndoStackRef.current.push({ after, before });
2636
2676
  customRedoStackRef.current = [];
2637
- lastComponentSnapshotRef.current.set(after.component, after);
2677
+ if (after) {
2678
+ lastComponentSnapshotRef.current.set(after.component, after);
2679
+ }
2638
2680
  if (customUndoStackRef.current.length > 100) {
2639
2681
  customUndoStackRef.current.shift();
2640
2682
  }
@@ -2666,7 +2708,7 @@ function GrapesPageEditor({
2666
2708
  const customEntry = action === "undo" ? customUndoStackRef.current.pop() : customRedoStackRef.current.pop();
2667
2709
  if (customEntry) {
2668
2710
  historyRestoreActiveRef.current = true;
2669
- restoreComponentSnapshot(action === "undo" ? customEntry.before : customEntry.after);
2711
+ restoreCustomHistoryEntry(customEntry, action === "undo" ? "before" : "after");
2670
2712
  if (action === "undo") {
2671
2713
  customRedoStackRef.current.push(customEntry);
2672
2714
  } else {
@@ -2932,6 +2974,21 @@ function GrapesPageEditor({
2932
2974
  }
2933
2975
  );
2934
2976
  });
2977
+ editor.on("component:add", (component) => {
2978
+ if (historyRestoreActiveRef.current) {
2979
+ return;
2980
+ }
2981
+ const typed = component;
2982
+ if (!isOrionBlockComponent(typed)) {
2983
+ return;
2984
+ }
2985
+ window.setTimeout(() => {
2986
+ if (historyRestoreActiveRef.current) {
2987
+ return;
2988
+ }
2989
+ pushCustomHistoryEntry(null, snapshotComponent(typed));
2990
+ }, 0);
2991
+ });
2935
2992
  editor.on("component:selected", (component) => {
2936
2993
  const typed = component;
2937
2994
  const target = getCurrentOrionBlockTarget(typed) || typed;
@@ -1991,6 +1991,7 @@ function GrapesPageEditor({
1991
1991
  }
1992
1992
  return null;
1993
1993
  };
1994
+ const isOrionBlockComponent = (component) => Object.keys(parseOrionBlockAttribute(component?.getAttributes?.()?.["data-orion-block"])).length > 0;
1994
1995
  const findSelectedCanvasOrionBlock = () => {
1995
1996
  const editor = editorRef.current;
1996
1997
  const wrapper = editor?.DomComponents?.getWrapper?.() || null;
@@ -2473,9 +2474,14 @@ function GrapesPageEditor({
2473
2474
  if (!component) {
2474
2475
  return null;
2475
2476
  }
2477
+ const parent = component.parent?.();
2478
+ const collection = parent?.components?.();
2479
+ const index = typeof collection?.indexOf === "function" ? collection.indexOf(component) : void 0;
2476
2480
  return {
2477
2481
  attributes: { ...component.getAttributes?.() || {} },
2478
2482
  component,
2483
+ index,
2484
+ parent,
2479
2485
  style: { ...component.getStyle?.() || {} }
2480
2486
  };
2481
2487
  };
@@ -2487,12 +2493,31 @@ function GrapesPageEditor({
2487
2493
  return snapshot;
2488
2494
  };
2489
2495
  const getPreviousComponentSnapshot = (component) => component ? lastComponentSnapshotRef.current.get(component) || snapshotComponent(component) : null;
2496
+ const isComponentAttached = (component) => Boolean(component.parent?.());
2497
+ const addComponentFromSnapshot = (snapshot) => {
2498
+ const parent = snapshot.parent;
2499
+ if (isComponentAttached(snapshot.component) || !parent?.components) {
2500
+ return;
2501
+ }
2502
+ parent.components?.().add?.(snapshot.component, { at: snapshot.index });
2503
+ };
2504
+ const removeComponentFromSnapshot = (snapshot) => {
2505
+ ;
2506
+ snapshot.component.remove?.();
2507
+ };
2490
2508
  const restoreComponentSnapshot = (snapshot) => {
2509
+ addComponentFromSnapshot(snapshot);
2491
2510
  const currentStyle = snapshot.component.getStyle?.() || {};
2511
+ const currentAttributes = snapshot.component.getAttributes?.() || {};
2512
+ const staleAttributes = Object.keys(currentAttributes).filter((key) => !(key in snapshot.attributes));
2492
2513
  snapshot.component.addStyle?.({
2493
2514
  ...Object.fromEntries(Object.keys(currentStyle).map((key) => [key, ""])),
2494
2515
  ...Object.fromEntries(Object.entries(snapshot.style).map(([key, value]) => [key, String(value)]))
2495
2516
  });
2517
+ if (staleAttributes.length > 0) {
2518
+ ;
2519
+ snapshot.component.removeAttributes?.(staleAttributes);
2520
+ }
2496
2521
  snapshot.component.addAttributes?.({ ...snapshot.attributes });
2497
2522
  selectedComponentRef.current = snapshot.component;
2498
2523
  lastSelectedComponentRef.current = snapshot.component;
@@ -2501,16 +2526,33 @@ function GrapesPageEditor({
2501
2526
  lastComponentSnapshotRef.current.set(snapshot.component, snapshot);
2502
2527
  refreshSelectedState(snapshot.component);
2503
2528
  };
2529
+ const restoreCustomHistoryEntry = (entry, target) => {
2530
+ const snapshot = entry[target];
2531
+ const otherSnapshot = target === "before" ? entry.after : entry.before;
2532
+ if (!snapshot) {
2533
+ if (otherSnapshot) {
2534
+ removeComponentFromSnapshot(otherSnapshot);
2535
+ }
2536
+ refreshSelectedState(null);
2537
+ return;
2538
+ }
2539
+ restoreComponentSnapshot(snapshot);
2540
+ };
2504
2541
  const pushCustomHistoryEntry = (before, after) => {
2505
- if (!before || !after || before.component !== after.component) {
2542
+ if (!before && !after) {
2543
+ return;
2544
+ }
2545
+ if (before && after && before.component !== after.component) {
2506
2546
  return;
2507
2547
  }
2508
- if (JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2548
+ if (before && after && JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2509
2549
  return;
2510
2550
  }
2511
2551
  customUndoStackRef.current.push({ after, before });
2512
2552
  customRedoStackRef.current = [];
2513
- lastComponentSnapshotRef.current.set(after.component, after);
2553
+ if (after) {
2554
+ lastComponentSnapshotRef.current.set(after.component, after);
2555
+ }
2514
2556
  if (customUndoStackRef.current.length > 100) {
2515
2557
  customUndoStackRef.current.shift();
2516
2558
  }
@@ -2542,7 +2584,7 @@ function GrapesPageEditor({
2542
2584
  const customEntry = action === "undo" ? customUndoStackRef.current.pop() : customRedoStackRef.current.pop();
2543
2585
  if (customEntry) {
2544
2586
  historyRestoreActiveRef.current = true;
2545
- restoreComponentSnapshot(action === "undo" ? customEntry.before : customEntry.after);
2587
+ restoreCustomHistoryEntry(customEntry, action === "undo" ? "before" : "after");
2546
2588
  if (action === "undo") {
2547
2589
  customRedoStackRef.current.push(customEntry);
2548
2590
  } else {
@@ -2808,6 +2850,21 @@ function GrapesPageEditor({
2808
2850
  }
2809
2851
  );
2810
2852
  });
2853
+ editor.on("component:add", (component) => {
2854
+ if (historyRestoreActiveRef.current) {
2855
+ return;
2856
+ }
2857
+ const typed = component;
2858
+ if (!isOrionBlockComponent(typed)) {
2859
+ return;
2860
+ }
2861
+ window.setTimeout(() => {
2862
+ if (historyRestoreActiveRef.current) {
2863
+ return;
2864
+ }
2865
+ pushCustomHistoryEntry(null, snapshotComponent(typed));
2866
+ }, 0);
2867
+ });
2811
2868
  editor.on("component:selected", (component) => {
2812
2869
  const typed = component;
2813
2870
  const target = getCurrentOrionBlockTarget(typed) || typed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-studios/payload-studio",
3
- "version": "0.6.0-beta.120",
3
+ "version": "0.6.0-beta.121",
4
4
  "description": "Base CMS, builder, and custom admin toolkit for Orion Studios websites",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",