astro-tractstack 2.0.13 → 2.0.15
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/dist/index.js +40 -0
- package/package.json +1 -1
- package/templates/src/client/view.js +5 -0
- package/templates/src/components/compositor/Compositor.tsx +3 -2
- package/templates/src/components/compositor/Node.tsx +25 -8
- package/templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx +105 -0
- package/templates/src/components/edit/ToolMode.tsx +7 -0
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +459 -561
- package/templates/src/components/edit/pane/AiPaneGenerator.tsx +19 -82
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +573 -0
- package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +140 -0
- package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +105 -0
- package/templates/src/components/edit/pane/steps/DesignLibraryStep.tsx +395 -0
- package/templates/src/components/edit/state/SaveToLibraryModal.tsx +205 -0
- package/templates/src/constants/prompts.json +3 -1
- package/templates/src/stores/selection.ts +4 -0
- package/templates/src/types/compositorTypes.ts +51 -1
- package/templates/src/types/tractstack.ts +36 -31
- package/templates/src/utils/aai/getTitleSlug.ts +1 -1
- package/templates/src/utils/api/brandConfig.ts +8 -2
- package/templates/src/utils/api/brandHelpers.ts +4 -0
- package/templates/src/utils/compositor/aiPaneParser.ts +32 -84
- package/templates/src/utils/compositor/designLibraryHelper.ts +416 -0
- package/templates/src/utils/compositor/processMarkdown.ts +1 -1
- package/utils/inject-files.ts +40 -0
- package/templates/src/components/edit/pane/PageGen.tsx +0 -485
- package/templates/src/components/edit/pane/PageGenSelector.tsx +0 -245
- package/templates/src/components/edit/pane/PageGenSpecial.tsx +0 -339
package/dist/index.js
CHANGED
|
@@ -126,6 +126,12 @@ async function w(t, e, c) {
|
|
|
126
126
|
),
|
|
127
127
|
dest: "src/components/compositor/nodes/Pane_eraser.tsx"
|
|
128
128
|
},
|
|
129
|
+
{
|
|
130
|
+
src: t(
|
|
131
|
+
"../templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx"
|
|
132
|
+
),
|
|
133
|
+
dest: "src/components/compositor/nodes/Pane_DesignLibrary.tsx"
|
|
134
|
+
},
|
|
129
135
|
{
|
|
130
136
|
src: t(
|
|
131
137
|
"../templates/src/components/compositor/nodes/Pane_layout.tsx"
|
|
@@ -428,6 +434,12 @@ async function w(t, e, c) {
|
|
|
428
434
|
),
|
|
429
435
|
dest: "src/components/edit/pane/AddPanePanel_codehook.tsx"
|
|
430
436
|
},
|
|
437
|
+
{
|
|
438
|
+
src: t(
|
|
439
|
+
"../templates/src/components/edit/pane/RestylePaneModal.tsx"
|
|
440
|
+
),
|
|
441
|
+
dest: "src/components/edit/pane/RestylePaneModal.tsx"
|
|
442
|
+
},
|
|
431
443
|
{
|
|
432
444
|
src: t("../templates/src/components/edit/pane/AiPaneGenerator.tsx"),
|
|
433
445
|
dest: "src/components/edit/pane/AiPaneGenerator.tsx"
|
|
@@ -436,6 +448,24 @@ async function w(t, e, c) {
|
|
|
436
448
|
src: t("../templates/src/components/edit/pane/AiPanePreview.tsx"),
|
|
437
449
|
dest: "src/components/edit/pane/AiPanePreview.tsx"
|
|
438
450
|
},
|
|
451
|
+
{
|
|
452
|
+
src: t(
|
|
453
|
+
"../templates/src/components/edit/pane/steps/CopyInputStep.tsx"
|
|
454
|
+
),
|
|
455
|
+
dest: "src/components/edit/pane/steps/CopyInputStep.tsx"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
src: t(
|
|
459
|
+
"../templates/src/components/edit/pane/steps/DesignLibraryStep.tsx"
|
|
460
|
+
),
|
|
461
|
+
dest: "src/components/edit/pane/steps/DesignLibraryStep.tsx"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
src: t(
|
|
465
|
+
"../templates/src/components/edit/pane/steps/AiDesignStep.tsx"
|
|
466
|
+
),
|
|
467
|
+
dest: "src/components/edit/pane/steps/AiDesignStep.tsx"
|
|
468
|
+
},
|
|
439
469
|
{
|
|
440
470
|
src: t(
|
|
441
471
|
"../templates/src/components/edit/pane/AddPanePanel_newCustomCopy.tsx"
|
|
@@ -624,6 +654,10 @@ async function w(t, e, c) {
|
|
|
624
654
|
src: t("../templates/src/utils/compositor/typeGuards.ts"),
|
|
625
655
|
dest: "src/utils/compositor/typeGuards.ts"
|
|
626
656
|
},
|
|
657
|
+
{
|
|
658
|
+
src: t("../templates/src/utils/compositor/designLibraryHelper.ts"),
|
|
659
|
+
dest: "src/utils/compositor/designLibraryHelper.ts"
|
|
660
|
+
},
|
|
627
661
|
{
|
|
628
662
|
src: t("../templates/src/utils/compositor/domHelpers.ts"),
|
|
629
663
|
dest: "src/utils/compositor/domHelpers.ts"
|
|
@@ -1345,6 +1379,12 @@ async function w(t, e, c) {
|
|
|
1345
1379
|
src: t("../templates/src/components/edit/state/SaveModal.tsx"),
|
|
1346
1380
|
dest: "src/components/edit/state/SaveModal.tsx"
|
|
1347
1381
|
},
|
|
1382
|
+
{
|
|
1383
|
+
src: t(
|
|
1384
|
+
"../templates/src/components/edit/state/SaveToLibraryModal.tsx"
|
|
1385
|
+
),
|
|
1386
|
+
dest: "src/components/edit/state/SaveToLibraryModal.tsx"
|
|
1387
|
+
},
|
|
1348
1388
|
{
|
|
1349
1389
|
src: t("../templates/src/components/edit/state/StylesMemory.tsx"),
|
|
1350
1390
|
dest: "src/components/edit/state/StylesMemory.tsx"
|
package/package.json
CHANGED
|
@@ -42,6 +42,11 @@ async function sendStateUpdate(data) {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
const config = window.TractStackApp.getConfig();
|
|
45
|
+
|
|
46
|
+
if (!config.sessionId || !config.storyfragmentId) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
const url = `${config.backendUrl}/api/v1/state`;
|
|
46
51
|
const body = { paneId: '', duration: 0, ...data };
|
|
47
52
|
log('Sending state update to backend.', { url, body });
|
|
@@ -284,11 +284,12 @@ export const Compositor = (props: CompositorProps) => {
|
|
|
284
284
|
|
|
285
285
|
useEffect(() => {
|
|
286
286
|
fullContentMapStore.set(props.fullContentMap);
|
|
287
|
-
hasAssemblyAIStore.set(props.config
|
|
287
|
+
hasAssemblyAIStore.set(props.config?.HAS_AAI || false);
|
|
288
288
|
urlParamsStore.set(props.urlParams);
|
|
289
289
|
canonicalURLStore.set(props.fullCanonicalURL);
|
|
290
290
|
preferredThemeStore.set(props.config.THEME as Theme);
|
|
291
|
-
|
|
291
|
+
if (props.config.BRAND_COLOURS)
|
|
292
|
+
brandColourStore.set(props.config.BRAND_COLOURS);
|
|
292
293
|
codehookMapStore.set(props.availableCodeHooks);
|
|
293
294
|
}, [
|
|
294
295
|
props.fullContentMap,
|
|
@@ -30,8 +30,8 @@ import { NodeBasicTag } from './nodes/tagElements/NodeBasicTag';
|
|
|
30
30
|
import { NodeBasicTagInsert } from './nodes/tagElements/NodeBasicTag_insert';
|
|
31
31
|
import { NodeBasicTagEraser } from './nodes/tagElements/NodeBasicTag_eraser';
|
|
32
32
|
import { NodeBasicTagSettings } from './nodes/tagElements/NodeBasicTag_settings';
|
|
33
|
+
import { Pane_DesignLibrary } from './nodes/Pane_DesignLibrary';
|
|
33
34
|
import AddPanePanel from '@/components/edit/pane/AddPanePanel';
|
|
34
|
-
import PageCreationSelector from '@/components/edit/pane/PageGenSelector';
|
|
35
35
|
import ConfigPanePanel from '@/components/edit/pane/ConfigPanePanel';
|
|
36
36
|
import StoryFragmentConfigPanel from '@/components/edit/storyfragment/StoryFragmentConfigPanel';
|
|
37
37
|
import StoryFragmentTitlePanel from '@/components/edit/storyfragment/StoryFragmentPanel_title';
|
|
@@ -45,6 +45,7 @@ import type {
|
|
|
45
45
|
BaseNode,
|
|
46
46
|
FlatNode,
|
|
47
47
|
} from '@/types/compositorTypes';
|
|
48
|
+
import { PaneAddMode } from '@/types/compositorTypes';
|
|
48
49
|
import { handleClickEventDefault } from '@/utils/compositor/handleClickEvent';
|
|
49
50
|
import { selectionStore } from '@/stores/selection';
|
|
50
51
|
import type { NodeProps, SelectionOrigin } from '@/types/nodeProps';
|
|
@@ -88,6 +89,25 @@ function parseCodeHook(node: BaseNode | FlatNode) {
|
|
|
88
89
|
return null;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// Helper component to safely set the panel mode for an empty page
|
|
93
|
+
const EmptyPageHandler = (props: NodeProps) => {
|
|
94
|
+
const ctx = getCtx(props);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
ctx.setPaneAddMode(props.nodeId, PaneAddMode.NEW);
|
|
97
|
+
}, []);
|
|
98
|
+
|
|
99
|
+
// Now that the mode is set, render the panel which will read it.
|
|
100
|
+
return (
|
|
101
|
+
<AddPanePanel
|
|
102
|
+
nodeId={props.nodeId}
|
|
103
|
+
first={true}
|
|
104
|
+
ctx={ctx}
|
|
105
|
+
isStoryFragment={true}
|
|
106
|
+
config={props.config!}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
91
111
|
const getElement = (
|
|
92
112
|
node: BaseNode | FlatNode,
|
|
93
113
|
props: NodeProps
|
|
@@ -95,7 +115,6 @@ const getElement = (
|
|
|
95
115
|
if (node === undefined) return <></>;
|
|
96
116
|
const isPreview = getCtx(props).rootNodeId.get() === `tmp`;
|
|
97
117
|
const hasPanes = useStore(getCtx(props).hasPanes);
|
|
98
|
-
const isTemplate = useStore(getCtx(props).isTemplate);
|
|
99
118
|
const sharedProps = { ...props, nodeId: node.id };
|
|
100
119
|
const type = getType(node);
|
|
101
120
|
|
|
@@ -151,12 +170,7 @@ const getElement = (
|
|
|
151
170
|
</div>
|
|
152
171
|
</div>
|
|
153
172
|
) : !hasPanes && sf.slug && sf.title && !isPreview ? (
|
|
154
|
-
<
|
|
155
|
-
nodeId={props.nodeId}
|
|
156
|
-
ctx={getCtx(props)}
|
|
157
|
-
isTemplate={isTemplate}
|
|
158
|
-
config={props.config!}
|
|
159
|
-
/>
|
|
173
|
+
<EmptyPageHandler {...sharedProps} />
|
|
160
174
|
) : (
|
|
161
175
|
<>
|
|
162
176
|
<PanelVisibilityWrapper
|
|
@@ -180,6 +194,9 @@ const getElement = (
|
|
|
180
194
|
const toolModeVal = getCtx(props).toolModeValStore.get().value;
|
|
181
195
|
const paneNodes = getCtx(props).getChildNodeIDs(node.id);
|
|
182
196
|
const paneNode = node as PaneNode;
|
|
197
|
+
if (toolModeVal === 'designLibrary') {
|
|
198
|
+
return <Pane_DesignLibrary {...sharedProps} />;
|
|
199
|
+
}
|
|
183
200
|
if (paneNode.isContextPane) {
|
|
184
201
|
if (!isPreview)
|
|
185
202
|
getCtx(props).hasTitle.set(!(!paneNode.slug || !paneNode.title));
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { type CSSProperties, useEffect, useState } from 'react';
|
|
2
|
+
import { useStore } from '@nanostores/react';
|
|
3
|
+
import ArchiveBoxArrowDownIcon from '@heroicons/react/24/outline/ArchiveBoxArrowDownIcon';
|
|
4
|
+
import ArrowPathRoundedSquareIcon from '@heroicons/react/24/outline/ArrowPathRoundedSquareIcon';
|
|
5
|
+
import { viewportKeyStore } from '@/stores/storykeep';
|
|
6
|
+
import { getCtx } from '@/stores/nodes';
|
|
7
|
+
import { RenderChildren } from './RenderChildren';
|
|
8
|
+
import { CodeHookContainer } from './Pane';
|
|
9
|
+
import type { NodeProps } from '@/types/nodeProps';
|
|
10
|
+
import { SaveToLibraryModal } from '@/components/edit/state/SaveToLibraryModal';
|
|
11
|
+
import { RestylePaneModal } from '@/components/edit/pane/RestylePaneModal';
|
|
12
|
+
import { selectionStore } from '@/stores/selection';
|
|
13
|
+
|
|
14
|
+
export const Pane_DesignLibrary = (props: NodeProps) => {
|
|
15
|
+
const ctx = getCtx(props);
|
|
16
|
+
|
|
17
|
+
if (!props.config || !props.config.TENANT_ID) {
|
|
18
|
+
return <></>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { isRestyleModalOpen } = useStore(selectionStore, {
|
|
22
|
+
keys: ['isRestyleModalOpen'],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const wrapperClasses = `grid ${ctx.getNodeClasses(
|
|
26
|
+
props.nodeId,
|
|
27
|
+
viewportKeyStore.get().value
|
|
28
|
+
)}`;
|
|
29
|
+
const contentClasses = 'relative w-full h-auto justify-self-start';
|
|
30
|
+
const contentStyles: CSSProperties = {
|
|
31
|
+
...ctx.getNodeCSSPropertiesStyles(props.nodeId),
|
|
32
|
+
gridArea: '1/1/1/1',
|
|
33
|
+
};
|
|
34
|
+
const codeHookPayload = ctx.getNodeCodeHookPayload(props.nodeId);
|
|
35
|
+
const [children, setChildren] = useState<string[]>([
|
|
36
|
+
...ctx.getChildNodeIDs(props.nodeId),
|
|
37
|
+
]);
|
|
38
|
+
const [isSaveModalOpen, setIsSaveModalOpen] = useState(false);
|
|
39
|
+
const getPaneId = (): string => `pane-${props.nodeId}`;
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const unsubscribe = ctx.notifications.subscribe(props.nodeId, () => {
|
|
43
|
+
setChildren([...ctx.getChildNodeIDs(props.nodeId)]);
|
|
44
|
+
});
|
|
45
|
+
return unsubscribe;
|
|
46
|
+
}, [props.nodeId, ctx.notifications]);
|
|
47
|
+
|
|
48
|
+
const handleRestyleClick = (e: React.MouseEvent) => {
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
selectionStore.setKey('paneToRestyleId', props.nodeId);
|
|
51
|
+
selectionStore.setKey('isRestyleModalOpen', true);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleSaveClick = (e: React.MouseEvent) => {
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
setIsSaveModalOpen(true);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div id={getPaneId()} className="pane min-h-16">
|
|
61
|
+
<div id={ctx.getNodeSlug(props.nodeId)} className={wrapperClasses}>
|
|
62
|
+
<div
|
|
63
|
+
className={contentClasses}
|
|
64
|
+
style={contentStyles}
|
|
65
|
+
onClick={(e) => {
|
|
66
|
+
ctx.setClickedNodeId(props.nodeId);
|
|
67
|
+
e.stopPropagation();
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<div className="absolute left-2 top-2 z-10 flex flex-col gap-y-2">
|
|
71
|
+
<button
|
|
72
|
+
title="Save Pane to Design Library"
|
|
73
|
+
onClick={handleSaveClick}
|
|
74
|
+
className="flex h-10 w-10 items-center justify-center rounded-full bg-cyan-600 p-1.5 shadow-lg hover:bg-cyan-700"
|
|
75
|
+
>
|
|
76
|
+
<ArchiveBoxArrowDownIcon className="h-7 w-7 text-white" />
|
|
77
|
+
</button>
|
|
78
|
+
<button
|
|
79
|
+
title="Restyle Pane from Design Library"
|
|
80
|
+
onClick={handleRestyleClick}
|
|
81
|
+
className="flex h-10 w-10 items-center justify-center rounded-full bg-blue-600 p-1.5 shadow-lg hover:bg-blue-700"
|
|
82
|
+
>
|
|
83
|
+
<ArrowPathRoundedSquareIcon className="h-7 w-7 text-white" />
|
|
84
|
+
</button>
|
|
85
|
+
</div>
|
|
86
|
+
{codeHookPayload ? (
|
|
87
|
+
<CodeHookContainer payload={codeHookPayload} />
|
|
88
|
+
) : (
|
|
89
|
+
<RenderChildren children={children} nodeProps={props} />
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
{isSaveModalOpen && (
|
|
94
|
+
<SaveToLibraryModal
|
|
95
|
+
paneId={props.nodeId}
|
|
96
|
+
config={props.config}
|
|
97
|
+
tenantId={props.config.TENANT_ID}
|
|
98
|
+
onClose={() => setIsSaveModalOpen(false)}
|
|
99
|
+
/>
|
|
100
|
+
)}
|
|
101
|
+
|
|
102
|
+
{isRestyleModalOpen && <RestylePaneModal config={props.config} />}
|
|
103
|
+
</div>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
@@ -3,6 +3,7 @@ import { useStore } from '@nanostores/react';
|
|
|
3
3
|
import PencilSquareIcon from '@heroicons/react/24/outline/PencilSquareIcon';
|
|
4
4
|
import PaintBrushIcon from '@heroicons/react/24/outline/PaintBrushIcon';
|
|
5
5
|
import TrashIcon from '@heroicons/react/24/outline/TrashIcon';
|
|
6
|
+
import ArrowPathRoundedSquareIcon from '@heroicons/react/24/outline/ArrowPathRoundedSquareIcon';
|
|
6
7
|
import ArrowsUpDownIcon from '@heroicons/react/24/outline/ArrowsUpDownIcon';
|
|
7
8
|
import PlusIcon from '@heroicons/react/24/outline/PlusIcon';
|
|
8
9
|
import BugAntIcon from '@heroicons/react/24/outline/BugAntIcon';
|
|
@@ -45,6 +46,12 @@ const storykeepToolModes = [
|
|
|
45
46
|
title: 'Move',
|
|
46
47
|
description: 'Keyboard accessible re-order',
|
|
47
48
|
},
|
|
49
|
+
{
|
|
50
|
+
key: 'designLibrary' as const,
|
|
51
|
+
Icon: ArrowPathRoundedSquareIcon,
|
|
52
|
+
title: 'Design Library',
|
|
53
|
+
description: 'Save pane to design library',
|
|
54
|
+
},
|
|
48
55
|
] as const;
|
|
49
56
|
|
|
50
57
|
interface StoryKeepToolModeProps {
|