@alpaca-editor/core 1.0.3914 → 1.0.3916

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.
Files changed (50) hide show
  1. package/dist/config/config.d.ts +1 -0
  2. package/dist/config/config.js +1 -0
  3. package/dist/config/config.js.map +1 -1
  4. package/dist/config/types.d.ts +2 -2
  5. package/dist/editor/Titlebar.js +5 -1
  6. package/dist/editor/Titlebar.js.map +1 -1
  7. package/dist/editor/client/EditorClient.js +6 -6
  8. package/dist/editor/client/EditorClient.js.map +1 -1
  9. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js +2 -1
  10. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js.map +1 -1
  11. package/dist/page-wizard/PageWizard.d.ts +5 -1
  12. package/dist/page-wizard/PageWizard.js.map +1 -1
  13. package/dist/page-wizard/WizardSteps.js +1 -1
  14. package/dist/page-wizard/WizardSteps.js.map +1 -1
  15. package/dist/page-wizard/steps/CollectStep.js +20 -13
  16. package/dist/page-wizard/steps/CollectStep.js.map +1 -1
  17. package/dist/page-wizard/steps/ComponentTypesSelector.js +2 -2
  18. package/dist/page-wizard/steps/ComponentTypesSelector.js.map +1 -1
  19. package/dist/page-wizard/steps/ContentStep.js +5 -5
  20. package/dist/page-wizard/steps/ContentStep.js.map +1 -1
  21. package/dist/page-wizard/steps/ImagesStep.js +2 -2
  22. package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
  23. package/dist/page-wizard/steps/LayoutStep.js +4 -4
  24. package/dist/page-wizard/steps/LayoutStep.js.map +1 -1
  25. package/dist/page-wizard/steps/MetaDataStep.js +1 -1
  26. package/dist/page-wizard/steps/MetaDataStep.js.map +1 -1
  27. package/dist/page-wizard/steps/SelectStep.js +8 -6
  28. package/dist/page-wizard/steps/SelectStep.js.map +1 -1
  29. package/dist/revision.d.ts +2 -2
  30. package/dist/revision.js +2 -2
  31. package/dist/splash-screen/SplashScreen.js +5 -1
  32. package/dist/splash-screen/SplashScreen.js.map +1 -1
  33. package/dist/styles.css +5 -0
  34. package/package.json +1 -1
  35. package/src/config/config.tsx +1 -0
  36. package/src/config/types.ts +6 -2
  37. package/src/editor/Titlebar.tsx +5 -2
  38. package/src/editor/client/EditorClient.tsx +7 -6
  39. package/src/editor/ui/CopyMoveTargetSelectorDialog.tsx +3 -1
  40. package/src/page-wizard/PageWizard.tsx +3 -1
  41. package/src/page-wizard/WizardSteps.tsx +1 -1
  42. package/src/page-wizard/steps/CollectStep.tsx +37 -12
  43. package/src/page-wizard/steps/ComponentTypesSelector.tsx +2 -2
  44. package/src/page-wizard/steps/ContentStep.tsx +5 -5
  45. package/src/page-wizard/steps/ImagesStep.tsx +2 -2
  46. package/src/page-wizard/steps/LayoutStep.tsx +4 -4
  47. package/src/page-wizard/steps/MetaDataStep.tsx +1 -1
  48. package/src/page-wizard/steps/SelectStep.tsx +21 -11
  49. package/src/revision.ts +2 -2
  50. package/src/splash-screen/SplashScreen.tsx +19 -0
@@ -129,6 +129,7 @@ const defaultRichTextEditorProfile: RichTextEditorProfile = {
129
129
 
130
130
  export const contentItemId = "0DE95AE4-41AB-4D01-9EB0-67441B7C2450";
131
131
  export const templatesRootItemId = "3c1715fe-6a13-4fcf-845f-de308ba9741d";
132
+ export const rootItemId = "11111111-1111-1111-1111-111111111111";
132
133
 
133
134
  const openTargetActionButton: ClientFieldButton = {
134
135
  label: "Open target item",
@@ -16,7 +16,11 @@ import {
16
16
  LocalizeItemCommand,
17
17
  } from "../editor/commands/itemCommands";
18
18
  import { User } from "../types";
19
- import { WizardData, WizardPageModel } from "../page-wizard/PageWizard";
19
+ import {
20
+ WizardData,
21
+ WizardPageModel,
22
+ WizardStep,
23
+ } from "../page-wizard/PageWizard";
20
24
  import { Wizard } from "../page-wizard/PageWizard";
21
25
 
22
26
  export type RichTextEditorProfile = {
@@ -266,7 +270,7 @@ export type TranslationStatus = {
266
270
  };
267
271
 
268
272
  export interface StepComponentProps {
269
- step: any;
273
+ step: WizardStep;
270
274
 
271
275
  data: WizardData;
272
276
  setData: React.Dispatch<React.SetStateAction<WizardData>>;
@@ -46,8 +46,11 @@ export function Titlebar() {
46
46
  <div className="z-1 flex min-h-11 items-center justify-between gap-1 bg-gradient-to-r from-gray-900 from-10% to-indigo-950">
47
47
  <div className="relative flex items-center justify-center gap-2 pl-2 font-bold text-white">
48
48
  <a
49
- href="/sitecore/shell/sitecore/client/Applications/Launchpad"
50
- className="glow-text flex items-center"
49
+ //href="/sitecore/shell/sitecore/client/Applications/Launchpad"
50
+ onClick={() => {
51
+ editContext.switchView("splash-screen");
52
+ }}
53
+ className="glow-text flex cursor-pointer items-center"
51
54
  >
52
55
  <Logo className="h-6 w-6" />
53
56
  <span className="ml-2 font-mono">{title}</span>
@@ -402,7 +402,9 @@ export function EditorClient({
402
402
  if (socket.readyState !== WebSocket.OPEN) {
403
403
  const url = "/alpaca/editor/client";
404
404
  await post(url, clientInfoMessage);
405
- } else socket.send(JSON.stringify(clientInfoMessage));
405
+ } else {
406
+ socket.send(JSON.stringify(clientInfoMessage));
407
+ }
406
408
  };
407
409
 
408
410
  const startTour = () => {
@@ -740,9 +742,9 @@ export function EditorClient({
740
742
  ? parseInt(searchParams.get("version")!)
741
743
  : 0);
742
744
 
743
- if (itemid && viewName === "splash-screen") {
744
- setViewName("page-editor");
745
- }
745
+ // if (itemid && viewName === "splash-screen") {
746
+ // setViewName("page-editor");
747
+ // }
746
748
 
747
749
  if (!itemId || !language) return;
748
750
 
@@ -788,7 +790,7 @@ export function EditorClient({
788
790
 
789
791
  useEffect(() => {
790
792
  sendClientInfo();
791
- }, [currentItemRef.current]);
793
+ }, [currentItemDescriptor]);
792
794
 
793
795
  const loadComments = useCallback(async () => {
794
796
  if (!currentItemDescriptor) return;
@@ -2043,7 +2045,6 @@ export function EditorClient({
2043
2045
  timings,
2044
2046
  startTour,
2045
2047
  viewName,
2046
- setViewName,
2047
2048
  compareMode,
2048
2049
  setCompareMode,
2049
2050
  addSocketMessageListener,
@@ -1,6 +1,6 @@
1
1
  import { Button } from "primereact/button";
2
2
 
3
- import { useEffect, useState } from "react";
3
+ import { useState } from "react";
4
4
 
5
5
  import { FullItem, ItemDescriptor } from "../pageModel";
6
6
  import { Dialog } from "primereact/dialog";
@@ -8,6 +8,7 @@ import DialogButtons from "./DialogButtons";
8
8
  import { DialogProps } from "../client/editContext";
9
9
  import { ScrollingContentTree } from "../ScrollingContentTree";
10
10
  import { EditContextType } from "../client/editContext";
11
+ import { rootItemId } from "../../config/config";
11
12
 
12
13
  export type CopyMoveTargetSelectorDialogProps = {
13
14
  items: FullItem[];
@@ -46,6 +47,7 @@ export function CopyMoveTargetSelectorDialog(
46
47
  <ScrollingContentTree
47
48
  selectedItemId={selectedItem?.id}
48
49
  expandedItemId={props.items[0]?.id}
50
+ rootItemId={rootItemId}
49
51
  onSelectionChange={(node) => {
50
52
  if (!props.items[0]) return;
51
53
  if (!node[0]) setSelectedItem(null);
@@ -50,7 +50,9 @@ export type WizardStep = {
50
50
  id: string;
51
51
  name: string;
52
52
  description: string;
53
- [property: string]: string;
53
+ type: string;
54
+ fields: { [key: string]: string };
55
+ children?: WizardStep[];
54
56
  };
55
57
 
56
58
  export type WizardData = {
@@ -356,7 +356,7 @@ export function WizardSteps({ wizard, parentItem }: WizardStepsProps) {
356
356
  if (StepComponent) {
357
357
  return (
358
358
  <StepComponent
359
- step={wizard.steps[currentStepIndex]}
359
+ step={step}
360
360
  data={data}
361
361
  setData={setData}
362
362
  setPageModel={setPageModel}
@@ -1,13 +1,13 @@
1
1
  import { InputText } from "primereact/inputtext";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import { WizardData } from "../PageWizard";
4
- import { Splitter, SplitterPanel } from "../../editor/ui/Splitter";
5
- import MDEditor from "@uiw/react-md-editor";
4
+
6
5
  import { StepComponentProps } from "../../config/types";
7
6
  import { ActionButton } from "../../components/ActionButton";
8
7
  import { UploadIcon, DocumentIcon } from "../../editor/ui/Icons";
9
8
  import { Spinner } from "../../editor/ui/Spinner";
10
9
  import { Card } from "../../components/ui/card";
10
+ import { Button } from "../../components/ui/button";
11
11
  import { LinkIcon } from "lucide-react";
12
12
  import { InputTextarea } from "primereact/inputtextarea";
13
13
 
@@ -25,22 +25,24 @@ export function CollectStep({
25
25
  const fileInputRef = useRef<HTMLInputElement>(null);
26
26
 
27
27
  // Extract configuration from step
28
- const enableUpload = step?.enableUpload === "1";
29
- const enableScrape = step?.enableScrape === "1";
30
- const enableText = step?.enableText === "1";
28
+ const enableUpload = step?.fields.enableUpload === "1";
29
+ const enableScrape = step?.fields.enableScrape === "1";
30
+ const enableText = step?.fields.enableText === "1";
31
31
 
32
- const uploadTitle = step?.uploadTitle || "Upload a file (optional)";
32
+ const uploadTitle = step?.fields.uploadTitle || "Upload a file (optional)";
33
33
  const uploadDescription =
34
- step?.uploadDescription || "Upload a file to the page";
34
+ step?.fields.uploadDescription || "Upload a file to the page";
35
35
 
36
- const scrapeTitle = step?.scrapeTitle || "Scrape page from URL (optional)";
36
+ const scrapeTitle =
37
+ step?.fields.scrapeTitle || "Scrape page from URL (optional)";
37
38
  const scrapeDescription =
38
- step?.scrapeDescription ||
39
+ step?.fields.scrapeDescription ||
39
40
  "Only scrape websites you have permission to access. You are responsible for complying with the website's terms of service and all applicable laws.";
40
41
 
41
- const textTitle = step?.textTitle || "Text";
42
+ const textTitle = step?.fields.textTitle || "Text";
42
43
  const textDescription =
43
- step?.textDescription || "Provide the text you want to use for the page";
44
+ step?.fields.textDescription ||
45
+ "Provide the text you want to use for the page";
44
46
 
45
47
  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
46
48
  e.preventDefault();
@@ -256,7 +258,7 @@ export function CollectStep({
256
258
  className={`${!enableUpload && !enableScrape ? "md:col-span-2" : enableUpload && enableScrape ? "md:col-span-2" : ""}`}
257
259
  >
258
260
  <InputTextarea
259
- className="max-h-full w-full"
261
+ className="border-theme-secondary max-h-full w-full text-sm"
260
262
  value={data.htmlContent}
261
263
  rows={20}
262
264
  onChange={(e) =>
@@ -266,6 +268,29 @@ export function CollectStep({
266
268
  }))
267
269
  }
268
270
  />
271
+ {step.children && step.children.length > 0 && (
272
+ <div>
273
+ <div className="mt-2 mb-1 text-sm font-semibold">
274
+ Use example prompts:
275
+ </div>
276
+ <div className="flex gap-2">
277
+ {step.children.map((child) => (
278
+ <Button
279
+ variant="outline"
280
+ key={child.id}
281
+ onClick={() => {
282
+ setData((prev: WizardData) => ({
283
+ ...prev,
284
+ htmlContent: child.fields.text,
285
+ }));
286
+ }}
287
+ >
288
+ {child.fields.title}
289
+ </Button>
290
+ ))}
291
+ </div>
292
+ </div>
293
+ )}
269
294
  </Card>
270
295
  )}
271
296
  </div>
@@ -216,9 +216,9 @@ export function ComponentTypeSelector({
216
216
 
217
217
  // Parse preselected components from step if available
218
218
  let stepPreselectedTypes: string[] = [];
219
- if (step["preselectedComponents"]) {
219
+ if (step.fields["preselectedComponents"]) {
220
220
  // Split by comma or newline and trim whitespace
221
- stepPreselectedTypes = step["preselectedComponents"]
221
+ stepPreselectedTypes = step.fields["preselectedComponents"]
222
222
  .split(/[,\n\r]+/)
223
223
  .map((type: string) => type.trim())
224
224
  .filter((type: string) => type && uniqueTypes.includes(type)); // Only include valid types
@@ -191,7 +191,7 @@ export function ContentStep({
191
191
  if (!internalState.layoutInstructions) {
192
192
  setInternalState({
193
193
  ...internalState,
194
- layoutInstructions: step.instructions,
194
+ layoutInstructions: step.fields.instructions,
195
195
  });
196
196
  }
197
197
 
@@ -242,8 +242,8 @@ export function ContentStep({
242
242
  ) {
243
243
  // Parse preselected components from step if available
244
244
  let stepPreselectedTypes: string[] = [];
245
- if (step["preselectedComponents"]) {
246
- stepPreselectedTypes = step["preselectedComponents"]
245
+ if (step.fields["preselectedComponents"]) {
246
+ stepPreselectedTypes = step.fields["preselectedComponents"]
247
247
  .split(/[,\n\r]+/)
248
248
  .map((type: string) => type.trim())
249
249
  .filter((type: string) => type && uniqueTypes.includes(type));
@@ -289,7 +289,7 @@ export function ContentStep({
289
289
 
290
290
  const generatePageName = async () => {
291
291
  const metaInstructions =
292
- step["Instructions for generating item name and meta fields"];
292
+ step.fields["Instructions for generating item name and meta fields"];
293
293
 
294
294
  setIsGenerating(true);
295
295
 
@@ -519,7 +519,7 @@ export function ContentStep({
519
519
  createWizardAiContext,
520
520
  { allowedFunctions: [] },
521
521
  { signal: localAbortController.signal },
522
- step.aiModel || "gpt-4.1",
522
+ step.fields.aiModel || "gpt-4.1",
523
523
  (response) => {
524
524
  try {
525
525
  const newLayout = JSON.parse(response.content) as WizardPageModel;
@@ -74,7 +74,7 @@ export const ImagesStep = (props: StepComponentProps) => {
74
74
 
75
75
  const editContext = useEditContext();
76
76
 
77
- const propName = props.step.propertyName || "images";
77
+ const propName = props.step.fields.propertyName || "images";
78
78
 
79
79
  const [showFolderDialog, setShowFolderDialog] = useState<boolean>(false);
80
80
  const [collapsedSections, setCollapsedSections] = useState<Set<number>>(
@@ -106,7 +106,7 @@ export const ImagesStep = (props: StepComponentProps) => {
106
106
  Please anaylze the provided data and suggest a number of images and specific keywords per image. The keywords will be used to find matching images in the image library.
107
107
  Response JSON format: { images: Image[] } type Image = { title: string, keywords: string[] }
108
108
  Input data: ${JSON.stringify(props.data)}
109
- Instructions: ${props.step.instructions}`,
109
+ Instructions: ${props.step.fields.instructions}`,
110
110
 
111
111
  name: "system",
112
112
  role: "system",
@@ -44,7 +44,7 @@ export function LayoutStep({
44
44
  }, [data.pageModel, isLoading]);
45
45
 
46
46
  useEffect(() => {
47
- setCustomInstructions(step.instructions);
47
+ setCustomInstructions(step.fields.instructions);
48
48
  }, []);
49
49
 
50
50
  const createLayout = async () => {
@@ -133,10 +133,10 @@ export function LayoutStep({
133
133
  if (!selectedComponentTypes.length) return;
134
134
 
135
135
  // Only set custom instructions if they're not already set or if step.instructions has changed
136
- if (customInstructions !== step.instructions) {
137
- setCustomInstructions(step.instructions);
136
+ if (customInstructions !== step.fields.instructions) {
137
+ setCustomInstructions(step.fields.instructions);
138
138
  }
139
- }, [step.instructions, selectedComponentTypes]);
139
+ }, [step.fields.instructions, selectedComponentTypes]);
140
140
 
141
141
  // Custom instructions panel
142
142
  const customInstructionsPanel = () => {
@@ -50,7 +50,7 @@ export function MetaDataStep({
50
50
 
51
51
  const generateMetaFields = async () => {
52
52
  const metaInstructions =
53
- step["Instructions for generating item name and meta fields"];
53
+ step.fields["Instructions for generating item name and meta fields"];
54
54
 
55
55
  setIsGenerating(true);
56
56
 
@@ -35,10 +35,10 @@ export function SelectStep({
35
35
  const [loading, setLoading] = useState(false);
36
36
  const [error, setError] = useState<string | null>(null);
37
37
  const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
38
- const [instructions, setInstructions] = useState(step.instructions);
38
+ const [instructions, setInstructions] = useState(step.fields.instructions);
39
39
 
40
40
  // Get the property name from the step or use "choice" as default
41
- const propertyName = step.propertyName || "selectedOptions";
41
+ const propertyName = step.fields.propertyName || "selectedOptions";
42
42
 
43
43
  useEffect(() => {
44
44
  if (data[propertyName]?.length) {
@@ -64,7 +64,7 @@ export function SelectStep({
64
64
 
65
65
  try {
66
66
  // Create a prompt based on step instructions and data
67
- const prompt = `${instructions}\n\nCurrent data: ${JSON.stringify(
67
+ const prompt = `${step.fields.systemInstructions}\n${instructions}\n\nCurrent data: ${JSON.stringify(
68
68
  data,
69
69
  null,
70
70
  2,
@@ -91,7 +91,7 @@ export function SelectStep({
91
91
  createWizardAiContext,
92
92
  { allowedFunctions: [] },
93
93
  undefined,
94
- step.aiModel || "gpt-4.1",
94
+ step.fields.aiModel || "gpt-4.1",
95
95
  );
96
96
 
97
97
  // Parse the result and set options
@@ -131,7 +131,7 @@ export function SelectStep({
131
131
  return;
132
132
  }
133
133
  generateOptions();
134
- }, [step.instructions, internalState]);
134
+ }, [step.fields.instructions, internalState]);
135
135
 
136
136
  // Sync data[propertyName] with selectedOptions state
137
137
  useEffect(() => {
@@ -180,9 +180,12 @@ export function SelectStep({
180
180
  return (
181
181
  <div className="flex h-full flex-col md:flex-row">
182
182
  <WizardBox
183
- title="Configuration"
183
+ title={step.fields.configureTitle || "Configuration"}
184
184
  icon={<Settings />}
185
- description="Configure instructions and regenerate options"
185
+ description={
186
+ step.fields.configureDescription ||
187
+ "Configure instructions and regenerate options"
188
+ }
186
189
  className="md:w-96"
187
190
  >
188
191
  <div className="flex h-full flex-col items-stretch">
@@ -193,7 +196,7 @@ export function SelectStep({
193
196
  className="h-48 w-full text-sm"
194
197
  value={instructions}
195
198
  onChange={(e) => setInstructions(e.target.value)}
196
- placeholder="Enter instructions for the options"
199
+ placeholder="Enter instructions for generating the options"
197
200
  />
198
201
  </div>
199
202
  </div>
@@ -212,15 +215,22 @@ export function SelectStep({
212
215
  </WizardBox>
213
216
  <WizardBoxConnector />
214
217
  <WizardBox
215
- title="Select Options"
218
+ title={step.fields.selectOptionsTitle || "Select Options"}
216
219
  icon={<CheckSquare />}
217
- description="Choose from the generated options below"
220
+ description={
221
+ step.fields.selectOptionsDescription ||
222
+ "Choose from the generated options below"
223
+ }
218
224
  className="flex-1"
219
225
  >
220
226
  <div className="h-full">
221
227
  {loading && (
222
228
  <div className="flex h-full items-center justify-center">
223
- <Generate title="Generating options..." />
229
+ <Generate
230
+ title={
231
+ step.fields.generatingOptionsText || "Generating options..."
232
+ }
233
+ />
224
234
  </div>
225
235
  )}
226
236
  {!loading && (
package/src/revision.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = "1.0.3914";
2
- export const buildDate = "2025-06-02 01:46:23";
1
+ export const version = "1.0.3916";
2
+ export const buildDate = "2025-06-02 14:37:59";
@@ -134,6 +134,25 @@ export function SplashScreen() {
134
134
  <ActionButton onClick={() => editContext?.startTour()}>
135
135
  Take tour <MagicEditIcon />
136
136
  </ActionButton>
137
+ <ActionButton
138
+ onClick={() => {
139
+ window.open(
140
+ "/sitecore/shell/sitecore/client/Applications/Launchpad",
141
+ "_blank",
142
+ );
143
+ }}
144
+ >
145
+ Open Sitecore Launchpad
146
+ </ActionButton>
147
+
148
+ <ActionButton
149
+ className="mt-6 md:mt-18"
150
+ onClick={() => {
151
+ editContext?.switchView("page-editor");
152
+ }}
153
+ >
154
+ Return to editor
155
+ </ActionButton>
137
156
  </div>
138
157
  </div>
139
158
  </Card>