astro-tractstack 2.0.12 → 2.0.14
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 +22 -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 +18 -2
- 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.tsx +5 -1
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +4 -1
- package/templates/src/components/edit/pane/AiPaneGenerator.tsx +264 -94
- package/templates/src/components/edit/pane/AiPanePreview.tsx +60 -210
- package/templates/src/components/edit/pane/PageGen.tsx +1 -1
- package/templates/src/components/edit/pane/PageGenSelector.tsx +4 -0
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +573 -0
- package/templates/src/components/edit/state/SaveToLibraryModal.tsx +205 -0
- package/templates/src/constants/prompts.json +3 -3
- 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 +39 -13
- package/templates/src/utils/compositor/designLibraryHelper.ts +331 -0
- package/templates/src/utils/compositor/processMarkdown.ts +1 -1
- package/utils/inject-files.ts +22 -0
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"
|
|
@@ -624,6 +636,10 @@ async function w(t, e, c) {
|
|
|
624
636
|
src: t("../templates/src/utils/compositor/typeGuards.ts"),
|
|
625
637
|
dest: "src/utils/compositor/typeGuards.ts"
|
|
626
638
|
},
|
|
639
|
+
{
|
|
640
|
+
src: t("../templates/src/utils/compositor/designLibraryHelper.ts"),
|
|
641
|
+
dest: "src/utils/compositor/designLibraryHelper.ts"
|
|
642
|
+
},
|
|
627
643
|
{
|
|
628
644
|
src: t("../templates/src/utils/compositor/domHelpers.ts"),
|
|
629
645
|
dest: "src/utils/compositor/domHelpers.ts"
|
|
@@ -1345,6 +1361,12 @@ async function w(t, e, c) {
|
|
|
1345
1361
|
src: t("../templates/src/components/edit/state/SaveModal.tsx"),
|
|
1346
1362
|
dest: "src/components/edit/state/SaveModal.tsx"
|
|
1347
1363
|
},
|
|
1364
|
+
{
|
|
1365
|
+
src: t(
|
|
1366
|
+
"../templates/src/components/edit/state/SaveToLibraryModal.tsx"
|
|
1367
|
+
),
|
|
1368
|
+
dest: "src/components/edit/state/SaveToLibraryModal.tsx"
|
|
1369
|
+
},
|
|
1348
1370
|
{
|
|
1349
1371
|
src: t("../templates/src/components/edit/state/StylesMemory.tsx"),
|
|
1350
1372
|
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,6 +30,7 @@ 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
35
|
import PageCreationSelector from '@/components/edit/pane/PageGenSelector';
|
|
35
36
|
import ConfigPanePanel from '@/components/edit/pane/ConfigPanePanel';
|
|
@@ -155,6 +156,7 @@ const getElement = (
|
|
|
155
156
|
nodeId={props.nodeId}
|
|
156
157
|
ctx={getCtx(props)}
|
|
157
158
|
isTemplate={isTemplate}
|
|
159
|
+
config={props.config!}
|
|
158
160
|
/>
|
|
159
161
|
) : (
|
|
160
162
|
<>
|
|
@@ -179,6 +181,9 @@ const getElement = (
|
|
|
179
181
|
const toolModeVal = getCtx(props).toolModeValStore.get().value;
|
|
180
182
|
const paneNodes = getCtx(props).getChildNodeIDs(node.id);
|
|
181
183
|
const paneNode = node as PaneNode;
|
|
184
|
+
if (toolModeVal === 'designLibrary') {
|
|
185
|
+
return <Pane_DesignLibrary {...sharedProps} />;
|
|
186
|
+
}
|
|
182
187
|
if (paneNode.isContextPane) {
|
|
183
188
|
if (!isPreview)
|
|
184
189
|
getCtx(props).hasTitle.set(!(!paneNode.slug || !paneNode.title));
|
|
@@ -215,6 +220,7 @@ const getElement = (
|
|
|
215
220
|
nodeId={node.id}
|
|
216
221
|
first={true}
|
|
217
222
|
ctx={getCtx(props)}
|
|
223
|
+
config={props.config!}
|
|
218
224
|
isContextPane={true}
|
|
219
225
|
/>
|
|
220
226
|
</PanelVisibilityWrapper>
|
|
@@ -242,7 +248,12 @@ const getElement = (
|
|
|
242
248
|
panelType="add"
|
|
243
249
|
ctx={getCtx(props)}
|
|
244
250
|
>
|
|
245
|
-
<AddPanePanel
|
|
251
|
+
<AddPanePanel
|
|
252
|
+
nodeId={node.id}
|
|
253
|
+
first={true}
|
|
254
|
+
ctx={getCtx(props)}
|
|
255
|
+
config={props.config!}
|
|
256
|
+
/>
|
|
246
257
|
</PanelVisibilityWrapper>
|
|
247
258
|
)}
|
|
248
259
|
<div className="py-0.5">
|
|
@@ -266,7 +277,12 @@ const getElement = (
|
|
|
266
277
|
panelType="add"
|
|
267
278
|
ctx={getCtx(props)}
|
|
268
279
|
>
|
|
269
|
-
<AddPanePanel
|
|
280
|
+
<AddPanePanel
|
|
281
|
+
nodeId={node.id}
|
|
282
|
+
first={false}
|
|
283
|
+
ctx={getCtx(props)}
|
|
284
|
+
config={props.config!}
|
|
285
|
+
/>
|
|
270
286
|
</PanelVisibilityWrapper>
|
|
271
287
|
</>
|
|
272
288
|
);
|
|
@@ -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 {
|
|
@@ -5,8 +5,9 @@ import AddPaneNewPanel from './AddPanePanel_new';
|
|
|
5
5
|
import AddPaneBreakPanel from './AddPanePanel_break';
|
|
6
6
|
import AddPaneReUsePanel from './AddPanePanel_reuse';
|
|
7
7
|
import AddPaneCodeHookPanel from './AddPanePanel_codehook';
|
|
8
|
-
import { NodesContext, ROOT_NODE_NAME, getCtx } from '@/stores/nodes';
|
|
8
|
+
import { NodesContext, ROOT_NODE_NAME, getCtx } from '@/stores/nodes';
|
|
9
9
|
import { PaneAddMode } from '@/types/compositorTypes';
|
|
10
|
+
import type { BrandConfig } from '@/types/tractstack';
|
|
10
11
|
|
|
11
12
|
interface AddPanePanelProps {
|
|
12
13
|
nodeId: string;
|
|
@@ -14,6 +15,7 @@ interface AddPanePanelProps {
|
|
|
14
15
|
ctx?: NodesContext;
|
|
15
16
|
isStoryFragment?: boolean;
|
|
16
17
|
isContextPane?: boolean;
|
|
18
|
+
config?: BrandConfig;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
const AddPanePanel = ({
|
|
@@ -22,6 +24,7 @@ const AddPanePanel = ({
|
|
|
22
24
|
ctx,
|
|
23
25
|
isStoryFragment = false,
|
|
24
26
|
isContextPane = false,
|
|
27
|
+
config,
|
|
25
28
|
}: AddPanePanelProps) => {
|
|
26
29
|
const [reset, setReset] = useState(false);
|
|
27
30
|
const lookup = first ? `${nodeId}-0` : nodeId;
|
|
@@ -62,6 +65,7 @@ const AddPanePanel = ({
|
|
|
62
65
|
ctx={nodesCtx}
|
|
63
66
|
isStoryFragment={isStoryFragment}
|
|
64
67
|
isContextPane={isContextPane}
|
|
68
|
+
config={config!}
|
|
65
69
|
/>
|
|
66
70
|
) : mode === PaneAddMode.BREAK && !isContextPane ? (
|
|
67
71
|
<AddPaneBreakPanel
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
import { templateCategories } from '@/utils/compositor/templateMarkdownStyles';
|
|
27
27
|
import { AiPaneGenerator } from './AiPaneGenerator';
|
|
28
28
|
import { AddPaneNewCustomCopy } from './AddPanePanel_newCustomCopy';
|
|
29
|
-
import { themes, type Theme } from '@/types/tractstack';
|
|
29
|
+
import { themes, type Theme, type BrandConfig } from '@/types/tractstack';
|
|
30
30
|
import { PaneAddMode, type TemplatePane } from '@/types/compositorTypes';
|
|
31
31
|
import { useStore } from '@nanostores/react';
|
|
32
32
|
|
|
@@ -37,6 +37,7 @@ interface AddPaneNewPanelProps {
|
|
|
37
37
|
ctx?: NodesContext;
|
|
38
38
|
isStoryFragment?: boolean;
|
|
39
39
|
isContextPane?: boolean;
|
|
40
|
+
config?: BrandConfig;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
interface PreviewPane {
|
|
@@ -65,6 +66,7 @@ const AddPaneNewPanel = ({
|
|
|
65
66
|
ctx,
|
|
66
67
|
isStoryFragment = false,
|
|
67
68
|
isContextPane = false,
|
|
69
|
+
config,
|
|
68
70
|
}: AddPaneNewPanelProps) => {
|
|
69
71
|
const brand = useStore(brandColourStore);
|
|
70
72
|
const hasAssemblyAI = useStore(hasAssemblyAIStore);
|
|
@@ -384,6 +386,7 @@ const AddPaneNewPanel = ({
|
|
|
384
386
|
ownerId={nodeId}
|
|
385
387
|
onComplete={handleApplyGeneratedPane}
|
|
386
388
|
onCancel={() => setMode('template')}
|
|
389
|
+
config={config!}
|
|
387
390
|
/>
|
|
388
391
|
</div>
|
|
389
392
|
)}
|