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

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.
@@ -823,10 +823,16 @@ var updateJsonListAttribute = ({
823
823
  [listAttr]: JSON.stringify(list)
824
824
  });
825
825
  };
826
- var snapshotModel = (model) => ({
827
- attributes: { ...model.getAttributes?.() || {} },
828
- style: { ...model.getStyle?.() || {} }
829
- });
826
+ var snapshotModel = (model, emptyListAttr) => {
827
+ const attributes = { ...model.getAttributes?.() || {} };
828
+ if (emptyListAttr && !attributes[emptyListAttr]) {
829
+ attributes[emptyListAttr] = "[]";
830
+ }
831
+ return {
832
+ attributes,
833
+ style: { ...model.getStyle?.() || {} }
834
+ };
835
+ };
830
836
  var pushModelHistory = ({
831
837
  after,
832
838
  before,
@@ -956,10 +962,10 @@ var bindEditablePreview = (view, editor) => {
956
962
  if (!listAttr) {
957
963
  return;
958
964
  }
959
- const before = snapshotModel(view.model);
965
+ const before = snapshotModel(view.model, listAttr);
960
966
  const runListMutation = (callback) => {
961
967
  withoutUndoTracking(editor, callback);
962
- const after = snapshotModel(view.model);
968
+ const after = snapshotModel(view.model, listAttr);
963
969
  if (JSON.stringify(before) !== JSON.stringify(after)) {
964
970
  pushModelHistory({
965
971
  after,
@@ -2115,6 +2121,7 @@ function GrapesPageEditor({
2115
2121
  }
2116
2122
  return null;
2117
2123
  };
2124
+ const isOrionBlockComponent = (component) => Boolean(component?.getAttributes?.()?.["data-orion-component"]) || Object.keys(parseOrionBlockAttribute(component?.getAttributes?.()?.["data-orion-block"])).length > 0;
2118
2125
  const findSelectedCanvasOrionBlock = () => {
2119
2126
  const editor = editorRef.current;
2120
2127
  const wrapper = editor?.DomComponents?.getWrapper?.() || null;
@@ -2597,9 +2604,14 @@ function GrapesPageEditor({
2597
2604
  if (!component) {
2598
2605
  return null;
2599
2606
  }
2607
+ const parent = component.parent?.();
2608
+ const collection = parent?.components?.();
2609
+ const index = typeof collection?.indexOf === "function" ? collection.indexOf(component) : void 0;
2600
2610
  return {
2601
2611
  attributes: { ...component.getAttributes?.() || {} },
2602
2612
  component,
2613
+ index,
2614
+ parent,
2603
2615
  style: { ...component.getStyle?.() || {} }
2604
2616
  };
2605
2617
  };
@@ -2611,12 +2623,31 @@ function GrapesPageEditor({
2611
2623
  return snapshot;
2612
2624
  };
2613
2625
  const getPreviousComponentSnapshot = (component) => component ? lastComponentSnapshotRef.current.get(component) || snapshotComponent(component) : null;
2626
+ const isComponentAttached = (component) => Boolean(component.parent?.());
2627
+ const addComponentFromSnapshot = (snapshot) => {
2628
+ const parent = snapshot.parent;
2629
+ if (isComponentAttached(snapshot.component) || !parent?.components) {
2630
+ return;
2631
+ }
2632
+ parent.components?.().add?.(snapshot.component, { at: snapshot.index });
2633
+ };
2634
+ const removeComponentFromSnapshot = (snapshot) => {
2635
+ ;
2636
+ snapshot.component.remove?.();
2637
+ };
2614
2638
  const restoreComponentSnapshot = (snapshot) => {
2639
+ addComponentFromSnapshot(snapshot);
2615
2640
  const currentStyle = snapshot.component.getStyle?.() || {};
2641
+ const currentAttributes = snapshot.component.getAttributes?.() || {};
2642
+ const staleAttributes = Object.keys(currentAttributes).filter((key) => !(key in snapshot.attributes));
2616
2643
  snapshot.component.addStyle?.({
2617
2644
  ...Object.fromEntries(Object.keys(currentStyle).map((key) => [key, ""])),
2618
2645
  ...Object.fromEntries(Object.entries(snapshot.style).map(([key, value]) => [key, String(value)]))
2619
2646
  });
2647
+ if (staleAttributes.length > 0) {
2648
+ ;
2649
+ snapshot.component.removeAttributes?.(staleAttributes);
2650
+ }
2620
2651
  snapshot.component.addAttributes?.({ ...snapshot.attributes });
2621
2652
  selectedComponentRef.current = snapshot.component;
2622
2653
  lastSelectedComponentRef.current = snapshot.component;
@@ -2625,16 +2656,33 @@ function GrapesPageEditor({
2625
2656
  lastComponentSnapshotRef.current.set(snapshot.component, snapshot);
2626
2657
  refreshSelectedState(snapshot.component);
2627
2658
  };
2659
+ const restoreCustomHistoryEntry = (entry, target) => {
2660
+ const snapshot = entry[target];
2661
+ const otherSnapshot = target === "before" ? entry.after : entry.before;
2662
+ if (!snapshot) {
2663
+ if (otherSnapshot) {
2664
+ removeComponentFromSnapshot(otherSnapshot);
2665
+ }
2666
+ refreshSelectedState(null);
2667
+ return;
2668
+ }
2669
+ restoreComponentSnapshot(snapshot);
2670
+ };
2628
2671
  const pushCustomHistoryEntry = (before, after) => {
2629
- if (!before || !after || before.component !== after.component) {
2672
+ if (!before && !after) {
2630
2673
  return;
2631
2674
  }
2632
- if (JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2675
+ if (before && after && before.component !== after.component) {
2676
+ return;
2677
+ }
2678
+ if (before && after && JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2633
2679
  return;
2634
2680
  }
2635
2681
  customUndoStackRef.current.push({ after, before });
2636
2682
  customRedoStackRef.current = [];
2637
- lastComponentSnapshotRef.current.set(after.component, after);
2683
+ if (after) {
2684
+ lastComponentSnapshotRef.current.set(after.component, after);
2685
+ }
2638
2686
  if (customUndoStackRef.current.length > 100) {
2639
2687
  customUndoStackRef.current.shift();
2640
2688
  }
@@ -2666,7 +2714,7 @@ function GrapesPageEditor({
2666
2714
  const customEntry = action === "undo" ? customUndoStackRef.current.pop() : customRedoStackRef.current.pop();
2667
2715
  if (customEntry) {
2668
2716
  historyRestoreActiveRef.current = true;
2669
- restoreComponentSnapshot(action === "undo" ? customEntry.before : customEntry.after);
2717
+ restoreCustomHistoryEntry(customEntry, action === "undo" ? "before" : "after");
2670
2718
  if (action === "undo") {
2671
2719
  customRedoStackRef.current.push(customEntry);
2672
2720
  } else {
@@ -2932,6 +2980,21 @@ function GrapesPageEditor({
2932
2980
  }
2933
2981
  );
2934
2982
  });
2983
+ editor.on("component:add", (component) => {
2984
+ if (historyRestoreActiveRef.current) {
2985
+ return;
2986
+ }
2987
+ const typed = component;
2988
+ if (!isOrionBlockComponent(typed)) {
2989
+ return;
2990
+ }
2991
+ window.setTimeout(() => {
2992
+ if (historyRestoreActiveRef.current) {
2993
+ return;
2994
+ }
2995
+ pushCustomHistoryEntry(null, snapshotComponent(typed));
2996
+ }, 0);
2997
+ });
2935
2998
  editor.on("component:selected", (component) => {
2936
2999
  const typed = component;
2937
3000
  const target = getCurrentOrionBlockTarget(typed) || typed;
@@ -699,10 +699,16 @@ var updateJsonListAttribute = ({
699
699
  [listAttr]: JSON.stringify(list)
700
700
  });
701
701
  };
702
- var snapshotModel = (model) => ({
703
- attributes: { ...model.getAttributes?.() || {} },
704
- style: { ...model.getStyle?.() || {} }
705
- });
702
+ var snapshotModel = (model, emptyListAttr) => {
703
+ const attributes = { ...model.getAttributes?.() || {} };
704
+ if (emptyListAttr && !attributes[emptyListAttr]) {
705
+ attributes[emptyListAttr] = "[]";
706
+ }
707
+ return {
708
+ attributes,
709
+ style: { ...model.getStyle?.() || {} }
710
+ };
711
+ };
706
712
  var pushModelHistory = ({
707
713
  after,
708
714
  before,
@@ -832,10 +838,10 @@ var bindEditablePreview = (view, editor) => {
832
838
  if (!listAttr) {
833
839
  return;
834
840
  }
835
- const before = snapshotModel(view.model);
841
+ const before = snapshotModel(view.model, listAttr);
836
842
  const runListMutation = (callback) => {
837
843
  withoutUndoTracking(editor, callback);
838
- const after = snapshotModel(view.model);
844
+ const after = snapshotModel(view.model, listAttr);
839
845
  if (JSON.stringify(before) !== JSON.stringify(after)) {
840
846
  pushModelHistory({
841
847
  after,
@@ -1991,6 +1997,7 @@ function GrapesPageEditor({
1991
1997
  }
1992
1998
  return null;
1993
1999
  };
2000
+ const isOrionBlockComponent = (component) => Boolean(component?.getAttributes?.()?.["data-orion-component"]) || Object.keys(parseOrionBlockAttribute(component?.getAttributes?.()?.["data-orion-block"])).length > 0;
1994
2001
  const findSelectedCanvasOrionBlock = () => {
1995
2002
  const editor = editorRef.current;
1996
2003
  const wrapper = editor?.DomComponents?.getWrapper?.() || null;
@@ -2473,9 +2480,14 @@ function GrapesPageEditor({
2473
2480
  if (!component) {
2474
2481
  return null;
2475
2482
  }
2483
+ const parent = component.parent?.();
2484
+ const collection = parent?.components?.();
2485
+ const index = typeof collection?.indexOf === "function" ? collection.indexOf(component) : void 0;
2476
2486
  return {
2477
2487
  attributes: { ...component.getAttributes?.() || {} },
2478
2488
  component,
2489
+ index,
2490
+ parent,
2479
2491
  style: { ...component.getStyle?.() || {} }
2480
2492
  };
2481
2493
  };
@@ -2487,12 +2499,31 @@ function GrapesPageEditor({
2487
2499
  return snapshot;
2488
2500
  };
2489
2501
  const getPreviousComponentSnapshot = (component) => component ? lastComponentSnapshotRef.current.get(component) || snapshotComponent(component) : null;
2502
+ const isComponentAttached = (component) => Boolean(component.parent?.());
2503
+ const addComponentFromSnapshot = (snapshot) => {
2504
+ const parent = snapshot.parent;
2505
+ if (isComponentAttached(snapshot.component) || !parent?.components) {
2506
+ return;
2507
+ }
2508
+ parent.components?.().add?.(snapshot.component, { at: snapshot.index });
2509
+ };
2510
+ const removeComponentFromSnapshot = (snapshot) => {
2511
+ ;
2512
+ snapshot.component.remove?.();
2513
+ };
2490
2514
  const restoreComponentSnapshot = (snapshot) => {
2515
+ addComponentFromSnapshot(snapshot);
2491
2516
  const currentStyle = snapshot.component.getStyle?.() || {};
2517
+ const currentAttributes = snapshot.component.getAttributes?.() || {};
2518
+ const staleAttributes = Object.keys(currentAttributes).filter((key) => !(key in snapshot.attributes));
2492
2519
  snapshot.component.addStyle?.({
2493
2520
  ...Object.fromEntries(Object.keys(currentStyle).map((key) => [key, ""])),
2494
2521
  ...Object.fromEntries(Object.entries(snapshot.style).map(([key, value]) => [key, String(value)]))
2495
2522
  });
2523
+ if (staleAttributes.length > 0) {
2524
+ ;
2525
+ snapshot.component.removeAttributes?.(staleAttributes);
2526
+ }
2496
2527
  snapshot.component.addAttributes?.({ ...snapshot.attributes });
2497
2528
  selectedComponentRef.current = snapshot.component;
2498
2529
  lastSelectedComponentRef.current = snapshot.component;
@@ -2501,16 +2532,33 @@ function GrapesPageEditor({
2501
2532
  lastComponentSnapshotRef.current.set(snapshot.component, snapshot);
2502
2533
  refreshSelectedState(snapshot.component);
2503
2534
  };
2535
+ const restoreCustomHistoryEntry = (entry, target) => {
2536
+ const snapshot = entry[target];
2537
+ const otherSnapshot = target === "before" ? entry.after : entry.before;
2538
+ if (!snapshot) {
2539
+ if (otherSnapshot) {
2540
+ removeComponentFromSnapshot(otherSnapshot);
2541
+ }
2542
+ refreshSelectedState(null);
2543
+ return;
2544
+ }
2545
+ restoreComponentSnapshot(snapshot);
2546
+ };
2504
2547
  const pushCustomHistoryEntry = (before, after) => {
2505
- if (!before || !after || before.component !== after.component) {
2548
+ if (!before && !after) {
2506
2549
  return;
2507
2550
  }
2508
- if (JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2551
+ if (before && after && before.component !== after.component) {
2552
+ return;
2553
+ }
2554
+ if (before && after && JSON.stringify(before.style) === JSON.stringify(after.style) && JSON.stringify(before.attributes) === JSON.stringify(after.attributes)) {
2509
2555
  return;
2510
2556
  }
2511
2557
  customUndoStackRef.current.push({ after, before });
2512
2558
  customRedoStackRef.current = [];
2513
- lastComponentSnapshotRef.current.set(after.component, after);
2559
+ if (after) {
2560
+ lastComponentSnapshotRef.current.set(after.component, after);
2561
+ }
2514
2562
  if (customUndoStackRef.current.length > 100) {
2515
2563
  customUndoStackRef.current.shift();
2516
2564
  }
@@ -2542,7 +2590,7 @@ function GrapesPageEditor({
2542
2590
  const customEntry = action === "undo" ? customUndoStackRef.current.pop() : customRedoStackRef.current.pop();
2543
2591
  if (customEntry) {
2544
2592
  historyRestoreActiveRef.current = true;
2545
- restoreComponentSnapshot(action === "undo" ? customEntry.before : customEntry.after);
2593
+ restoreCustomHistoryEntry(customEntry, action === "undo" ? "before" : "after");
2546
2594
  if (action === "undo") {
2547
2595
  customRedoStackRef.current.push(customEntry);
2548
2596
  } else {
@@ -2808,6 +2856,21 @@ function GrapesPageEditor({
2808
2856
  }
2809
2857
  );
2810
2858
  });
2859
+ editor.on("component:add", (component) => {
2860
+ if (historyRestoreActiveRef.current) {
2861
+ return;
2862
+ }
2863
+ const typed = component;
2864
+ if (!isOrionBlockComponent(typed)) {
2865
+ return;
2866
+ }
2867
+ window.setTimeout(() => {
2868
+ if (historyRestoreActiveRef.current) {
2869
+ return;
2870
+ }
2871
+ pushCustomHistoryEntry(null, snapshotComponent(typed));
2872
+ }, 0);
2873
+ });
2811
2874
  editor.on("component:selected", (component) => {
2812
2875
  const typed = component;
2813
2876
  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.122",
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",