astro-tractstack 2.0.0-rc.8 → 2.0.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/LICENSE +8 -97
- package/README.md +7 -5
- package/bin/create-tractstack.js +35 -11
- package/dist/index.js +106 -29
- package/package.json +10 -5
- package/templates/css/frontend.css +1 -1
- package/templates/custom/minimal/CodeHook.astro +13 -12
- package/templates/custom/minimal/CustomRoutes.astro +25 -31
- package/templates/custom/with-examples/CodeHook.astro +22 -11
- package/templates/custom/with-examples/CustomRoutes.astro +4 -8
- package/templates/custom/with-examples/ProductCard.astro +29 -0
- package/templates/custom/with-examples/ProductCardWrapper.astro +43 -0
- package/templates/custom/with-examples/ProductGrid.astro +64 -0
- package/templates/custom/with-examples/pages/Collections.astro +58 -98
- package/templates/gitignore +42 -0
- package/templates/prettierignore +5 -0
- package/templates/prettierrc +19 -0
- package/templates/src/client/app.js +127 -0
- package/templates/src/client/htmx.min.js +3519 -0
- package/templates/src/client/view.js +429 -0
- package/templates/src/components/Footer.astro +4 -9
- package/templates/src/components/Header.astro +67 -60
- package/templates/src/components/Menu.tsx +188 -52
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +2 -2
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +9 -13
- package/templates/src/components/codehooks/EpinetTableView.tsx +11 -7
- package/templates/src/components/codehooks/EpinetWrapper.tsx +1 -0
- package/templates/src/components/codehooks/FeaturedArticle.astro +105 -0
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +318 -0
- package/templates/src/components/codehooks/ListContent.astro +32 -162
- package/templates/src/components/codehooks/ListContentSetup.tsx +43 -138
- package/templates/src/components/codehooks/ProductCardSetup.tsx +152 -0
- package/templates/src/components/codehooks/ProductGridSetup.tsx +274 -0
- package/templates/src/components/codehooks/SearchWidget.tsx +453 -0
- package/templates/src/components/compositor/Node.tsx +3 -6
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +21 -11
- package/templates/src/components/compositor/elements/BunnyVideo.tsx +21 -20
- package/templates/src/components/compositor/nodes/Pane.tsx +51 -21
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +6 -1
- package/templates/src/components/compositor/nodes/Widget.tsx +16 -2
- package/templates/src/components/compositor/preview/FeaturedArticlePreview.tsx +155 -0
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +20 -1
- package/templates/src/components/edit/Header.tsx +10 -4
- package/templates/src/components/edit/PanelSwitch.tsx +11 -7
- package/templates/src/components/edit/SettingsPanel.tsx +29 -18
- package/templates/src/components/edit/ToolBar.tsx +1 -28
- package/templates/src/components/edit/ToolMode.tsx +45 -32
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +12 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +8 -2
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +1 -1
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +17 -27
- package/templates/src/components/edit/pane/PageGenSelector.tsx +16 -16
- package/templates/src/components/edit/pane/PageGenSpecial.tsx +26 -49
- package/templates/src/components/edit/pane/PageGen_preview.tsx +17 -2
- package/templates/src/components/edit/pane/PanePanel_path.tsx +2 -4
- package/templates/src/components/edit/pane/PanePanel_title.tsx +243 -76
- package/templates/src/components/edit/panels/StyleBreakPanel.tsx +17 -19
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +48 -37
- package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +60 -55
- package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +56 -50
- package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +54 -47
- package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +54 -44
- package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +113 -138
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +54 -40
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +3 -3
- package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +56 -49
- package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +14 -5
- package/templates/src/components/edit/state/SaveModal.tsx +316 -169
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +1 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +56 -55
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +538 -59
- package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +656 -0
- package/templates/src/components/edit/widgets/ToggleWidget.tsx +9 -16
- package/templates/src/components/fields/ArtpackImage.tsx +4 -1
- package/templates/src/components/fields/BackgroundImage.tsx +1 -1
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +127 -35
- package/templates/src/components/fields/ColorPickerCombo.tsx +66 -62
- package/templates/src/components/fields/ImageUpload.tsx +1 -1
- package/templates/src/components/fields/ViewportComboBox.tsx +59 -42
- package/templates/src/components/form/ActionBuilderBeliefSelector.tsx +117 -0
- package/templates/src/components/form/ActionBuilderField.tsx +306 -87
- package/templates/src/components/search/SearchModal.tsx +420 -0
- package/templates/src/components/search/SearchResults.tsx +367 -0
- package/templates/src/components/search/SearchWrapper.tsx +46 -0
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Analytics.tsx +34 -8
- package/templates/src/components/storykeep/Dashboard_Content.tsx +6 -0
- package/templates/src/components/storykeep/StoryKeepBackdrop.astro +87 -0
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +37 -33
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +55 -7
- package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +17 -2
- package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +5 -8
- package/templates/src/components/storykeep/state/FetchAnalytics.tsx +274 -228
- package/templates/src/components/storykeep/widgets/Wizard.tsx +14 -7
- package/templates/src/components/tenant/RegistrationForm.tsx +1 -1
- package/templates/src/components/widgets/ImpressionWrapper.tsx +0 -1
- package/templates/src/constants/shapes.ts +9 -0
- package/templates/src/constants.ts +2121 -16
- package/templates/src/hooks/useSearch.ts +228 -0
- package/templates/src/layouts/Layout.astro +213 -104
- package/templates/src/lib/storyData.ts +4 -1
- package/templates/src/pages/[...slug]/edit.astro +14 -14
- package/templates/src/pages/[...slug].astro +82 -21
- package/templates/src/pages/api/orphan-analysis.ts +0 -1
- package/templates/src/pages/api/tailwind.ts +23 -21
- package/templates/src/pages/context/[...contextSlug]/edit.astro +14 -14
- package/templates/src/pages/context/[...contextSlug].astro +7 -2
- package/templates/src/pages/storykeep/advanced.astro +5 -4
- package/templates/src/pages/storykeep/branding.astro +5 -4
- package/templates/src/pages/storykeep/content.astro +5 -4
- package/templates/src/pages/storykeep/init.astro +40 -1
- package/templates/src/pages/storykeep/login.astro +1 -1
- package/templates/src/pages/storykeep.astro +5 -4
- package/templates/src/stores/nodes.ts +59 -88
- package/templates/src/stores/orphanAnalysis.ts +19 -21
- package/templates/src/stores/storykeep.ts +7 -0
- package/templates/src/types/compositorTypes.ts +6 -0
- package/templates/src/types/tractstack.ts +17 -0
- package/templates/src/utils/actions/lispLexer.ts +2 -2
- package/templates/src/utils/actions/preParse_Action.ts +3 -0
- package/templates/src/utils/api/beliefHelpers.ts +12 -36
- package/templates/src/utils/api/menuHelpers.ts +2 -2
- package/templates/src/utils/api.ts +26 -0
- package/templates/src/utils/compositor/TemplateNodes.ts +7 -0
- package/templates/src/utils/compositor/allowInsert.ts +5 -3
- package/templates/src/utils/compositor/nodesHelper.ts +4 -0
- package/templates/src/utils/compositor/processMarkdown.ts +16 -2
- package/templates/src/utils/compositor/reduceNodesClassNames.ts +4 -0
- package/templates/src/utils/compositor/templateMarkdownStyles.ts +13 -13
- package/templates/src/utils/compositor/typeGuards.ts +1 -0
- package/templates/src/utils/customHelpers.ts +38 -0
- package/templates/src/utils/helpers.ts +2 -2
- package/templates/src/utils/layout.ts +65 -144
- package/utils/inject-files.ts +95 -18
- package/templates/src/client/analytics-events.js +0 -207
- package/templates/src/client/belief-events.js +0 -191
- package/templates/src/client/sse.js +0 -613
- package/templates/src/components/codehooks/FeaturedContent.astro +0 -273
- package/templates/src/components/codehooks/FeaturedContentSetup.tsx +0 -738
- package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +0 -128
- package/templates/src/components/edit/pane/PanePanel_slug.tsx +0 -219
|
@@ -37,16 +37,14 @@ export default function BeliefForm({
|
|
|
37
37
|
onClose,
|
|
38
38
|
}: BeliefFormProps) {
|
|
39
39
|
const [customValue, setCustomValue] = useState('');
|
|
40
|
+
const [customValueError, setCustomValueError] = useState<string | null>(null);
|
|
40
41
|
|
|
41
|
-
// Subscribe to orphan analysis store
|
|
42
42
|
const orphanState = useStore(orphanAnalysisStore);
|
|
43
43
|
|
|
44
|
-
// Load orphan analysis on component mount
|
|
45
44
|
useEffect(() => {
|
|
46
45
|
loadOrphanAnalysis();
|
|
47
46
|
}, []);
|
|
48
47
|
|
|
49
|
-
// Get usage information for this belief
|
|
50
48
|
const getBeliefUsage = (): string[] => {
|
|
51
49
|
if (!belief?.id || !orphanState.data || !orphanState.data.beliefs) {
|
|
52
50
|
return [];
|
|
@@ -54,7 +52,6 @@ export default function BeliefForm({
|
|
|
54
52
|
return orphanState.data.beliefs[belief.id] || [];
|
|
55
53
|
};
|
|
56
54
|
|
|
57
|
-
// Check if belief is in use
|
|
58
55
|
const isBeliefInUse = (): boolean => {
|
|
59
56
|
if (isCreate || !belief?.id) return false;
|
|
60
57
|
return getBeliefUsage().length > 0;
|
|
@@ -63,7 +60,6 @@ export default function BeliefForm({
|
|
|
63
60
|
const beliefInUse = isBeliefInUse();
|
|
64
61
|
const usageCount = getBeliefUsage().length;
|
|
65
62
|
|
|
66
|
-
// Initialize form state
|
|
67
63
|
const initialState: BeliefNodeState = belief
|
|
68
64
|
? convertToLocalState(belief)
|
|
69
65
|
: {
|
|
@@ -85,7 +81,6 @@ export default function BeliefForm({
|
|
|
85
81
|
data
|
|
86
82
|
);
|
|
87
83
|
|
|
88
|
-
// Call success callback after save (original pattern)
|
|
89
84
|
setTimeout(() => {
|
|
90
85
|
onClose?.(true);
|
|
91
86
|
}, 1000);
|
|
@@ -102,23 +97,30 @@ export default function BeliefForm({
|
|
|
102
97
|
},
|
|
103
98
|
});
|
|
104
99
|
|
|
105
|
-
const
|
|
106
|
-
|
|
100
|
+
const handleCustomValueChange = (value: string) => {
|
|
101
|
+
setCustomValue(value);
|
|
102
|
+
const valueRegex = /^[a-zA-Z]([a-zA-Z0-9?!]| (?=[a-zA-Z0-9?!]))*$/;
|
|
103
|
+
if (value && !valueRegex.test(value)) {
|
|
104
|
+
setCustomValueError(
|
|
105
|
+
'Must start with a letter. No double or trailing spaces.'
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
setCustomValueError(null);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
107
111
|
|
|
112
|
+
const handleAddCustomValue = () => {
|
|
113
|
+
if (!customValue.trim() || customValueError) return;
|
|
108
114
|
const newState = addCustomValue(formState.state, customValue);
|
|
109
115
|
formState.updateField('customValues', newState.customValues);
|
|
110
116
|
setCustomValue('');
|
|
111
117
|
};
|
|
112
118
|
|
|
113
119
|
const handleRemoveCustomValue = (index: number) => {
|
|
114
|
-
// Check if this is a newly added value (not saved yet)
|
|
115
120
|
const currentValue = formState.state.customValues[index];
|
|
116
121
|
const originalValues = formState.originalState.customValues || [];
|
|
117
122
|
const isNewValue = !originalValues.includes(currentValue);
|
|
118
123
|
|
|
119
|
-
// Allow removal if:
|
|
120
|
-
// 1. Belief is not in use, OR
|
|
121
|
-
// 2. This is a new value that hasn't been saved yet
|
|
122
124
|
if (!beliefInUse || isNewValue) {
|
|
123
125
|
const newState = removeCustomValue(formState.state, index);
|
|
124
126
|
formState.updateField('customValues', newState.customValues);
|
|
@@ -188,7 +190,6 @@ export default function BeliefForm({
|
|
|
188
190
|
|
|
189
191
|
return (
|
|
190
192
|
<div className="space-y-8">
|
|
191
|
-
{/* Header */}
|
|
192
193
|
<div className="border-b border-gray-200 pb-4">
|
|
193
194
|
<h2 className="text-2xl font-bold text-gray-900">
|
|
194
195
|
{isCreate ? 'Create Belief' : 'Edit Belief'}
|
|
@@ -200,10 +201,8 @@ export default function BeliefForm({
|
|
|
200
201
|
</p>
|
|
201
202
|
</div>
|
|
202
203
|
|
|
203
|
-
{/* Usage Warning */}
|
|
204
204
|
{renderUsageWarning()}
|
|
205
205
|
|
|
206
|
-
{/* Info Box */}
|
|
207
206
|
<div className="rounded-md bg-blue-50 p-4">
|
|
208
207
|
<div className="text-sm text-blue-700">
|
|
209
208
|
<p className="font-bold">What are Beliefs?</p>
|
|
@@ -225,7 +224,6 @@ export default function BeliefForm({
|
|
|
225
224
|
</div>
|
|
226
225
|
</div>
|
|
227
226
|
|
|
228
|
-
{/* Basic Fields */}
|
|
229
227
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
230
228
|
<StringInput
|
|
231
229
|
value={formState.state.title}
|
|
@@ -254,7 +252,6 @@ export default function BeliefForm({
|
|
|
254
252
|
</div>
|
|
255
253
|
</div>
|
|
256
254
|
|
|
257
|
-
{/* Scale Selection */}
|
|
258
255
|
<div className="space-y-4">
|
|
259
256
|
<div className="relative">
|
|
260
257
|
<EnumSelect
|
|
@@ -276,7 +273,6 @@ export default function BeliefForm({
|
|
|
276
273
|
{renderScalePreview()}
|
|
277
274
|
</div>
|
|
278
275
|
|
|
279
|
-
{/* Custom Values Section */}
|
|
280
276
|
{formState.state.scale === 'custom' && (
|
|
281
277
|
<div className="space-y-4">
|
|
282
278
|
<div>
|
|
@@ -286,31 +282,41 @@ export default function BeliefForm({
|
|
|
286
282
|
</p>
|
|
287
283
|
</div>
|
|
288
284
|
|
|
289
|
-
{/* Add Custom Value */}
|
|
290
285
|
<div className="flex gap-2">
|
|
291
286
|
<div className="flex-1">
|
|
292
|
-
<
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
287
|
+
<input
|
|
288
|
+
type="text"
|
|
289
|
+
value={customValue}
|
|
290
|
+
onChange={(e) => handleCustomValueChange(e.target.value)}
|
|
291
|
+
onKeyDown={handleKeyDown}
|
|
292
|
+
placeholder="Enter custom value"
|
|
293
|
+
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 sm:text-sm sm:leading-6 ${
|
|
294
|
+
customValueError
|
|
295
|
+
? 'ring-red-500 focus:ring-red-600'
|
|
296
|
+
: 'ring-gray-300 focus:ring-cyan-600'
|
|
297
|
+
}`}
|
|
298
|
+
/>
|
|
302
299
|
</div>
|
|
303
300
|
<button
|
|
304
301
|
type="button"
|
|
305
302
|
onClick={handleAddCustomValue}
|
|
306
|
-
disabled={!customValue.trim()}
|
|
303
|
+
disabled={!customValue.trim() || !!customValueError}
|
|
307
304
|
className="inline-flex items-center rounded-md bg-cyan-600 px-3 py-2 text-sm font-bold text-white shadow-sm hover:bg-cyan-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cyan-600 disabled:cursor-not-allowed disabled:opacity-50"
|
|
308
305
|
>
|
|
309
306
|
<PlusIcon className="h-4 w-4" />
|
|
310
307
|
</button>
|
|
311
308
|
</div>
|
|
312
309
|
|
|
313
|
-
{
|
|
310
|
+
{customValueError && (
|
|
311
|
+
<p className="mt-1 text-sm text-red-600">{customValueError}</p>
|
|
312
|
+
)}
|
|
313
|
+
|
|
314
|
+
{formState.errors.customValues && (
|
|
315
|
+
<p className="text-sm text-red-600">
|
|
316
|
+
{formState.errors.customValues}
|
|
317
|
+
</p>
|
|
318
|
+
)}
|
|
319
|
+
|
|
314
320
|
{formState.state.customValues.length > 0 && (
|
|
315
321
|
<div className="space-y-2">
|
|
316
322
|
{formState.state.customValues.map((value, index) => {
|
|
@@ -355,7 +361,6 @@ export default function BeliefForm({
|
|
|
355
361
|
</div>
|
|
356
362
|
)}
|
|
357
363
|
|
|
358
|
-
{/* Save/Cancel Bar */}
|
|
359
364
|
<UnsavedChangesBar
|
|
360
365
|
formState={formState}
|
|
361
366
|
message="You have unsaved belief changes"
|
|
@@ -363,7 +368,6 @@ export default function BeliefForm({
|
|
|
363
368
|
cancelLabel="Discard Changes"
|
|
364
369
|
/>
|
|
365
370
|
|
|
366
|
-
{/* Cancel Navigation Button */}
|
|
367
371
|
<div className="flex justify-start">
|
|
368
372
|
<button
|
|
369
373
|
type="button"
|
|
@@ -12,6 +12,8 @@ import StringInput from '@/components/form/StringInput';
|
|
|
12
12
|
import EnumSelect from '@/components/form/EnumSelect';
|
|
13
13
|
import ActionBuilderField from '@/components/form/ActionBuilderField';
|
|
14
14
|
import UnsavedChangesBar from '@/components/form/UnsavedChangesBar';
|
|
15
|
+
import ArrowUpIcon from '@heroicons/react/24/outline/ArrowUpIcon';
|
|
16
|
+
import ArrowDownIcon from '@heroicons/react/24/outline/ArrowDownIcon';
|
|
15
17
|
import type {
|
|
16
18
|
MenuNode,
|
|
17
19
|
MenuNodeState,
|
|
@@ -88,6 +90,26 @@ export default function MenuForm({
|
|
|
88
90
|
formState.updateField('menuLinks', newState.menuLinks);
|
|
89
91
|
};
|
|
90
92
|
|
|
93
|
+
const handleMoveUp = (index: number) => {
|
|
94
|
+
if (index === 0) return;
|
|
95
|
+
const newMenuLinks = [...formState.state.menuLinks];
|
|
96
|
+
[newMenuLinks[index - 1], newMenuLinks[index]] = [
|
|
97
|
+
newMenuLinks[index],
|
|
98
|
+
newMenuLinks[index - 1],
|
|
99
|
+
];
|
|
100
|
+
formState.updateField('menuLinks', newMenuLinks);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const handleMoveDown = (index: number) => {
|
|
104
|
+
if (index === formState.state.menuLinks.length - 1) return;
|
|
105
|
+
const newMenuLinks = [...formState.state.menuLinks];
|
|
106
|
+
[newMenuLinks[index], newMenuLinks[index + 1]] = [
|
|
107
|
+
newMenuLinks[index + 1],
|
|
108
|
+
newMenuLinks[index],
|
|
109
|
+
];
|
|
110
|
+
formState.updateField('menuLinks', newMenuLinks);
|
|
111
|
+
};
|
|
112
|
+
|
|
91
113
|
const handleCancel = () => {
|
|
92
114
|
onClose?.(false);
|
|
93
115
|
};
|
|
@@ -155,13 +177,39 @@ export default function MenuForm({
|
|
|
155
177
|
<h4 className="text-sm font-bold text-gray-900">
|
|
156
178
|
Link {index + 1}
|
|
157
179
|
</h4>
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
180
|
+
<div className="flex items-center gap-2">
|
|
181
|
+
{/* Reorder buttons */}
|
|
182
|
+
<div className="flex items-center gap-1">
|
|
183
|
+
{index > 0 && (
|
|
184
|
+
<button
|
|
185
|
+
type="button"
|
|
186
|
+
onClick={() => handleMoveUp(index)}
|
|
187
|
+
className="rounded p-1 text-gray-600 hover:bg-gray-100 hover:text-gray-900"
|
|
188
|
+
title="Move up"
|
|
189
|
+
>
|
|
190
|
+
<ArrowUpIcon className="h-4 w-4" />
|
|
191
|
+
</button>
|
|
192
|
+
)}
|
|
193
|
+
{index < formState.state.menuLinks.length - 1 && (
|
|
194
|
+
<button
|
|
195
|
+
type="button"
|
|
196
|
+
onClick={() => handleMoveDown(index)}
|
|
197
|
+
className="rounded p-1 text-gray-600 hover:bg-gray-100 hover:text-gray-900"
|
|
198
|
+
title="Move down"
|
|
199
|
+
>
|
|
200
|
+
<ArrowDownIcon className="h-4 w-4" />
|
|
201
|
+
</button>
|
|
202
|
+
)}
|
|
203
|
+
</div>
|
|
204
|
+
{/* Remove button */}
|
|
205
|
+
<button
|
|
206
|
+
type="button"
|
|
207
|
+
onClick={() => handleRemoveLink(index)}
|
|
208
|
+
className="text-sm font-bold text-red-600 hover:text-red-800"
|
|
209
|
+
>
|
|
210
|
+
Remove
|
|
211
|
+
</button>
|
|
212
|
+
</div>
|
|
165
213
|
</div>
|
|
166
214
|
|
|
167
215
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
|
@@ -252,12 +252,26 @@ export default function ResourceForm({
|
|
|
252
252
|
/>
|
|
253
253
|
);
|
|
254
254
|
|
|
255
|
-
case 'image':
|
|
255
|
+
case 'image': {
|
|
256
|
+
let fileUploadValue = ''; // Default to an empty string.
|
|
257
|
+
|
|
258
|
+
if (typeof fieldValue === 'string') {
|
|
259
|
+
// Case 1: The value is a string (Base64 URI).
|
|
260
|
+
fileUploadValue = fieldValue;
|
|
261
|
+
} else if (
|
|
262
|
+
fieldValue &&
|
|
263
|
+
typeof fieldValue === 'object' &&
|
|
264
|
+
fieldValue.src
|
|
265
|
+
) {
|
|
266
|
+
// already saved, url
|
|
267
|
+
fileUploadValue = fieldValue.src;
|
|
268
|
+
}
|
|
269
|
+
|
|
256
270
|
return (
|
|
257
271
|
<FileUpload
|
|
258
272
|
key={fieldName}
|
|
259
273
|
label={fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}
|
|
260
|
-
value={
|
|
274
|
+
value={fileUploadValue}
|
|
261
275
|
onChange={(value) => updateOptionsField(fieldName, value)}
|
|
262
276
|
accept="image/*"
|
|
263
277
|
showPreview={true}
|
|
@@ -265,6 +279,7 @@ export default function ResourceForm({
|
|
|
265
279
|
required={!fieldDef.optional}
|
|
266
280
|
/>
|
|
267
281
|
);
|
|
282
|
+
}
|
|
268
283
|
|
|
269
284
|
default:
|
|
270
285
|
return (
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
orphanAnalysisStore,
|
|
8
8
|
loadOrphanAnalysis,
|
|
9
9
|
} from '@/stores/orphanAnalysis';
|
|
10
|
+
import { TractStackAPI } from '@/utils/api';
|
|
10
11
|
import UsageCell from '../UsageCell';
|
|
11
12
|
import type { FullContentMapItem } from '@/types/tractstack';
|
|
12
13
|
|
|
@@ -138,17 +139,13 @@ const StoryFragmentTable = ({
|
|
|
138
139
|
|
|
139
140
|
setIsLoading(true);
|
|
140
141
|
try {
|
|
141
|
-
const
|
|
142
|
+
const api = new TractStackAPI(
|
|
143
|
+
window.TRACTSTACK_CONFIG?.tenantId || 'default'
|
|
144
|
+
);
|
|
145
|
+
await api.request(`/api/v1/nodes/storyfragments/${id}`, {
|
|
142
146
|
method: 'DELETE',
|
|
143
|
-
headers: {
|
|
144
|
-
'Content-Type': 'application/json',
|
|
145
|
-
},
|
|
146
147
|
});
|
|
147
148
|
|
|
148
|
-
if (!response.ok) {
|
|
149
|
-
throw new Error('Failed to delete story fragment');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
149
|
// Reload the page to refresh the data
|
|
153
150
|
window.location.reload();
|
|
154
151
|
} catch (error) {
|