@alpaca-editor/core 1.0.3896 → 1.0.3898
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/components/ActionButton.js +2 -2
- package/dist/components/ActionButton.js.map +1 -1
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/button.js.map +1 -1
- package/dist/config/config.js +44 -22
- package/dist/config/config.js.map +1 -1
- package/dist/editor/FieldListField.js +1 -1
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/Titlebar.js +2 -1
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/client/EditorClient.d.ts +27 -2
- package/dist/editor/client/EditorClient.js +140 -1
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +6 -1
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +1 -1
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.js +1 -1
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/control-center/About.d.ts +1 -0
- package/dist/editor/control-center/About.js +8 -0
- package/dist/editor/control-center/About.js.map +1 -0
- package/dist/editor/control-center/ControlCenterMenu.js +3 -0
- package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
- package/dist/editor/control-center/Info.d.ts +1 -0
- package/dist/editor/control-center/Info.js +10 -0
- package/dist/editor/control-center/Info.js.map +1 -0
- package/dist/editor/control-center/QuotaInfo.d.ts +1 -0
- package/dist/editor/control-center/QuotaInfo.js +102 -0
- package/dist/editor/control-center/QuotaInfo.js.map +1 -0
- package/dist/editor/control-center/Status.js +69 -2
- package/dist/editor/control-center/Status.js.map +1 -1
- package/dist/editor/control-center/WebSocketMessages.d.ts +1 -0
- package/dist/editor/control-center/WebSocketMessages.js +66 -0
- package/dist/editor/control-center/WebSocketMessages.js.map +1 -0
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +7 -6
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +7 -1
- package/dist/editor/services/aiService.js +8 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +1 -1
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.js +9 -4
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +19 -1
- package/dist/editor/ui/Icons.js +23 -5
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/SimpleMenu.js +1 -1
- package/dist/editor/ui/SimpleMenu.js.map +1 -1
- package/dist/fonts/index.d.ts +4 -0
- package/dist/fonts/index.js +9 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/images/wizard-bg.png +0 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/WizardBox.d.ts +8 -0
- package/dist/page-wizard/WizardBox.js +6 -0
- package/dist/page-wizard/WizardBox.js.map +1 -0
- package/dist/page-wizard/WizardBoxConnector.d.ts +3 -0
- package/dist/page-wizard/WizardBoxConnector.js +6 -0
- package/dist/page-wizard/WizardBoxConnector.js.map +1 -0
- package/dist/page-wizard/WizardSteps.d.ts +4 -2
- package/dist/page-wizard/WizardSteps.js +44 -18
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/page-wizard/steps/CollectStep.js +16 -21
- package/dist/page-wizard/steps/CollectStep.js.map +1 -1
- package/dist/page-wizard/steps/ComponentTypesSelector.js +50 -45
- package/dist/page-wizard/steps/ComponentTypesSelector.js.map +1 -1
- package/dist/page-wizard/steps/CreatePage.js +6 -3
- package/dist/page-wizard/steps/CreatePage.js.map +1 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +21 -28
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js.map +1 -1
- package/dist/page-wizard/steps/Generate.js +27 -5
- package/dist/page-wizard/steps/Generate.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +46 -44
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +11 -19
- package/dist/page-wizard/steps/SelectStep.js.map +1 -1
- package/dist/page-wizard/steps/usePageCreator.js +41 -12
- package/dist/page-wizard/steps/usePageCreator.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +236 -120
- package/images/wizard-bg.png +0 -0
- package/package.json +1 -1
- package/src/components/ActionButton.tsx +6 -8
- package/src/components/ui/button.tsx +3 -3
- package/src/config/config.tsx +54 -22
- package/src/editor/FieldListField.tsx +2 -2
- package/src/editor/Titlebar.tsx +2 -1
- package/src/editor/client/EditorClient.tsx +192 -9
- package/src/editor/client/editContext.ts +12 -2
- package/src/editor/client/itemsRepository.ts +1 -1
- package/src/editor/client/operations.ts +1 -1
- package/src/editor/control-center/About.tsx +342 -0
- package/src/editor/control-center/ControlCenterMenu.tsx +5 -0
- package/src/editor/control-center/Info.tsx +104 -0
- package/src/editor/control-center/QuotaInfo.tsx +301 -0
- package/src/editor/control-center/Status.tsx +108 -2
- package/src/editor/control-center/WebSocketMessages.tsx +155 -0
- package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +20 -5
- package/src/editor/page-viewer/PageViewer.tsx +1 -1
- package/src/editor/services/aiService.ts +17 -2
- package/src/editor/sidebar/ComponentTree.tsx +1 -1
- package/src/editor/sidebar/ViewSelector.tsx +10 -11
- package/src/editor/ui/Icons.tsx +146 -26
- package/src/editor/ui/SimpleMenu.tsx +1 -1
- package/src/fonts/index.ts +10 -0
- package/src/index.ts +7 -1
- package/src/page-wizard/WizardBox.tsx +40 -0
- package/src/page-wizard/WizardBoxConnector.tsx +21 -0
- package/src/page-wizard/WizardSteps.tsx +236 -116
- package/src/page-wizard/steps/CollectStep.tsx +129 -67
- package/src/page-wizard/steps/ComponentTypesSelector.tsx +32 -11
- package/src/page-wizard/steps/CreatePage.tsx +130 -84
- package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +47 -30
- package/src/page-wizard/steps/Generate.tsx +45 -17
- package/src/page-wizard/steps/ImagesStep.tsx +161 -141
- package/src/page-wizard/steps/SelectStep.tsx +92 -76
- package/src/page-wizard/steps/usePageCreator.ts +40 -14
- package/src/revision.ts +2 -2
- package/styles.css +49 -8
|
@@ -2,7 +2,6 @@ import { StepComponentProps } from "../../config/types";
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { ScrollingContentTree } from "../../editor/ScrollingContentTree";
|
|
4
4
|
import { ItemTreeNodeData } from "../../editor/services/contentService";
|
|
5
|
-
import { Splitter, SplitterPanel } from "../../editor/ui/Splitter";
|
|
6
5
|
import { useEditContext } from "../../editor/client/editContext";
|
|
7
6
|
import { executePrompt, executeSearch } from "../../editor/services/aiService";
|
|
8
7
|
import { createWizardAiContext } from "../service";
|
|
@@ -11,6 +10,10 @@ import { classNames } from "primereact/utils";
|
|
|
11
10
|
import { Button } from "primereact/button";
|
|
12
11
|
import { Dialog } from "primereact/dialog";
|
|
13
12
|
import { FullItem } from "../../editor/pageModel";
|
|
13
|
+
import { WizardBox } from "../WizardBox";
|
|
14
|
+
import { WizardBoxConnector } from "../WizardBoxConnector";
|
|
15
|
+
import { Settings, Images, ChevronDown, Check } from "lucide-react";
|
|
16
|
+
|
|
14
17
|
type Thumbnail = {
|
|
15
18
|
id: string;
|
|
16
19
|
name: string;
|
|
@@ -36,6 +39,9 @@ export const ImagesStep = (props: StepComponentProps) => {
|
|
|
36
39
|
const propName = props.step.propertyName || "images";
|
|
37
40
|
|
|
38
41
|
const [showFolderDialog, setShowFolderDialog] = useState<boolean>(false);
|
|
42
|
+
const [collapsedSections, setCollapsedSections] = useState<Set<number>>(
|
|
43
|
+
new Set(),
|
|
44
|
+
);
|
|
39
45
|
|
|
40
46
|
const [selectedFolder, setSelectedFolder] = useState<FullItem>();
|
|
41
47
|
|
|
@@ -158,160 +164,174 @@ export const ImagesStep = (props: StepComponentProps) => {
|
|
|
158
164
|
loadFolder();
|
|
159
165
|
}, [selectedFolderId]);
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<div className="mb-2 text-sm text-gray-
|
|
173
|
-
|
|
167
|
+
return (
|
|
168
|
+
<div className="flex h-full">
|
|
169
|
+
<WizardBox
|
|
170
|
+
title="Settings"
|
|
171
|
+
icon={<Settings />}
|
|
172
|
+
description="Configure image search settings and find matching images"
|
|
173
|
+
className="w-96"
|
|
174
|
+
>
|
|
175
|
+
<div className="flex h-full flex-col gap-4">
|
|
176
|
+
<div className="flex-1 overflow-y-auto">
|
|
177
|
+
<div className="relative mb-4 rounded-md border border-gray-400 bg-white p-4">
|
|
178
|
+
<div className="mb-2 text-sm font-bold text-gray-800">
|
|
179
|
+
Image library folder
|
|
174
180
|
</div>
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
onClick={() => {
|
|
179
|
-
setShowFolderDialog(true);
|
|
180
|
-
}}
|
|
181
|
-
/>
|
|
182
|
-
<Dialog
|
|
183
|
-
header="Select Folder"
|
|
184
|
-
visible={showFolderDialog}
|
|
185
|
-
onHide={() => {
|
|
186
|
-
setShowFolderDialog(false);
|
|
187
|
-
}}
|
|
188
|
-
style={{ width: "50vw", height: "50vh" }}
|
|
189
|
-
>
|
|
190
|
-
<div className="flex h-full flex-col p-1">
|
|
191
|
-
<div className="relative flex-1">
|
|
192
|
-
<ScrollingContentTree
|
|
193
|
-
rootItemId={mediaRootId}
|
|
194
|
-
onSelectionChange={(selection) => {
|
|
195
|
-
const selectedNode = selection[0] as ItemTreeNodeData;
|
|
196
|
-
if (selectedNode) setSelectedFolderId(selectedNode.id);
|
|
197
|
-
else setSelectedFolderId(mediaRootId);
|
|
198
|
-
setShowFolderDialog(false);
|
|
199
|
-
}}
|
|
200
|
-
/>
|
|
181
|
+
{selectedFolder && (
|
|
182
|
+
<div className="mb-2 text-sm text-gray-500">
|
|
183
|
+
{selectedFolder.path}
|
|
201
184
|
</div>
|
|
202
|
-
|
|
203
|
-
|
|
185
|
+
)}
|
|
186
|
+
<Button
|
|
187
|
+
label="Change Folder"
|
|
188
|
+
onClick={() => {
|
|
189
|
+
setShowFolderDialog(true);
|
|
190
|
+
}}
|
|
191
|
+
/>
|
|
192
|
+
<Dialog
|
|
193
|
+
header="Select Folder"
|
|
194
|
+
visible={showFolderDialog}
|
|
195
|
+
onHide={() => {
|
|
196
|
+
setShowFolderDialog(false);
|
|
197
|
+
}}
|
|
198
|
+
style={{ width: "50vw", height: "50vh" }}
|
|
199
|
+
>
|
|
200
|
+
<div className="flex h-full flex-col p-1">
|
|
201
|
+
<div className="relative flex-1">
|
|
202
|
+
<ScrollingContentTree
|
|
203
|
+
rootItemId={mediaRootId}
|
|
204
|
+
onSelectionChange={(selection) => {
|
|
205
|
+
const selectedNode = selection[0] as ItemTreeNodeData;
|
|
206
|
+
if (selectedNode) setSelectedFolderId(selectedNode.id);
|
|
207
|
+
else setSelectedFolderId(mediaRootId);
|
|
208
|
+
setShowFolderDialog(false);
|
|
209
|
+
}}
|
|
210
|
+
/>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</Dialog>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
<div className="flex-shrink-0">
|
|
217
|
+
<ActionButton
|
|
218
|
+
onClick={findMatchingImages}
|
|
219
|
+
isLoading={isLoading}
|
|
220
|
+
disabled={isLoading}
|
|
221
|
+
loadingText="Searching..."
|
|
222
|
+
className="w-full"
|
|
223
|
+
>
|
|
224
|
+
Find Matching Images
|
|
225
|
+
</ActionButton>
|
|
204
226
|
</div>
|
|
205
|
-
<ActionButton
|
|
206
|
-
onClick={findMatchingImages}
|
|
207
|
-
isLoading={isLoading}
|
|
208
|
-
disabled={isLoading}
|
|
209
|
-
loadingText="Searching..."
|
|
210
|
-
>
|
|
211
|
-
Find Matching Images
|
|
212
|
-
</ActionButton>
|
|
213
227
|
</div>
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
</WizardBox>
|
|
229
|
+
<WizardBoxConnector className="mt-6" />
|
|
230
|
+
<WizardBox
|
|
231
|
+
title="Images"
|
|
232
|
+
icon={<Images />}
|
|
233
|
+
description="Select images from the search results"
|
|
234
|
+
noPadding={true}
|
|
235
|
+
className="relative flex-1"
|
|
236
|
+
>
|
|
220
237
|
<div className="absolute inset-0 overflow-auto">
|
|
221
|
-
<div className="
|
|
222
|
-
<div className="
|
|
223
|
-
{error && <div className="text-red-500">{error}</div>}
|
|
238
|
+
<div className="p-6">
|
|
239
|
+
{error && <div className="mb-4 text-red-500">{error}</div>}
|
|
224
240
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
optionIndex === thumbnailIndex
|
|
260
|
-
? {
|
|
261
|
-
...option,
|
|
262
|
-
selected:
|
|
263
|
-
!option.selected,
|
|
264
|
-
}
|
|
265
|
-
: option,
|
|
266
|
-
),
|
|
267
|
-
}) as Image,
|
|
268
|
-
),
|
|
269
|
-
}));
|
|
270
|
-
}}
|
|
271
|
-
>
|
|
272
|
-
<img
|
|
273
|
-
key={thumbnailIndex}
|
|
274
|
-
src={option.thumbUrl}
|
|
275
|
-
alt={option.name}
|
|
276
|
-
/>
|
|
241
|
+
{props.data[propName]?.length > 0 && (
|
|
242
|
+
<div className="space-y-6">
|
|
243
|
+
{props.data[propName]?.map((image: Image, index: number) => {
|
|
244
|
+
const isCollapsed = collapsedSections.has(index);
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<div key={index} className="space-y-4">
|
|
248
|
+
<button
|
|
249
|
+
onClick={() => {
|
|
250
|
+
const newCollapsed = new Set(collapsedSections);
|
|
251
|
+
if (isCollapsed) {
|
|
252
|
+
newCollapsed.delete(index);
|
|
253
|
+
} else {
|
|
254
|
+
newCollapsed.add(index);
|
|
255
|
+
}
|
|
256
|
+
setCollapsedSections(newCollapsed);
|
|
257
|
+
}}
|
|
258
|
+
className="flex w-full items-center justify-between text-left"
|
|
259
|
+
>
|
|
260
|
+
<h3 className="text-lg font-medium text-gray-900">
|
|
261
|
+
{image.title}
|
|
262
|
+
</h3>
|
|
263
|
+
<ChevronDown
|
|
264
|
+
className={classNames(
|
|
265
|
+
"h-5 w-5 text-gray-500 transition-transform",
|
|
266
|
+
isCollapsed ? "-rotate-90" : "rotate-0",
|
|
267
|
+
)}
|
|
268
|
+
/>
|
|
269
|
+
</button>
|
|
270
|
+
|
|
271
|
+
{!isCollapsed && (
|
|
272
|
+
<div className="grid grid-cols-6 gap-4">
|
|
273
|
+
{image.options?.map(
|
|
274
|
+
(option: Thumbnail, thumbnailIndex: number) => (
|
|
277
275
|
<div
|
|
276
|
+
key={thumbnailIndex}
|
|
278
277
|
className={classNames(
|
|
279
|
-
"
|
|
278
|
+
"relative aspect-square cursor-pointer overflow-hidden rounded-lg border-2 transition-all",
|
|
280
279
|
option.selected
|
|
281
|
-
? "
|
|
282
|
-
: "",
|
|
280
|
+
? "border-purple-500 ring-2 ring-purple-200"
|
|
281
|
+
: "border-gray-200 hover:border-gray-300",
|
|
283
282
|
)}
|
|
283
|
+
onClick={() => {
|
|
284
|
+
props.setData((prevData) => ({
|
|
285
|
+
...prevData,
|
|
286
|
+
[propName]: prevData[propName].map(
|
|
287
|
+
(img: Image, imgIndex: number) =>
|
|
288
|
+
({
|
|
289
|
+
...img,
|
|
290
|
+
options:
|
|
291
|
+
imgIndex !== index
|
|
292
|
+
? img.options
|
|
293
|
+
: img.options?.map(
|
|
294
|
+
(
|
|
295
|
+
option,
|
|
296
|
+
optionIndex: number,
|
|
297
|
+
) =>
|
|
298
|
+
optionIndex ===
|
|
299
|
+
thumbnailIndex
|
|
300
|
+
? {
|
|
301
|
+
...option,
|
|
302
|
+
selected:
|
|
303
|
+
!option.selected,
|
|
304
|
+
}
|
|
305
|
+
: option,
|
|
306
|
+
),
|
|
307
|
+
}) as Image,
|
|
308
|
+
),
|
|
309
|
+
}));
|
|
310
|
+
}}
|
|
284
311
|
>
|
|
312
|
+
<img
|
|
313
|
+
src={option.thumbUrl}
|
|
314
|
+
alt={option.name}
|
|
315
|
+
className="h-full w-full object-cover"
|
|
316
|
+
/>
|
|
285
317
|
{option.selected && (
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
height="24"
|
|
290
|
-
viewBox="0 0 24 24"
|
|
291
|
-
fill="none"
|
|
292
|
-
stroke="currentColor"
|
|
293
|
-
strokeWidth="2"
|
|
294
|
-
strokeLinecap="round"
|
|
295
|
-
strokeLinejoin="round"
|
|
296
|
-
>
|
|
297
|
-
<path d="M20 6 9 17l-5-5"></path>
|
|
298
|
-
</svg>
|
|
318
|
+
<div className="absolute top-2 right-2 flex h-6 w-6 items-center justify-center rounded-full bg-purple-500 text-white">
|
|
319
|
+
<Check className="h-4 w-4" />
|
|
320
|
+
</div>
|
|
299
321
|
)}
|
|
300
322
|
</div>
|
|
301
|
-
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
</
|
|
306
|
-
)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
323
|
+
),
|
|
324
|
+
)}
|
|
325
|
+
</div>
|
|
326
|
+
)}
|
|
327
|
+
</div>
|
|
328
|
+
);
|
|
329
|
+
})}
|
|
330
|
+
</div>
|
|
331
|
+
)}
|
|
310
332
|
</div>
|
|
311
333
|
</div>
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return <Splitter panels={panels} />;
|
|
334
|
+
</WizardBox>
|
|
335
|
+
</div>
|
|
336
|
+
);
|
|
317
337
|
};
|
|
@@ -4,11 +4,14 @@ import { useEditContext } from "../../editor/client/editContext";
|
|
|
4
4
|
import { executePrompt } from "../../editor/services/aiService";
|
|
5
5
|
import { createWizardAiContext } from "../service";
|
|
6
6
|
import { classNames } from "primereact/utils";
|
|
7
|
-
import { Splitter, SplitterPanel } from "../../editor/ui/Splitter";
|
|
8
7
|
import { InputTextarea } from "primereact/inputtextarea";
|
|
9
8
|
import { StepComponentProps } from "../../config/types";
|
|
10
9
|
import { ActionButton } from "../../components/ActionButton";
|
|
11
10
|
import Generate from "./Generate";
|
|
11
|
+
import { WizardBox } from "../WizardBox";
|
|
12
|
+
import { WizardBoxConnector } from "../WizardBoxConnector";
|
|
13
|
+
import { Settings, CheckSquare } from "lucide-react";
|
|
14
|
+
|
|
12
15
|
type Option = {
|
|
13
16
|
title: string;
|
|
14
17
|
description: string;
|
|
@@ -174,82 +177,95 @@ export function SelectStep({
|
|
|
174
177
|
);
|
|
175
178
|
}
|
|
176
179
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
return (
|
|
181
|
+
<div className="flex h-full">
|
|
182
|
+
<WizardBox
|
|
183
|
+
title="Configuration"
|
|
184
|
+
icon={<Settings />}
|
|
185
|
+
description="Configure instructions and regenerate options"
|
|
186
|
+
className="w-96"
|
|
187
|
+
>
|
|
188
|
+
<div className="flex h-full flex-col items-stretch">
|
|
189
|
+
<div className="relative flex-1">
|
|
190
|
+
<div className="absolute inset-0 overflow-y-auto pr-6">
|
|
191
|
+
<h3 className="text-sm font-bold">Instructions</h3>
|
|
192
|
+
<InputTextarea
|
|
193
|
+
className="h-48 w-full text-sm"
|
|
194
|
+
value={instructions}
|
|
195
|
+
onChange={(e) => setInstructions(e.target.value)}
|
|
196
|
+
placeholder="Enter instructions for the options"
|
|
197
|
+
/>
|
|
198
|
+
</div>
|
|
185
199
|
</div>
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return (
|
|
198
|
-
<div
|
|
199
|
-
key={option.id}
|
|
200
|
-
className={classNames(
|
|
201
|
-
"mb-3 flex items-center rounded border-2 bg-white p-3",
|
|
202
|
-
index % 2 === 0
|
|
203
|
-
? "animate-fadeRight"
|
|
204
|
-
: "animate-fadeLeft",
|
|
205
|
-
isSelected
|
|
206
|
-
? "text-canvas-pink border-canvas-pink"
|
|
207
|
-
: "border-gray-300 text-gray-600",
|
|
208
|
-
)}
|
|
209
|
-
onClick={() => handleOptionSelect(option)}
|
|
210
|
-
>
|
|
211
|
-
<div className="flex flex-1 cursor-pointer flex-col">
|
|
212
|
-
<div className="font-medium">{option.title}</div>
|
|
213
|
-
<div className="text-xs text-gray-600">
|
|
214
|
-
{option.description}
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
{isSelected && (
|
|
218
|
-
<div className="text-canvas-pink ml-2">✓</div>
|
|
219
|
-
)}
|
|
220
|
-
</div>
|
|
221
|
-
);
|
|
222
|
-
})
|
|
223
|
-
)}
|
|
200
|
+
<div className="py-2">
|
|
201
|
+
<ActionButton
|
|
202
|
+
onClick={generateOptions}
|
|
203
|
+
isLoading={loading}
|
|
204
|
+
disabled={loading}
|
|
205
|
+
loadingText="Thinking..."
|
|
206
|
+
className="w-full"
|
|
207
|
+
>
|
|
208
|
+
Regenerate Options
|
|
209
|
+
</ActionButton>
|
|
224
210
|
</div>
|
|
225
|
-
|
|
226
|
-
</
|
|
227
|
-
|
|
228
|
-
|
|
211
|
+
</div>
|
|
212
|
+
</WizardBox>
|
|
213
|
+
<WizardBoxConnector className="mt-6" />
|
|
214
|
+
<WizardBox
|
|
215
|
+
title="Select Options"
|
|
216
|
+
icon={<CheckSquare />}
|
|
217
|
+
description="Choose from the generated options below"
|
|
218
|
+
className="flex-1"
|
|
219
|
+
>
|
|
220
|
+
<div className="h-full">
|
|
221
|
+
{loading && (
|
|
222
|
+
<div className="flex h-full items-center justify-center">
|
|
223
|
+
<Generate title="Generating options..." />
|
|
224
|
+
</div>
|
|
225
|
+
)}
|
|
226
|
+
{!loading && (
|
|
227
|
+
<div>
|
|
228
|
+
{options.length === 0 ? (
|
|
229
|
+
<div className="p-4 text-gray-500">
|
|
230
|
+
No options available. Try refreshing the page.
|
|
231
|
+
</div>
|
|
232
|
+
) : (
|
|
233
|
+
options.map((option, index) => {
|
|
234
|
+
const isSelected = selectedOptions.includes(option.id);
|
|
229
235
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
236
|
+
return (
|
|
237
|
+
<div
|
|
238
|
+
key={option.id}
|
|
239
|
+
className={classNames(
|
|
240
|
+
"mb-3 flex items-center rounded border-2 bg-white p-3",
|
|
241
|
+
index % 2 === 0
|
|
242
|
+
? "animate-fadeRight"
|
|
243
|
+
: "animate-fadeLeft",
|
|
244
|
+
isSelected
|
|
245
|
+
? "text-theme-secondary border-theme-secondary"
|
|
246
|
+
: "border-gray-300 text-gray-600",
|
|
247
|
+
)}
|
|
248
|
+
onClick={() => handleOptionSelect(option)}
|
|
249
|
+
>
|
|
250
|
+
<div className="flex flex-1 cursor-pointer flex-col">
|
|
251
|
+
<div className="font-medium">{option.title}</div>
|
|
252
|
+
<div className="text-xs text-gray-600">
|
|
253
|
+
{option.description}
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
{isSelected && (
|
|
257
|
+
<div className="bg-theme-secondary ml-2 flex h-6 w-6 items-center justify-center rounded-full text-white">
|
|
258
|
+
✓
|
|
259
|
+
</div>
|
|
260
|
+
)}
|
|
261
|
+
</div>
|
|
262
|
+
);
|
|
263
|
+
})
|
|
264
|
+
)}
|
|
265
|
+
</div>
|
|
266
|
+
)}
|
|
267
|
+
</div>
|
|
268
|
+
</WizardBox>
|
|
269
|
+
</div>
|
|
270
|
+
);
|
|
255
271
|
}
|
|
@@ -10,8 +10,9 @@ import { useEditContextRef } from "../../editor/client/editContext";
|
|
|
10
10
|
import { useEditContext } from "../../editor/client/editContext";
|
|
11
11
|
import { getComponentById } from "../../editor/componentTreeHelper";
|
|
12
12
|
import { getPlaceholder } from "./schema";
|
|
13
|
-
import { normalizeGuid } from "../../editor/utils";
|
|
13
|
+
import { getItemDescriptor, normalizeGuid } from "../../editor/utils";
|
|
14
14
|
import { ItemDescriptor } from "../../editor/pageModel";
|
|
15
|
+
import { generateImage } from "../../editor/services/aiService";
|
|
15
16
|
|
|
16
17
|
export function usePageCreator(
|
|
17
18
|
pageItem: ItemDescriptor | undefined,
|
|
@@ -169,8 +170,6 @@ export function usePageCreator(
|
|
|
169
170
|
|
|
170
171
|
const { fieldIdsMap, componentMap } = mappings;
|
|
171
172
|
|
|
172
|
-
console.log("Creating components recursively", components);
|
|
173
|
-
|
|
174
173
|
// Process each component in the array
|
|
175
174
|
for (let i = 0; i < components.length; i++) {
|
|
176
175
|
//console.log("Processing component", i);
|
|
@@ -238,18 +237,45 @@ export function usePageCreator(
|
|
|
238
237
|
let value = field.value as any;
|
|
239
238
|
|
|
240
239
|
if (field.type === "Picture") {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
240
|
+
console.log("#### Editing picture field", field);
|
|
241
|
+
if (rawValue.startsWith("generate:")) {
|
|
242
|
+
rawValue = rawValue.slice(9);
|
|
243
|
+
const image = await generateImage({
|
|
244
|
+
...fieldDescriptor,
|
|
245
|
+
prompt: rawValue,
|
|
246
|
+
sessionId: editContext.sessionId,
|
|
247
|
+
pageItem: getItemDescriptor(pageItem),
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
if (rawValue.startsWith("id:")) {
|
|
251
|
+
rawValue = rawValue.slice(3);
|
|
252
|
+
const imageId = rawValue.split(":")[1];
|
|
253
|
+
if (imageId) {
|
|
254
|
+
value = {
|
|
255
|
+
Variants: [{ Name: "Landscape", MediaId: imageId }],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
await editContext.operations.editField({
|
|
259
|
+
field: fieldDescriptor,
|
|
260
|
+
value: value,
|
|
261
|
+
rawValue: value,
|
|
262
|
+
refresh: "none",
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
246
266
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
rawValue
|
|
251
|
-
|
|
252
|
-
|
|
267
|
+
// value = {
|
|
268
|
+
// Variants: [{ Name: "Landscape", MediaId: field.value }],
|
|
269
|
+
// };
|
|
270
|
+
// rawValue = JSON.stringify(value);
|
|
271
|
+
} else {
|
|
272
|
+
await editContext.operations.editField({
|
|
273
|
+
field: fieldDescriptor,
|
|
274
|
+
value: value,
|
|
275
|
+
rawValue: rawValue,
|
|
276
|
+
refresh: "none",
|
|
277
|
+
});
|
|
278
|
+
}
|
|
253
279
|
|
|
254
280
|
setPageModel((prev) => {
|
|
255
281
|
const component = findComponent(prev.components, componentPath);
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-05-
|
|
1
|
+
export const version = "1.0.3898";
|
|
2
|
+
export const buildDate = "2025-05-25 15:23:00";
|