astro-tractstack 2.2.1 → 2.2.3
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.
- package/package.json +1 -1
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +0 -1
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +0 -1
- package/templates/src/components/codehooks/ListContentSetup.tsx +0 -1
- package/templates/src/components/codehooks/ProductCardSetup.tsx +0 -1
- package/templates/src/components/codehooks/ProductGridSetup.tsx +0 -1
- package/templates/src/components/compositor/Compositor.tsx +0 -1
- package/templates/src/components/compositor/Node.tsx +157 -133
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +2 -4
- package/templates/src/components/edit/Header.tsx +2 -6
- package/templates/src/components/edit/context/ContextPaneConfig_slug.tsx +1 -1
- package/templates/src/components/edit/context/ContextPaneConfig_title.tsx +0 -1
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +1 -0
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +8 -12
- package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +9 -6
- package/templates/src/components/edit/pane/AiRestylePaneModal.tsx +7 -69
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +2 -2
- package/templates/src/components/edit/pane/PanePanel_impression.tsx +0 -4
- package/templates/src/components/edit/pane/PanePanel_path.tsx +0 -1
- package/templates/src/components/edit/pane/PanePanel_title.tsx +1 -2
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +1 -4
- package/templates/src/components/edit/pane/steps/AiCreativeDesignStep.tsx +0 -3
- package/templates/src/components/edit/pane/steps/AiRefineDesignStep.tsx +2 -2
- package/templates/src/components/edit/pane/steps/AiStandardDesignStep.tsx +173 -80
- package/templates/src/components/edit/pane/steps/CreativeInjectStep.tsx +0 -5
- package/templates/src/components/edit/pane/steps/DesignLibraryStep.tsx +2 -1
- package/templates/src/components/edit/panels/StyleBreakPanel.tsx +1 -4
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +0 -1
- package/templates/src/components/edit/panels/StyleElementPanel.tsx +1 -1
- package/templates/src/components/edit/panels/StyleElementPanel_remove.tsx +1 -4
- package/templates/src/components/edit/panels/StyleElementPanel_update.tsx +3 -3
- package/templates/src/components/edit/panels/StyleImagePanel.tsx +3 -3
- package/templates/src/components/edit/panels/StyleImagePanel_remove.tsx +1 -4
- package/templates/src/components/edit/panels/StyleImagePanel_update.tsx +3 -4
- package/templates/src/components/edit/panels/StyleLiElementPanel_remove.tsx +1 -4
- package/templates/src/components/edit/panels/StyleLiElementPanel_update.tsx +3 -3
- package/templates/src/components/edit/panels/StyleLinkPanel.tsx +1 -1
- package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +1 -1
- package/templates/src/components/edit/panels/StyleLinkPanel_remove.tsx +1 -1
- package/templates/src/components/edit/panels/StyleLinkPanel_update.tsx +1 -1
- package/templates/src/components/edit/panels/StyleParentPanel.tsx +0 -7
- package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +0 -2
- package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +0 -2
- package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +0 -2
- package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +0 -3
- package/templates/src/components/edit/panels/StyleWidgetPanel_remove.tsx +1 -4
- package/templates/src/components/edit/panels/StyleWidgetPanel_update.tsx +3 -4
- package/templates/src/components/edit/panels/StyleWordCarouselPanel.tsx +0 -2
- package/templates/src/components/edit/state/StylesMemory.tsx +3 -9
- package/templates/src/components/edit/storyfragment/StoryFragmentConfigPanel.tsx +0 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +0 -2
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +0 -2
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +0 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_title.tsx +0 -1
- package/templates/src/components/fields/ArtpackImage.tsx +0 -7
- package/templates/src/components/fields/BackgroundImage.tsx +0 -14
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +0 -5
- package/templates/src/components/fields/ImageUpload.tsx +0 -3
- package/templates/src/pages/[...slug]/edit.astro +0 -1
- package/templates/src/pages/sandbox.astro +0 -1
- package/templates/src/stores/nodes.ts +278 -312
- package/templates/src/stores/nodesHistory.ts +59 -24
- package/templates/src/utils/api/setupHelpers.ts +1 -1
- package/templates/src/utils/compositor/aiPaneParser.ts +57 -0
- package/templates/src/utils/compositor/designLibraryHelper.ts +1 -3
- package/templates/src/utils/compositor/htmlAst.ts +109 -2
- package/templates/src/utils/compositor/nodesHelper.ts +1 -9
- package/templates/src/utils/compositor/savePipeline.ts +1 -4
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { atom, type WritableAtom } from 'nanostores';
|
|
2
|
-
import type { NodesContext } from '@/stores/nodes
|
|
2
|
+
import type { NodesContext } from '@/stores/nodes';
|
|
3
|
+
|
|
4
|
+
export const VERBOSE = false;
|
|
5
|
+
const COALESCE_WINDOW = 16000;
|
|
3
6
|
|
|
4
7
|
export enum PatchOp {
|
|
5
8
|
ADD,
|
|
@@ -19,8 +22,7 @@ export class NodesHistory {
|
|
|
19
22
|
|
|
20
23
|
protected _ctx: NodesContext;
|
|
21
24
|
protected _maxBuffer: number;
|
|
22
|
-
|
|
23
|
-
private _pendingPatch: HistoryPatch | null = null;
|
|
25
|
+
public lastPatchTime: number = 0;
|
|
24
26
|
|
|
25
27
|
constructor(ctx: NodesContext, maxBuffer: number) {
|
|
26
28
|
this._ctx = ctx;
|
|
@@ -38,30 +40,62 @@ export class NodesHistory {
|
|
|
38
40
|
return this.history.get().length > 0 && this.headIndex.get() > 0;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
addPatch(patch: HistoryPatch) {
|
|
42
|
-
|
|
43
|
+
addPatch(patch: HistoryPatch, options?: { merge?: boolean }) {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
const timeDelta = now - this.lastPatchTime;
|
|
46
|
+
const shouldMerge =
|
|
47
|
+
options?.merge !== false &&
|
|
48
|
+
timeDelta < COALESCE_WINDOW &&
|
|
49
|
+
this.headIndex.get() === 0 && // Only merge if we are at the tip of history
|
|
50
|
+
this.history.get().length > 0;
|
|
43
51
|
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if (shouldMerge) {
|
|
53
|
+
if (VERBOSE) {
|
|
54
|
+
console.log(
|
|
55
|
+
`[History] Merging patch (Delta: ${timeDelta}ms < ${COALESCE_WINDOW}ms)`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
47
58
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const currentHistory = [...this.history.get()];
|
|
60
|
+
const previousPatch = currentHistory[0];
|
|
61
|
+
|
|
62
|
+
// Create a composite patch that executes both actions
|
|
63
|
+
const mergedPatch: HistoryPatch = {
|
|
64
|
+
op: PatchOp.REPLACE, // Merged operations are generally treated as complex replacements
|
|
65
|
+
undo: (ctx) => {
|
|
66
|
+
// Reverse order: Undo the new action, then undo the old action
|
|
67
|
+
patch.undo(ctx);
|
|
68
|
+
previousPatch.undo(ctx);
|
|
69
|
+
},
|
|
70
|
+
redo: (ctx) => {
|
|
71
|
+
// Forward order: Redo the old action, then redo the new action
|
|
72
|
+
previousPatch.redo(ctx);
|
|
73
|
+
patch.redo(ctx);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
currentHistory[0] = mergedPatch;
|
|
78
|
+
this.history.set(currentHistory);
|
|
79
|
+
// We do NOT update lastPatchTime on merge. This keeps the window anchored to the start of the "thought".
|
|
80
|
+
} else {
|
|
81
|
+
if (VERBOSE) {
|
|
82
|
+
console.log(`[History] Pushing new patch (Delta: ${timeDelta}ms)`);
|
|
63
83
|
}
|
|
64
|
-
|
|
84
|
+
|
|
85
|
+
// If we are not at the tip (we undid something), verify we clear the future
|
|
86
|
+
while (this.headIndex.get() !== 0) {
|
|
87
|
+
this.history.get().shift();
|
|
88
|
+
this.headIndex.set(this.headIndex.get() - 1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const newHistory = [patch, ...this.history.get()];
|
|
92
|
+
if (newHistory.length > this._maxBuffer) {
|
|
93
|
+
newHistory.pop();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.history.set(newHistory);
|
|
97
|
+
this.lastPatchTime = now;
|
|
98
|
+
}
|
|
65
99
|
}
|
|
66
100
|
|
|
67
101
|
undo() {
|
|
@@ -81,5 +115,6 @@ export class NodesHistory {
|
|
|
81
115
|
clearHistory() {
|
|
82
116
|
this.history.set([]);
|
|
83
117
|
this.headIndex.set(0);
|
|
118
|
+
this.lastPatchTime = 0;
|
|
84
119
|
}
|
|
85
120
|
}
|
|
@@ -164,7 +164,7 @@ function forceMarkAllDirty(ctx: any) {
|
|
|
164
164
|
if (VERBOSE)
|
|
165
165
|
console.log('[forceMarkAllDirty] Flagging all nodes for SaveModal...');
|
|
166
166
|
const allNodes = Array.from(ctx.allNodes.get().values());
|
|
167
|
-
const dirtyUpdates = allNodes.map((n: any) => ({ ...n
|
|
167
|
+
const dirtyUpdates = allNodes.map((n: any) => ({ ...n }));
|
|
168
168
|
ctx.modifyNodes(dirtyUpdates);
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -747,3 +747,60 @@ export const parseAiPane = (
|
|
|
747
747
|
// Fallback for invalid input
|
|
748
748
|
throw new Error('Invalid input for parseAiPane');
|
|
749
749
|
};
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Generates a default design shell when AI styling is disabled.
|
|
753
|
+
* Provides a clean, white-label structure compatible with the parser.
|
|
754
|
+
*/
|
|
755
|
+
export function createDefaultShell(layout: 'standard' | 'grid'): ShellJson {
|
|
756
|
+
const baseDefaults: LLMDefaultClasses = {
|
|
757
|
+
h2: {
|
|
758
|
+
mobile: 'text-3xl font-bold tracking-tight text-gray-900',
|
|
759
|
+
tablet: 'text-4xl',
|
|
760
|
+
},
|
|
761
|
+
h3: {
|
|
762
|
+
mobile: 'text-2xl font-bold tracking-tight text-gray-900',
|
|
763
|
+
},
|
|
764
|
+
p: {
|
|
765
|
+
mobile: 'mt-6 text-lg leading-8 text-gray-600',
|
|
766
|
+
},
|
|
767
|
+
ul: {
|
|
768
|
+
mobile: 'mt-6 list-disc list-outside ml-6 text-gray-600',
|
|
769
|
+
},
|
|
770
|
+
li: {
|
|
771
|
+
mobile: 'mb-2',
|
|
772
|
+
},
|
|
773
|
+
a: {
|
|
774
|
+
mobile: 'text-indigo-600 hover:text-indigo-500 font-semibold',
|
|
775
|
+
},
|
|
776
|
+
button: {
|
|
777
|
+
mobile:
|
|
778
|
+
'rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
|
|
779
|
+
},
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
if (layout === 'grid') {
|
|
783
|
+
return {
|
|
784
|
+
bgColour: '#ffffff',
|
|
785
|
+
parentClasses: [
|
|
786
|
+
{ mobile: 'mx-auto max-w-7xl' },
|
|
787
|
+
{ mobile: 'px-6 py-24', tablet: 'px-8 py-32' },
|
|
788
|
+
],
|
|
789
|
+
defaultClasses: baseDefaults,
|
|
790
|
+
columns: [
|
|
791
|
+
{ gridClasses: { mobile: 'flex flex-col gap-y-4' } }, // Left Column
|
|
792
|
+
{ gridClasses: { mobile: 'flex flex-col gap-y-4' } }, // Right Column
|
|
793
|
+
],
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Standard Layout
|
|
798
|
+
return {
|
|
799
|
+
bgColour: '#ffffff',
|
|
800
|
+
parentClasses: [
|
|
801
|
+
{ mobile: 'mx-auto max-w-3xl text-base leading-7' },
|
|
802
|
+
{ mobile: 'px-6 py-24', tablet: 'px-8 py-32' },
|
|
803
|
+
],
|
|
804
|
+
defaultClasses: baseDefaults,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
@@ -500,8 +500,7 @@ function convertLivePaneToStoragePane(
|
|
|
500
500
|
: [],
|
|
501
501
|
};
|
|
502
502
|
} else if (gridLayoutNode) {
|
|
503
|
-
const { id, parentId,
|
|
504
|
-
gridLayoutNode;
|
|
503
|
+
const { id, parentId, parentCss, gridCss, ...restOfGrid } = gridLayoutNode;
|
|
505
504
|
storageGridLayout = {
|
|
506
505
|
...restOfGrid,
|
|
507
506
|
nodes: ctx
|
|
@@ -515,7 +514,6 @@ function convertLivePaneToStoragePane(
|
|
|
515
514
|
const {
|
|
516
515
|
id,
|
|
517
516
|
parentId,
|
|
518
|
-
isChanged,
|
|
519
517
|
markdownId,
|
|
520
518
|
parentCss,
|
|
521
519
|
gridCss,
|
|
@@ -562,10 +562,13 @@ export async function regenerateCreativePane(
|
|
|
562
562
|
} else if (updates.image === null) {
|
|
563
563
|
delete targetNode.attrs['data-image'];
|
|
564
564
|
}
|
|
565
|
-
|
|
566
565
|
if (updates.src && updates.tagName === 'img') {
|
|
567
566
|
targetNode.attrs.src = updates.src;
|
|
568
|
-
if (updates.srcSet)
|
|
567
|
+
if (updates.srcSet) {
|
|
568
|
+
targetNode.attrs.srcset = updates.srcSet;
|
|
569
|
+
} else {
|
|
570
|
+
delete targetNode.attrs.srcset;
|
|
571
|
+
}
|
|
569
572
|
}
|
|
570
573
|
if (updates.alt) {
|
|
571
574
|
targetNode.attrs.alt = updates.alt;
|
|
@@ -702,3 +705,107 @@ export function extractFileIdsFromAst(payload: CreativePanePayload): string[] {
|
|
|
702
705
|
}
|
|
703
706
|
return results;
|
|
704
707
|
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Simple Markdown to HTML converter.
|
|
711
|
+
* Handles:
|
|
712
|
+
* - Headers (## through ######)
|
|
713
|
+
* - Unordered lists (- item)
|
|
714
|
+
* - Bold (**text**)
|
|
715
|
+
* - Italic (*text*)
|
|
716
|
+
* - Links ([text](url))
|
|
717
|
+
* - Paragraphs (everything else)
|
|
718
|
+
*/
|
|
719
|
+
export function markdownToHtml(markdown: string): string {
|
|
720
|
+
const lines = markdown.split('\n');
|
|
721
|
+
let html = '';
|
|
722
|
+
let inList = false;
|
|
723
|
+
|
|
724
|
+
const parseInline = (text: string): string => {
|
|
725
|
+
return (
|
|
726
|
+
text
|
|
727
|
+
// Bold: **text**
|
|
728
|
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
729
|
+
// Italic: *text*
|
|
730
|
+
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
|
731
|
+
// Link: [text](url)
|
|
732
|
+
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
|
|
733
|
+
);
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
for (const line of lines) {
|
|
737
|
+
const trimmed = line.trim();
|
|
738
|
+
|
|
739
|
+
// Skip empty lines, but close list if open
|
|
740
|
+
if (!trimmed) {
|
|
741
|
+
if (inList) {
|
|
742
|
+
html += '</ul>';
|
|
743
|
+
inList = false;
|
|
744
|
+
}
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// Headers (## to ######) - Note: Ignoring # (h1) as per standard rules
|
|
749
|
+
const headerMatch = trimmed.match(/^(#{2,6})\s+(.*)$/);
|
|
750
|
+
if (headerMatch) {
|
|
751
|
+
if (inList) {
|
|
752
|
+
html += '</ul>';
|
|
753
|
+
inList = false;
|
|
754
|
+
}
|
|
755
|
+
const level = headerMatch[1].length;
|
|
756
|
+
const content = parseInline(headerMatch[2]);
|
|
757
|
+
html += `<h${level}>${content}</h${level}>`;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// Unordered Lists (- item)
|
|
762
|
+
const listMatch = trimmed.match(/^-\s+(.*)$/);
|
|
763
|
+
if (listMatch) {
|
|
764
|
+
if (!inList) {
|
|
765
|
+
html += '<ul>';
|
|
766
|
+
inList = true;
|
|
767
|
+
}
|
|
768
|
+
const content = parseInline(listMatch[1]);
|
|
769
|
+
html += `<li>${content}</li>`;
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// Paragraphs (default block)
|
|
774
|
+
if (inList) {
|
|
775
|
+
html += '</ul>';
|
|
776
|
+
inList = false;
|
|
777
|
+
}
|
|
778
|
+
html += `<p>${parseInline(trimmed)}</p>`;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// Close any remaining open list
|
|
782
|
+
if (inList) {
|
|
783
|
+
html += '</ul>';
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return html;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Sanitizes HTML for AI processing or other non-editor contexts.
|
|
791
|
+
* Strips editor-specific guards, metadata, and heavy base64 data.
|
|
792
|
+
*/
|
|
793
|
+
export function cleanHtml(html: string): string {
|
|
794
|
+
if (!html) return '';
|
|
795
|
+
|
|
796
|
+
return (
|
|
797
|
+
html
|
|
798
|
+
// 1. Revert Base64 images to static placeholder to save tokens and avoid confusion
|
|
799
|
+
.replace(/src="data:[^"]*"/g, 'src="/static.jpg"')
|
|
800
|
+
// 2. Remove Content Editable attribute
|
|
801
|
+
.replace(/contenteditable="true"/g, '')
|
|
802
|
+
.replace(/contenteditable="false"/g, '')
|
|
803
|
+
// 3. Remove Editor Interaction Guards
|
|
804
|
+
.replace(/onclick="return false;"/g, '')
|
|
805
|
+
.replace(/style="pointer-events: none;"/g, '')
|
|
806
|
+
// 4. Remove Internal Upload Metadata
|
|
807
|
+
.replace(/data-file-id="[^"]*"/g, '')
|
|
808
|
+
// 5. Clean up resulting double spaces
|
|
809
|
+
.replace(/\s{2,}/g, ' ')
|
|
810
|
+
);
|
|
811
|
+
}
|
|
@@ -304,7 +304,6 @@ export function createEmptyStorykeep(id: string) {
|
|
|
304
304
|
nodeType: 'StoryFragment',
|
|
305
305
|
tractStackId: 'temp',
|
|
306
306
|
parentId: null,
|
|
307
|
-
isChanged: false,
|
|
308
307
|
paneIds: [],
|
|
309
308
|
changed: undefined,
|
|
310
309
|
slug: 'temp',
|
|
@@ -549,7 +548,6 @@ export function revertFromGrid(gridLayoutId: string) {
|
|
|
549
548
|
markdownNodeToKeep.parentId = paneNode.id;
|
|
550
549
|
markdownNodeToKeep.parentClasses = gridLayoutNode.parentClasses || [];
|
|
551
550
|
markdownNodeToKeep.defaultClasses = gridLayoutNode.defaultClasses || {};
|
|
552
|
-
markdownNodeToKeep.isChanged = true;
|
|
553
551
|
newAllNodes.set(markdownNodeToKeepId, markdownNodeToKeep);
|
|
554
552
|
|
|
555
553
|
const paneChildren = [...(newParentNodes.get(paneNode.id) || [])];
|
|
@@ -567,7 +565,6 @@ export function revertFromGrid(gridLayoutId: string) {
|
|
|
567
565
|
}
|
|
568
566
|
|
|
569
567
|
const updatedPaneNode = cloneDeep(paneNode);
|
|
570
|
-
updatedPaneNode.isChanged = true;
|
|
571
568
|
newAllNodes.set(paneNode.id, updatedPaneNode);
|
|
572
569
|
|
|
573
570
|
ctx.allNodes.set(newAllNodes);
|
|
@@ -622,7 +619,6 @@ export function convertToGrid(markdownNodeId: string) {
|
|
|
622
619
|
parentClasses: markdownNode.parentClasses || [],
|
|
623
620
|
defaultClasses: markdownNode.defaultClasses || {},
|
|
624
621
|
gridColumns: { mobile: 1, tablet: 2, desktop: 2 },
|
|
625
|
-
isChanged: true,
|
|
626
622
|
};
|
|
627
623
|
|
|
628
624
|
const updatedMarkdownNode = cloneDeep(markdownNode);
|
|
@@ -630,7 +626,6 @@ export function convertToGrid(markdownNodeId: string) {
|
|
|
630
626
|
updatedMarkdownNode.parentClasses = [];
|
|
631
627
|
updatedMarkdownNode.parentCss = [];
|
|
632
628
|
updatedMarkdownNode.defaultClasses = {};
|
|
633
|
-
updatedMarkdownNode.isChanged = true;
|
|
634
629
|
|
|
635
630
|
// Create a new, truly empty MarkdownNode for the second column.
|
|
636
631
|
const newColumnNodeId = ulid();
|
|
@@ -642,12 +637,11 @@ export function convertToGrid(markdownNodeId: string) {
|
|
|
642
637
|
markdownId: ulid(),
|
|
643
638
|
defaultClasses: {},
|
|
644
639
|
parentClasses: [],
|
|
645
|
-
isChanged: true,
|
|
646
640
|
};
|
|
647
641
|
|
|
648
642
|
newAllNodes.set(gridLayoutId, newGridLayoutNode);
|
|
649
643
|
newAllNodes.set(markdownNodeId, updatedMarkdownNode);
|
|
650
|
-
newAllNodes.set(paneNode.id, { ...cloneDeep(paneNode)
|
|
644
|
+
newAllNodes.set(paneNode.id, { ...cloneDeep(paneNode) });
|
|
651
645
|
newAllNodes.set(newColumnNodeId, newColumnNode);
|
|
652
646
|
|
|
653
647
|
const paneChildren = [...(newParentNodes.get(paneNode.id) || [])];
|
|
@@ -703,7 +697,6 @@ export function addColumn(gridLayoutId: string) {
|
|
|
703
697
|
defaultClasses: {},
|
|
704
698
|
parentClasses: [],
|
|
705
699
|
gridClasses: { mobile: {}, tablet: {}, desktop: {} },
|
|
706
|
-
isChanged: true,
|
|
707
700
|
};
|
|
708
701
|
|
|
709
702
|
newAllNodes.set(newMarkdownNodeId, newColumnNode);
|
|
@@ -714,7 +707,6 @@ export function addColumn(gridLayoutId: string) {
|
|
|
714
707
|
newParentNodes.set(newMarkdownNodeId, []); // Set children to an empty array
|
|
715
708
|
|
|
716
709
|
const updatedGridLayoutNode = cloneDeep(gridLayoutNode);
|
|
717
|
-
updatedGridLayoutNode.isChanged = true;
|
|
718
710
|
newAllNodes.set(gridLayoutId, updatedGridLayoutNode);
|
|
719
711
|
|
|
720
712
|
ctx.allNodes.set(newAllNodes);
|
|
@@ -211,7 +211,6 @@ export async function executeSavePipeline(
|
|
|
211
211
|
updatedNode.fileId = result.fileId;
|
|
212
212
|
updatedNode.src = result.src;
|
|
213
213
|
if (result.srcSet) updatedNode.srcSet = result.srcSet;
|
|
214
|
-
updatedNode.isChanged = true;
|
|
215
214
|
ctx.modifyNodes([updatedNode]);
|
|
216
215
|
|
|
217
216
|
const localRef = fileNode as PendingFileNode;
|
|
@@ -286,9 +285,7 @@ export async function executeSavePipeline(
|
|
|
286
285
|
}
|
|
287
286
|
);
|
|
288
287
|
|
|
289
|
-
ctx.modifyNodes([
|
|
290
|
-
{ ...pane, htmlAst: cleanAst, isChanged: true } as PaneNode,
|
|
291
|
-
]);
|
|
288
|
+
ctx.modifyNodes([{ ...pane, htmlAst: cleanAst } as PaneNode]);
|
|
292
289
|
logDebug(`Creative Pane ${pane.id} assets processed and node updated.`);
|
|
293
290
|
} catch (err) {
|
|
294
291
|
console.error('Creative Pane Asset Upload Error:', err);
|