astro-tractstack 2.1.2 → 2.2.0
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/README.md +54 -266
- package/bin/create-tractstack.js +9 -6
- package/dist/index.js +109 -71
- package/package.json +4 -2
- package/templates/css/custom.css +5 -0
- package/templates/custom/minimal/CodeHook.astro +1 -0
- package/templates/custom/with-examples/CodeHook.astro +1 -0
- package/templates/icons/code.svg +18 -0
- package/templates/icons/li.svg +4 -0
- package/templates/icons/link.svg +22 -0
- package/templates/icons/p.svg +3 -0
- package/templates/src/client/app.js +80 -1
- package/templates/src/components/Footer.astro +1 -1
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +6 -6
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +3 -3
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +1 -1
- package/templates/src/components/codehooks/ListContentSetup.tsx +2 -2
- package/templates/src/components/codehooks/ProductCardSetup.tsx +1 -1
- package/templates/src/components/codehooks/ProductGridSetup.tsx +2 -2
- package/templates/src/components/codehooks/SandboxRegisterForm.tsx +3 -3
- package/templates/src/components/compositor/Compositor.tsx +25 -9
- package/templates/src/components/compositor/Node.tsx +168 -496
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +1 -0
- package/templates/src/components/compositor/elements/SignUp.tsx +1 -1
- package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +2 -0
- package/templates/src/components/compositor/nodes/CreativePane.tsx +262 -0
- package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +4 -6
- package/templates/src/components/compositor/nodes/GridLayout.tsx +4 -2
- package/templates/src/components/compositor/nodes/Markdown.tsx +18 -3
- package/templates/src/components/compositor/nodes/Pane.tsx +11 -5
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +1 -1
- package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +5 -5
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +90 -42
- package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +2 -0
- package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +27 -1
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +10 -8
- package/templates/src/components/compositor/tools/NodeOverlay.tsx +224 -0
- package/templates/src/components/compositor/tools/PaneOverlay.tsx +122 -0
- package/templates/src/components/edit/Header.tsx +68 -9
- package/templates/src/components/edit/PanelSwitch.tsx +42 -4
- package/templates/src/components/edit/SettingsPanel.tsx +2 -3
- package/templates/src/components/edit/ToolMode.tsx +1 -31
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +2 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +1 -1
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +193 -659
- package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +15 -82
- package/templates/src/components/edit/pane/AiRestylePaneModal.tsx +95 -45
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +137 -49
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +1 -1
- package/templates/src/components/edit/pane/steps/AiCreativeDesignStep.tsx +375 -0
- package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +1 -23
- package/templates/src/components/edit/pane/steps/AiLibraryCopyStep.tsx +327 -0
- package/templates/src/components/edit/pane/steps/AiRefineDesignStep.tsx +267 -0
- package/templates/src/components/edit/pane/steps/AiStandardDesignStep.tsx +371 -0
- package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +201 -76
- package/templates/src/components/edit/pane/steps/CreativeInjectStep.tsx +141 -0
- package/templates/src/components/edit/panels/CreativeImagePanel.tsx +435 -0
- package/templates/src/components/edit/panels/CreativeLinkPanel.tsx +110 -0
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +1 -1
- package/templates/src/components/edit/panels/StyleParentPanel.tsx +118 -126
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +3 -2
- package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +1 -0
- package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +3 -1
- package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +3 -1
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +1 -1
- package/templates/src/components/edit/state/SaveModal.tsx +19 -787
- package/templates/src/components/edit/state/SaveToLibraryModal.tsx +2 -2
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +1 -1
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +5 -5
- package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +1 -1
- package/templates/src/components/edit/widgets/SignupWidget.tsx +1 -1
- package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +1 -1
- package/templates/src/components/fields/ArtpackImage.tsx +11 -3
- package/templates/src/components/fields/BackgroundImage.tsx +8 -0
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +15 -9
- package/templates/src/components/fields/ImageUpload.tsx +6 -0
- package/templates/src/components/form/ActionBuilderField.tsx +15 -5
- package/templates/src/components/form/ActionBuilderSlugSelector.tsx +1 -1
- package/templates/src/components/form/ColorPicker.tsx +1 -1
- package/templates/src/components/form/EnumSelect.tsx +1 -1
- package/templates/src/components/form/NumberInput.tsx +1 -1
- package/templates/src/components/form/StringArrayInput.tsx +1 -1
- package/templates/src/components/form/StringInput.tsx +1 -1
- package/templates/src/components/form/UnsavedChangesBar.tsx +1 -1
- package/templates/src/components/form/advanced/APIConfigSection.tsx +2 -2
- package/templates/src/components/form/advanced/AuthConfigSection.tsx +2 -2
- package/templates/src/components/profile/ProfileCreate.tsx +1 -1
- package/templates/src/components/profile/ProfileEdit.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +2 -2
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +2 -2
- package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/ManageContent.tsx +6 -6
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +1 -1
- package/templates/src/components/storykeep/controls/content/PaneTable.tsx +358 -0
- package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +1 -1
- package/templates/src/constants/prompts.json +18 -10
- package/templates/src/constants.ts +3 -0
- package/templates/src/hooks/usePaneFragments.ts +60 -0
- package/templates/src/lib/session.ts +71 -16
- package/templates/src/pages/[...slug].astro +5 -46
- package/templates/src/pages/api/css.ts +149 -0
- package/templates/src/pages/context/[...contextSlug].astro +1 -0
- package/templates/src/pages/maint.astro +1 -1
- package/templates/src/pages/storykeep/login.astro +2 -2
- package/templates/src/stores/nodes.ts +162 -49
- package/templates/src/stores/orphanAnalysis.ts +6 -30
- package/templates/src/stores/previews.ts +7 -0
- package/templates/src/stores/storykeep.ts +0 -8
- package/templates/src/types/compositorTypes.ts +53 -10
- package/templates/src/utils/compositor/aiGeneration.ts +93 -0
- package/templates/src/utils/compositor/allowInsert.ts +2 -0
- package/templates/src/utils/compositor/htmlAst.ts +704 -0
- package/templates/src/utils/compositor/nodesHelper.ts +281 -102
- package/templates/src/utils/compositor/savePipeline.ts +893 -0
- package/templates/src/utils/etl/index.ts +3 -0
- package/templates/src/utils/etl/transformer.ts +10 -0
- package/templates/src/utils/helpers.ts +101 -0
- package/utils/inject-files.ts +100 -62
- package/templates/icons/text.svg +0 -6
- package/templates/src/components/compositor/NodeWithGuid.tsx +0 -69
- package/templates/src/components/compositor/nodes/GridLayout_eraser.tsx +0 -33
- package/templates/src/components/compositor/nodes/Markdown_eraser.tsx +0 -56
- package/templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx +0 -269
- package/templates/src/components/compositor/nodes/Pane_eraser.tsx +0 -186
- package/templates/src/components/compositor/nodes/Pane_layout.tsx +0 -79
- package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +0 -26
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +0 -61
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +0 -120
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +0 -62
- package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +0 -26
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
|
|
3
3
|
import { savePaneToLibrary } from '@/utils/compositor/designLibraryHelper';
|
|
4
4
|
import { convertToBackendFormat } from '@/utils/api/brandHelpers';
|
|
5
5
|
import StringInput from '@/components/form/StringInput';
|
|
@@ -165,7 +165,7 @@ export function SaveToLibraryModal({
|
|
|
165
165
|
id="category-select"
|
|
166
166
|
value={selectedCategory}
|
|
167
167
|
onChange={(e) => setSelectedCategory(e.target.value)}
|
|
168
|
-
className="
|
|
168
|
+
className="mt-1 block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-base focus:border-cyan-500 focus:outline-none focus:ring-cyan-500 md:text-sm"
|
|
169
169
|
>
|
|
170
170
|
{categories.map((cat) => (
|
|
171
171
|
<option key={cat} value={cat}>
|
|
@@ -282,7 +282,7 @@ const StoryFragmentMenuPanel = ({
|
|
|
282
282
|
/>
|
|
283
283
|
</Combobox.Trigger>
|
|
284
284
|
</div>
|
|
285
|
-
<Combobox.Content className="
|
|
285
|
+
<Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
286
286
|
{filteredMenus.length === 0 && query !== '' ? (
|
|
287
287
|
<div className="relative cursor-default select-none px-4 py-2 text-mydarkgrey">
|
|
288
288
|
Nothing found.
|
|
@@ -382,7 +382,7 @@ function BunnyWidget({ node, onUpdate }: BunnyWidgetProps) {
|
|
|
382
382
|
</Dialog.Title>
|
|
383
383
|
</div>
|
|
384
384
|
<div className="flex-1 overflow-y-auto p-4">
|
|
385
|
-
<div className="
|
|
385
|
+
<div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
|
386
386
|
<div className="rounded-lg border border-gray-200 bg-white shadow-sm">
|
|
387
387
|
<div className="flex items-center justify-between border-b border-gray-200 p-3">
|
|
388
388
|
<h3 className="text-base font-bold text-gray-900">
|
|
@@ -433,7 +433,7 @@ function BunnyWidget({ node, onUpdate }: BunnyWidgetProps) {
|
|
|
433
433
|
onBlur={() =>
|
|
434
434
|
handleUpdate(videoId, title, chapters)
|
|
435
435
|
}
|
|
436
|
-
className={`
|
|
436
|
+
className={`mt-1 block w-full rounded-md border-gray-300 px-2 py-1 shadow-sm md:text-sm ${formErrors[`title-${index}`] ? 'border-red-300' : 'focus:border-cyan-500 focus:ring-cyan-500'}`}
|
|
437
437
|
/>
|
|
438
438
|
</div>
|
|
439
439
|
<div>
|
|
@@ -451,7 +451,7 @@ function BunnyWidget({ node, onUpdate }: BunnyWidgetProps) {
|
|
|
451
451
|
onBlur={() =>
|
|
452
452
|
handleUpdate(videoId, title, chapters)
|
|
453
453
|
}
|
|
454
|
-
className="
|
|
454
|
+
className="mt-1 block w-full rounded-md border-gray-300 px-2 py-1 shadow-sm focus:border-cyan-500 focus:ring-cyan-500 md:text-sm"
|
|
455
455
|
/>
|
|
456
456
|
</div>
|
|
457
457
|
<div className="grid grid-cols-2 gap-2">
|
|
@@ -472,7 +472,7 @@ function BunnyWidget({ node, onUpdate }: BunnyWidgetProps) {
|
|
|
472
472
|
onBlur={() =>
|
|
473
473
|
handleUpdate(videoId, title, chapters)
|
|
474
474
|
}
|
|
475
|
-
className={`
|
|
475
|
+
className={`mt-1 block w-full rounded-md border-gray-300 px-2 py-1 shadow-sm md:text-sm ${formErrors[`startTime-${index}`] || formErrors[`overlap-${index}`] ? 'border-red-300' : 'focus:border-cyan-500 focus:ring-cyan-500'}`}
|
|
476
476
|
/>
|
|
477
477
|
</div>
|
|
478
478
|
<div>
|
|
@@ -491,7 +491,7 @@ function BunnyWidget({ node, onUpdate }: BunnyWidgetProps) {
|
|
|
491
491
|
onBlur={() =>
|
|
492
492
|
handleUpdate(videoId, title, chapters)
|
|
493
493
|
}
|
|
494
|
-
className={`
|
|
494
|
+
className={`mt-1 block w-full rounded-md border-gray-300 px-2 py-1 shadow-sm md:text-sm ${formErrors[`endTime-${index}`] || formErrors[`overlap-${index}`] ? 'border-red-300' : 'focus:border-cyan-500 focus:ring-cyan-500'}`}
|
|
495
495
|
/>
|
|
496
496
|
</div>
|
|
497
497
|
</div>
|
|
@@ -621,7 +621,7 @@ export default function InteractiveDisclosureWidget({
|
|
|
621
621
|
<h3 className="font-bold text-gray-800">
|
|
622
622
|
Widget Styles
|
|
623
623
|
</h3>
|
|
624
|
-
<div className="
|
|
624
|
+
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
625
625
|
<div>
|
|
626
626
|
<ColorPickerCombo
|
|
627
627
|
title="Background Color"
|
|
@@ -135,7 +135,7 @@ function SignupWidget({ node, onUpdate }: SignupWidgetProps) {
|
|
|
135
135
|
/>
|
|
136
136
|
</Combobox.Trigger>
|
|
137
137
|
</div>
|
|
138
|
-
<Combobox.Content className="
|
|
138
|
+
<Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
139
139
|
{collection.items.length === 0 ? (
|
|
140
140
|
<div className="relative cursor-default select-none px-4 py-2 text-gray-700">
|
|
141
141
|
Nothing found.
|
|
@@ -270,7 +270,7 @@ export default function ActionBuilderTimeSelector({
|
|
|
270
270
|
</Combobox.Trigger>
|
|
271
271
|
</div>
|
|
272
272
|
|
|
273
|
-
<Combobox.Content className="
|
|
273
|
+
<Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
274
274
|
{availableVideos.length > 0 ? (
|
|
275
275
|
collection.items.length === 0 ? (
|
|
276
276
|
<div className="relative cursor-default select-none px-4 py-2 text-gray-700">
|
|
@@ -9,7 +9,7 @@ import SwatchIcon from '@heroicons/react/24/outline/SwatchIcon';
|
|
|
9
9
|
import ChevronUpDownIcon from '@heroicons/react/24/outline/ChevronUpDownIcon';
|
|
10
10
|
import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
|
|
11
11
|
import { getCtx } from '@/stores/nodes';
|
|
12
|
-
import { hasArtpacksStore } from '@/stores/storykeep';
|
|
12
|
+
import { hasArtpacksStore, settingsPanelStore } from '@/stores/storykeep';
|
|
13
13
|
import { cloneDeep } from '@/utils/helpers';
|
|
14
14
|
import type { ArtpackImageNode, PaneNode } from '@/types/compositorTypes';
|
|
15
15
|
|
|
@@ -157,7 +157,15 @@ const ArtpackImage = ({ paneId, onUpdate }: ArtpackImageProps) => {
|
|
|
157
157
|
ctx.modifyNodes([updatedPaneNode]);
|
|
158
158
|
setArtpackNode(updatedArtNode);
|
|
159
159
|
setIsModalOpen(false);
|
|
160
|
+
const currentSignal = settingsPanelStore.get();
|
|
161
|
+
if (currentSignal) {
|
|
162
|
+
settingsPanelStore.set({
|
|
163
|
+
...currentSignal,
|
|
164
|
+
editLock: Date.now(),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
160
167
|
onUpdate();
|
|
168
|
+
ctx.notifyNode('root');
|
|
161
169
|
};
|
|
162
170
|
|
|
163
171
|
const handleRemoveImage = () => {
|
|
@@ -395,7 +403,7 @@ const ArtpackImage = ({ paneId, onUpdate }: ArtpackImageProps) => {
|
|
|
395
403
|
/>
|
|
396
404
|
</Combobox.Trigger>
|
|
397
405
|
</div>
|
|
398
|
-
<Combobox.Content className="
|
|
406
|
+
<Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
399
407
|
{collection.items.length === 0 ? (
|
|
400
408
|
<div className="relative cursor-default select-none px-4 py-2 text-gray-700">
|
|
401
409
|
No collections found.
|
|
@@ -429,7 +437,7 @@ const ArtpackImage = ({ paneId, onUpdate }: ArtpackImageProps) => {
|
|
|
429
437
|
<label className="mb-2 block text-sm font-bold text-mydarkgrey">
|
|
430
438
|
Select Image from {selectedCollection}
|
|
431
439
|
</label>
|
|
432
|
-
<div className="
|
|
440
|
+
<div className="grid grid-cols-2 gap-4 p-2 md:grid-cols-3">
|
|
433
441
|
{availableImages.map((image) => (
|
|
434
442
|
<div
|
|
435
443
|
key={image}
|
|
@@ -9,6 +9,7 @@ import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
|
|
|
9
9
|
import ChevronUpDownIcon from '@heroicons/react/24/outline/ChevronUpDownIcon';
|
|
10
10
|
import { getCtx } from '@/stores/nodes';
|
|
11
11
|
import { cloneDeep } from '@/utils/helpers';
|
|
12
|
+
import { settingsPanelStore } from '@/stores/storykeep';
|
|
12
13
|
import type {
|
|
13
14
|
ImageFileNode,
|
|
14
15
|
BgImageNode,
|
|
@@ -166,6 +167,13 @@ const BackgroundImage = ({ paneId, onUpdate }: BackgroundImageProps) => {
|
|
|
166
167
|
ctx.modifyNodes([updatedPaneNode]);
|
|
167
168
|
setBgImageNode(updatedBgNode);
|
|
168
169
|
setLocalAltDescription(updatedBgNode.alt || '');
|
|
170
|
+
const currentSignal = settingsPanelStore.get();
|
|
171
|
+
if (currentSignal) {
|
|
172
|
+
settingsPanelStore.set({
|
|
173
|
+
...currentSignal,
|
|
174
|
+
editLock: Date.now(),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
169
177
|
onUpdate();
|
|
170
178
|
ctx.notifyNode('root');
|
|
171
179
|
};
|
|
@@ -17,6 +17,7 @@ import { isArtpackImageNode } from '@/utils/compositor/typeGuards';
|
|
|
17
17
|
|
|
18
18
|
export interface BackgroundImageWrapperProps {
|
|
19
19
|
paneId: string;
|
|
20
|
+
isGrid: boolean;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
const CheckIcon = () => (
|
|
@@ -49,7 +50,10 @@ const ChevronDownIcon = () => (
|
|
|
49
50
|
</svg>
|
|
50
51
|
);
|
|
51
52
|
|
|
52
|
-
const BackgroundImageWrapper = ({
|
|
53
|
+
const BackgroundImageWrapper = ({
|
|
54
|
+
paneId,
|
|
55
|
+
isGrid,
|
|
56
|
+
}: BackgroundImageWrapperProps) => {
|
|
53
57
|
const ctx = getCtx();
|
|
54
58
|
const allNodes = useStore(ctx.allNodes);
|
|
55
59
|
const $artpacks = useStore(hasArtpacksStore);
|
|
@@ -113,13 +117,15 @@ const BackgroundImageWrapper = ({ paneId }: BackgroundImageWrapperProps) => {
|
|
|
113
117
|
const position = bgNode?.position || 'background';
|
|
114
118
|
const size = bgNode?.size || 'equal';
|
|
115
119
|
|
|
116
|
-
const positionOptions =
|
|
117
|
-
{ label: 'Background', value: 'background' }
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
const positionOptions = isGrid
|
|
121
|
+
? [{ label: 'Background', value: 'background' }]
|
|
122
|
+
: [
|
|
123
|
+
{ label: 'Background', value: 'background' },
|
|
124
|
+
{ label: 'Left', value: 'left' },
|
|
125
|
+
{ label: 'Right', value: 'right' },
|
|
126
|
+
{ label: 'Left Bleed', value: 'leftBleed' },
|
|
127
|
+
{ label: 'Right Bleed', value: 'rightBleed' },
|
|
128
|
+
];
|
|
123
129
|
|
|
124
130
|
const collection = useMemo(
|
|
125
131
|
() =>
|
|
@@ -163,7 +169,7 @@ const BackgroundImageWrapper = ({ paneId }: BackgroundImageWrapperProps) => {
|
|
|
163
169
|
allowNull={true}
|
|
164
170
|
/>
|
|
165
171
|
{!bgNode && (
|
|
166
|
-
<div className="
|
|
172
|
+
<div className="flex flex-col gap-4 md:flex-row">
|
|
167
173
|
<div className="flex-1">
|
|
168
174
|
<h4 className="mb-2 text-sm font-bold text-gray-700">
|
|
169
175
|
Background Image
|
|
@@ -21,6 +21,8 @@ export interface ImageParams {
|
|
|
21
21
|
srcSet?: string;
|
|
22
22
|
altDescription: string;
|
|
23
23
|
base64Data?: string;
|
|
24
|
+
collection?: string | null;
|
|
25
|
+
image?: string | null;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
interface ImageUploadProps {
|
|
@@ -144,6 +146,8 @@ export const ImageUpload = ({
|
|
|
144
146
|
src: selected.src,
|
|
145
147
|
srcSet: selected.srcSet,
|
|
146
148
|
altDescription: selected.altDescription || missingAlt,
|
|
149
|
+
collection: null,
|
|
150
|
+
image: null,
|
|
147
151
|
});
|
|
148
152
|
|
|
149
153
|
// Update the node for existing files
|
|
@@ -192,6 +196,8 @@ export const ImageUpload = ({
|
|
|
192
196
|
fileId: ulid(),
|
|
193
197
|
src: base64, // Use base64 as src for immediate display
|
|
194
198
|
altDescription: defaultAlt,
|
|
199
|
+
collection: null,
|
|
200
|
+
image: null,
|
|
195
201
|
});
|
|
196
202
|
|
|
197
203
|
// Update the node with base64Data
|
|
@@ -15,6 +15,7 @@ interface ActionBuilderFieldProps {
|
|
|
15
15
|
label?: string;
|
|
16
16
|
error?: string;
|
|
17
17
|
slug?: string;
|
|
18
|
+
restriction?: 'navigation' | 'action';
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
const parseActionLisp = (
|
|
@@ -42,6 +43,7 @@ export default function ActionBuilderField({
|
|
|
42
43
|
label = 'Action',
|
|
43
44
|
error,
|
|
44
45
|
slug,
|
|
46
|
+
restriction,
|
|
45
47
|
}: ActionBuilderFieldProps) {
|
|
46
48
|
const [command, setCommand] = useState<ActionCommand>('goto');
|
|
47
49
|
const [params, setParams] = useState('');
|
|
@@ -109,6 +111,8 @@ export default function ActionBuilderField({
|
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
const handleCommandChange = (newCommand: ActionCommand) => {
|
|
114
|
+
if (restriction === 'navigation' && newCommand !== 'goto') return;
|
|
115
|
+
if (restriction === 'action' && newCommand === 'goto') return;
|
|
112
116
|
setCommand(newCommand);
|
|
113
117
|
setParams('');
|
|
114
118
|
};
|
|
@@ -183,11 +187,17 @@ export default function ActionBuilderField({
|
|
|
183
187
|
onChange={(e) => handleCommandChange(e.target.value as ActionCommand)}
|
|
184
188
|
className="w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-cyan-700 focus:ring-cyan-700"
|
|
185
189
|
>
|
|
186
|
-
{Object.entries(ACTION_COMMANDS)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
190
|
+
{Object.entries(ACTION_COMMANDS)
|
|
191
|
+
.filter(([key]) => {
|
|
192
|
+
if (restriction === 'navigation') return key === 'goto';
|
|
193
|
+
if (restriction === 'action') return key !== 'goto';
|
|
194
|
+
return true;
|
|
195
|
+
})
|
|
196
|
+
.map(([key, data]) => (
|
|
197
|
+
<option key={key} value={key}>
|
|
198
|
+
{data.name}
|
|
199
|
+
</option>
|
|
200
|
+
))}
|
|
191
201
|
</select>
|
|
192
202
|
<p className="mt-1 text-sm text-gray-500">
|
|
193
203
|
{ACTION_COMMANDS[command]?.description}
|
|
@@ -151,7 +151,7 @@ const ActionBuilderSlugSelector = ({
|
|
|
151
151
|
</Combobox.Trigger>
|
|
152
152
|
</div>
|
|
153
153
|
|
|
154
|
-
<Combobox.Content className="
|
|
154
|
+
<Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full max-w-md overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
155
155
|
{filteredItems.length === 0 ? (
|
|
156
156
|
<div className="relative cursor-default select-none px-4 py-2 text-gray-700">
|
|
157
157
|
{query ? 'No matching items found' : 'No items available'}
|
|
@@ -56,7 +56,7 @@ const EnumSelect = ({
|
|
|
56
56
|
'block w-fit min-w-48 rounded-md border-0 px-3 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset',
|
|
57
57
|
error ? 'ring-red-300 focus:ring-red-500' : 'focus:ring-cyan-600',
|
|
58
58
|
disabled ? 'cursor-not-allowed bg-gray-50 text-gray-500' : 'bg-white',
|
|
59
|
-
'
|
|
59
|
+
'md:text-sm md:leading-6'
|
|
60
60
|
)}
|
|
61
61
|
>
|
|
62
62
|
{(allowEmpty || !value) && (
|
|
@@ -140,7 +140,7 @@ const StringArrayInput = ({
|
|
|
140
140
|
className={classNames(
|
|
141
141
|
'block w-full rounded-md border-0 px-3 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset',
|
|
142
142
|
error ? 'ring-red-300 focus:ring-red-500' : 'focus:ring-cyan-600',
|
|
143
|
-
'
|
|
143
|
+
'md:text-sm md:leading-6'
|
|
144
144
|
)}
|
|
145
145
|
/>
|
|
146
146
|
)}
|
|
@@ -147,7 +147,7 @@ export default function UnsavedChangesBar<T>({
|
|
|
147
147
|
<div className="absolute inset-0 bg-black/10 backdrop-blur-sm" />
|
|
148
148
|
|
|
149
149
|
{/* Main content bar */}
|
|
150
|
-
<div className="
|
|
150
|
+
<div className="relative mx-auto max-w-7xl px-4 py-4 md:px-6 xl:px-8">
|
|
151
151
|
<div
|
|
152
152
|
className={`flex items-center justify-between rounded-lg border px-4 py-3 shadow-lg ${styling.bgColor} ${styling.borderColor}`}
|
|
153
153
|
>
|
|
@@ -19,8 +19,8 @@ export default function APIConfigSection({
|
|
|
19
19
|
const aaiConfigured = status?.aaiAPIKeySet;
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
|
-
<div className="
|
|
23
|
-
<div className="
|
|
22
|
+
<div className="bg-white shadow md:rounded-lg">
|
|
23
|
+
<div className="px-4 py-5 md:p-6">
|
|
24
24
|
<div className="flex items-center justify-between">
|
|
25
25
|
<h3 className="text-base font-bold leading-6 text-gray-900">
|
|
26
26
|
API Configuration
|
|
@@ -20,8 +20,8 @@ export default function AuthConfigSection({
|
|
|
20
20
|
const editorConfigured = status?.editorPasswordSet;
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<div className="
|
|
24
|
-
<div className="
|
|
23
|
+
<div className="bg-white shadow md:rounded-lg">
|
|
24
|
+
<div className="px-4 py-5 md:p-6">
|
|
25
25
|
<h3 className="text-base font-bold leading-6 text-gray-900">
|
|
26
26
|
Authentication Configuration
|
|
27
27
|
</h3>
|
|
@@ -332,7 +332,7 @@ export const ProfileCreate = ({ onSuccess, onError }: ProfileCreateProps) => {
|
|
|
332
332
|
|
|
333
333
|
<Portal>
|
|
334
334
|
<Select.Positioner>
|
|
335
|
-
<Select.Content className="
|
|
335
|
+
<Select.Content className="relative z-10 mt-1 max-h-56 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
336
336
|
{contactPersona.map((item) => (
|
|
337
337
|
<Select.Item
|
|
338
338
|
key={item.id}
|
|
@@ -294,7 +294,7 @@ export const ProfileEdit = ({ onSuccess, onError }: ProfileEditProps) => {
|
|
|
294
294
|
|
|
295
295
|
<Portal>
|
|
296
296
|
<Select.Positioner>
|
|
297
|
-
<Select.Content className="
|
|
297
|
+
<Select.Content className="relative z-10 mt-1 max-h-56 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none md:text-sm">
|
|
298
298
|
{contactPersona.map((item) => (
|
|
299
299
|
<Select.Item
|
|
300
300
|
key={item.id}
|
|
@@ -100,8 +100,8 @@ export default function StoryKeepDashboard_Advanced({
|
|
|
100
100
|
const icon = status?.tursoEnabled ? '☁️' : '📁';
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
|
-
<div className="
|
|
104
|
-
<div className="
|
|
103
|
+
<div className="bg-white shadow md:rounded-lg">
|
|
104
|
+
<div className="px-4 py-5 md:p-6">
|
|
105
105
|
<h3 className="text-base font-bold leading-6 text-gray-900">
|
|
106
106
|
Database Configuration
|
|
107
107
|
</h3>
|
|
@@ -288,7 +288,7 @@ export default function BeliefForm({
|
|
|
288
288
|
onChange={(e) => handleCustomValueChange(e.target.value)}
|
|
289
289
|
onKeyDown={handleKeyDown}
|
|
290
290
|
placeholder="Enter custom value"
|
|
291
|
-
className={`
|
|
291
|
+
className={`block w-full rounded-md border-0 px-3 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset placeholder:text-gray-400 focus:ring-2 focus:ring-inset md:text-sm md:leading-6 ${
|
|
292
292
|
customValueError
|
|
293
293
|
? 'ring-red-500 focus:ring-red-600'
|
|
294
294
|
: 'ring-gray-300 focus:ring-cyan-600'
|
|
@@ -47,7 +47,7 @@ const ContentSummary = ({ fullContentMap }: ContentSummaryProps) => {
|
|
|
47
47
|
<h2 className="mb-4 text-xl font-bold text-gray-900">
|
|
48
48
|
Content Overview
|
|
49
49
|
</h2>
|
|
50
|
-
<div className="
|
|
50
|
+
<div className="grid grid-cols-2 gap-4 md:grid-cols-4 xl:grid-cols-8">
|
|
51
51
|
<div className="text-center">
|
|
52
52
|
<div className="text-2xl font-bold text-cyan-600">
|
|
53
53
|
{contentStats.storyfragments}
|
|
@@ -89,7 +89,7 @@ const ContentSummary = ({ fullContentMap }: ContentSummaryProps) => {
|
|
|
89
89
|
{/* Quick Actions */}
|
|
90
90
|
<div className="rounded-lg bg-white p-6 shadow">
|
|
91
91
|
<h2 className="mb-4 text-xl font-bold text-gray-900">Quick Actions</h2>
|
|
92
|
-
<div className="
|
|
92
|
+
<div className="grid grid-cols-2 gap-4 md:grid-cols-4">
|
|
93
93
|
<a
|
|
94
94
|
href="/create/edit"
|
|
95
95
|
className="rounded-lg border-2 border-dashed border-gray-300 p-4 text-center hover:border-cyan-500 hover:text-cyan-600"
|
|
@@ -195,7 +195,7 @@ const KnownResourceTable = ({
|
|
|
195
195
|
<td className="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
196
196
|
{fieldCount} {fieldCount === 1 ? 'field' : 'fields'}
|
|
197
197
|
</td>
|
|
198
|
-
<td className="
|
|
198
|
+
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-bold md:pr-6">
|
|
199
199
|
<div className="flex items-center justify-end space-x-2">
|
|
200
200
|
{/* Edit button */}
|
|
201
201
|
<button
|
|
@@ -11,6 +11,7 @@ import { getBeliefById } from '@/utils/api/beliefConfig';
|
|
|
11
11
|
import { getResource } from '@/utils/api/resourceConfig';
|
|
12
12
|
import ContentSummary from './ContentSummary';
|
|
13
13
|
import StoryFragmentTable from './StoryFragmentTable';
|
|
14
|
+
import PaneTable from './PaneTable';
|
|
14
15
|
import MenuTable from './MenuTable';
|
|
15
16
|
import MenuForm from './MenuForm';
|
|
16
17
|
import BeliefTable from './BeliefTable';
|
|
@@ -45,7 +46,7 @@ const staticContentManagementTabs: ContentManagementTab[] = [
|
|
|
45
46
|
{ id: 'menus', name: 'Menus' },
|
|
46
47
|
{ id: 'resources', name: 'Resources' },
|
|
47
48
|
{ id: 'beliefs', name: 'Beliefs' },
|
|
48
|
-
|
|
49
|
+
{ id: 'panes', name: 'Panes' },
|
|
49
50
|
//{ id: 'epinets', name: 'Epinets' },
|
|
50
51
|
//{ id: 'files', name: 'Files' },
|
|
51
52
|
];
|
|
@@ -313,11 +314,10 @@ const ManageContent = ({
|
|
|
313
314
|
|
|
314
315
|
case 'panes':
|
|
315
316
|
return (
|
|
316
|
-
<
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
</div>
|
|
317
|
+
<PaneTable
|
|
318
|
+
fullContentMap={currentContentMap}
|
|
319
|
+
onRefresh={refreshData}
|
|
320
|
+
/>
|
|
321
321
|
);
|
|
322
322
|
|
|
323
323
|
case 'menus':
|