@alpaca-editor/core 1.0.4190 → 1.0.4191
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/agents-view/AgentCard.js +1 -1
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentsView.js +5 -7
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/config/config.js +14 -7
- package/dist/config/config.js.map +1 -1
- package/dist/editor/ItemInfo.js +3 -3
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/QuickItemSwitcher.js +1 -1
- package/dist/editor/QuickItemSwitcher.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.d.ts +1 -7
- package/dist/editor/ai/AgentTerminal.js +382 -256
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/Agents.js +84 -198
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +1 -3
- package/dist/editor/ai/AiResponseMessage.js +12 -63
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +1 -2
- package/dist/editor/ai/ToolCallDisplay.js +5 -13
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/client/EditorShell.js +5 -6
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +4 -6
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +0 -2
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/control-center/About.js +1 -1
- package/dist/editor/control-center/About.js.map +1 -1
- package/dist/editor/control-center/AllAgentsPanel.js +1 -1
- package/dist/editor/field-types/MultiLineText.js +1 -1
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +0 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +1 -1
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/PageWizard.js +3 -3
- package/dist/page-wizard/PageWizard.js.map +1 -1
- package/dist/page-wizard/WizardSteps.js +1 -1
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/OpenPage.js +6 -10
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +2 -2
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +1 -1
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +12 -241
- package/package.json +1 -1
- package/src/agents-view/AgentCard.tsx +6 -1
- package/src/agents-view/AgentsView.tsx +30 -18
- package/src/config/config.tsx +17 -8
- package/src/editor/ItemInfo.tsx +2 -3
- package/src/editor/QuickItemSwitcher.tsx +1 -1
- package/src/editor/ai/AgentTerminal.tsx +649 -544
- package/src/editor/ai/Agents.tsx +250 -464
- package/src/editor/ai/AiResponseMessage.tsx +29 -154
- package/src/editor/ai/ToolCallDisplay.tsx +4 -18
- package/src/editor/client/EditorShell.tsx +6 -9
- package/src/editor/client/hooks/useSocketMessageHandler.ts +7 -6
- package/src/editor/commands/componentCommands.tsx +0 -1
- package/src/editor/control-center/About.tsx +2 -2
- package/src/editor/control-center/AllAgentsPanel.tsx +1 -1
- package/src/editor/field-types/MultiLineText.tsx +1 -1
- package/src/editor/services/aiService.ts +0 -2
- package/src/editor/sidebar/Validation.tsx +1 -1
- package/src/index.ts +0 -5
- package/src/page-wizard/PageWizard.tsx +3 -3
- package/src/page-wizard/WizardSteps.tsx +1 -1
- package/src/revision.ts +2 -2
- package/src/splash-screen/OpenPage.tsx +4 -12
- package/src/splash-screen/RecentPages.tsx +61 -58
- package/src/splash-screen/SplashScreen.tsx +1 -1
- package/styles.css +0 -20
- package/dist/components/ui/PlaceholderInput.d.ts +0 -41
- package/dist/components/ui/PlaceholderInput.js +0 -160
- package/dist/components/ui/PlaceholderInput.js.map +0 -1
- package/dist/components/ui/PlaceholderInputTypes.d.ts +0 -41
- package/dist/components/ui/PlaceholderInputTypes.js +0 -48
- package/dist/components/ui/PlaceholderInputTypes.js.map +0 -1
- package/dist/components/ui/PlaceholderItemSelector.d.ts +0 -7
- package/dist/components/ui/PlaceholderItemSelector.js +0 -154
- package/dist/components/ui/PlaceholderItemSelector.js.map +0 -1
- package/dist/splash-screen/ModernSplashScreen.d.ts +0 -8
- package/dist/splash-screen/ModernSplashScreen.js +0 -36
- package/dist/splash-screen/ModernSplashScreen.js.map +0 -1
- package/dist/splash-screen/ParheliaAssistantChat.d.ts +0 -8
- package/dist/splash-screen/ParheliaAssistantChat.js +0 -155
- package/dist/splash-screen/ParheliaAssistantChat.js.map +0 -1
- package/dist/splash-screen/RecentAgents.d.ts +0 -7
- package/dist/splash-screen/RecentAgents.js +0 -76
- package/dist/splash-screen/RecentAgents.js.map +0 -1
- package/src/components/ui/PlaceholderInput.tsx +0 -290
- package/src/components/ui/PlaceholderInputTypes.tsx +0 -97
- package/src/components/ui/PlaceholderItemSelector.tsx +0 -253
- package/src/splash-screen/ModernSplashScreen.tsx +0 -158
- package/src/splash-screen/ParheliaAssistantChat.tsx +0 -273
- package/src/splash-screen/RecentAgents.tsx +0 -151
|
@@ -46,7 +46,7 @@ export function RecentPages() {
|
|
|
46
46
|
editContext.switchView(
|
|
47
47
|
editContext.contentEditorItem?.hasLayout
|
|
48
48
|
? "page-editor"
|
|
49
|
-
: "content-
|
|
49
|
+
: "content-editor",
|
|
50
50
|
);
|
|
51
51
|
});
|
|
52
52
|
}
|
|
@@ -54,69 +54,72 @@ export function RecentPages() {
|
|
|
54
54
|
|
|
55
55
|
return (
|
|
56
56
|
<Card
|
|
57
|
-
collapsible="no"
|
|
58
|
-
defaultCollapsed="no"
|
|
59
57
|
icon={<History className="h-4 w-4" />}
|
|
60
58
|
title="Recent Pages/Items"
|
|
61
59
|
description="Quick access to your recently viewed pages"
|
|
60
|
+
className="flex h-full flex-col"
|
|
62
61
|
>
|
|
63
|
-
|
|
64
|
-
<div className="
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
className="flex-shrink-0"
|
|
92
|
-
/>
|
|
93
|
-
)} */}
|
|
94
|
-
<div className="min-w-0 flex-1 pl-1">
|
|
95
|
-
<div className="font-medium text-gray-900">
|
|
96
|
-
{page.name}
|
|
97
|
-
</div>
|
|
98
|
-
<div className="break-all text-xs text-gray-500">
|
|
99
|
-
{page.path}
|
|
62
|
+
<div className="relative flex min-h-0 flex-1 flex-col">
|
|
63
|
+
<div className="absolute inset-0 overflow-auto">
|
|
64
|
+
<table className="w-full text-xs">
|
|
65
|
+
<tbody>
|
|
66
|
+
{history?.map((page, index) => (
|
|
67
|
+
<tr
|
|
68
|
+
key={page.id || index}
|
|
69
|
+
onClick={() => handlePageLoad(page)}
|
|
70
|
+
className="cursor-pointer border-b border-gray-100 hover:bg-gray-50"
|
|
71
|
+
>
|
|
72
|
+
<td className="px-1.5 py-3">
|
|
73
|
+
<div className="flex items-center gap-2">
|
|
74
|
+
{/* {page.icon && (
|
|
75
|
+
<img
|
|
76
|
+
src={page.icon}
|
|
77
|
+
width="16"
|
|
78
|
+
height="16"
|
|
79
|
+
alt=""
|
|
80
|
+
className="flex-shrink-0"
|
|
81
|
+
/>
|
|
82
|
+
)} */}
|
|
83
|
+
<div className="min-w-0 flex-1 pl-1">
|
|
84
|
+
<div className="font-medium text-gray-900">
|
|
85
|
+
{page.name}
|
|
86
|
+
</div>
|
|
87
|
+
<div className="text-xs break-all text-gray-500">
|
|
88
|
+
{page.path}
|
|
89
|
+
</div>
|
|
100
90
|
</div>
|
|
101
91
|
</div>
|
|
102
|
-
</
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
</
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
</
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
</
|
|
118
|
-
|
|
119
|
-
|
|
92
|
+
</td>
|
|
93
|
+
<td className="hidden p-3 text-gray-700 md:table-cell">
|
|
94
|
+
<div className="truncate">{page.templateName || "—"}</div>
|
|
95
|
+
</td>
|
|
96
|
+
<td className="p-3">
|
|
97
|
+
<span className="inline-flex items-center truncate rounded-full bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
|
|
98
|
+
{page.workflowState || "Draft"}
|
|
99
|
+
</span>
|
|
100
|
+
</td>
|
|
101
|
+
<td className="hidden p-3 text-gray-700 md:table-cell">
|
|
102
|
+
{page.versions || 0}
|
|
103
|
+
</td>
|
|
104
|
+
</tr>
|
|
105
|
+
))}
|
|
106
|
+
</tbody>
|
|
107
|
+
</table>
|
|
108
|
+
{isLoading && (
|
|
109
|
+
<div className="flex h-full flex-col items-center justify-center p-6 text-center">
|
|
110
|
+
<Loader2 className="h-5 w-5 animate-spin text-gray-400" />
|
|
111
|
+
<div className="mt-2 text-xs text-gray-500">
|
|
112
|
+
Loading recent pages...
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
)}
|
|
116
|
+
{!isLoading && (!history || history.length === 0) && (
|
|
117
|
+
<div className="p-6 text-center text-xs text-gray-500">
|
|
118
|
+
No recent pages found
|
|
119
|
+
</div>
|
|
120
|
+
)}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
120
123
|
</Card>
|
|
121
124
|
);
|
|
122
125
|
}
|
|
@@ -174,7 +174,7 @@ export function SplashScreen() {
|
|
|
174
174
|
title=<span className="tracking-wides text-2xl font-extralight">
|
|
175
175
|
parhelia
|
|
176
176
|
</span>
|
|
177
|
-
description="
|
|
177
|
+
description="The easiest way to create and manage your content"
|
|
178
178
|
icon={<AnimatedSunIcon />}
|
|
179
179
|
className="flex-1"
|
|
180
180
|
>
|
package/styles.css
CHANGED
|
@@ -1064,23 +1064,3 @@ body {
|
|
|
1064
1064
|
[data-side="right"].slide-in-from-left-2 {
|
|
1065
1065
|
animation-name: slide-in-from-left;
|
|
1066
1066
|
}
|
|
1067
|
-
|
|
1068
|
-
/* ViewTransition animations for Parhelia Assistant Chat */
|
|
1069
|
-
::view-transition-old(.slide-fade-in) {
|
|
1070
|
-
animation: 200ms cubic-bezier(0.4, 0, 0.2, 1) both fade-out;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
::view-transition-new(.slide-fade-in) {
|
|
1074
|
-
animation: 400ms cubic-bezier(0.4, 0, 0.2, 1) both slide-fade-in-animation;
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
@keyframes slide-fade-in-animation {
|
|
1078
|
-
from {
|
|
1079
|
-
opacity: 0;
|
|
1080
|
-
transform: translateY(20px);
|
|
1081
|
-
}
|
|
1082
|
-
to {
|
|
1083
|
-
opacity: 1;
|
|
1084
|
-
transform: translateY(0);
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PlaceholderInput component for AI Agent quick actions.
|
|
3
|
-
*
|
|
4
|
-
* Allows users to fill in placeholders in text templates with tab navigation.
|
|
5
|
-
*
|
|
6
|
-
* Example usage for AI Agents:
|
|
7
|
-
* ```json
|
|
8
|
-
* {
|
|
9
|
-
* "label": "Create Component",
|
|
10
|
-
* "prompt": "Create a {component_type} component named {component_name}",
|
|
11
|
-
* "behavior": "submit"
|
|
12
|
-
* }
|
|
13
|
-
* ```
|
|
14
|
-
*
|
|
15
|
-
* Supported placeholder formats:
|
|
16
|
-
* - Curly braces: {placeholder_name} or {0}, {1}, {2}
|
|
17
|
-
* - Angle brackets: <placeholder_name> or <0>, <1>, <2>
|
|
18
|
-
*
|
|
19
|
-
* Keyboard navigation:
|
|
20
|
-
* - Tab: Move to next placeholder (wraps to first)
|
|
21
|
-
* - Shift+Tab: Move to previous placeholder (wraps to last)
|
|
22
|
-
* - Enter: Submit with filled values
|
|
23
|
-
* - Escape: Cancel
|
|
24
|
-
*/
|
|
25
|
-
export type Placeholder = {
|
|
26
|
-
name: string;
|
|
27
|
-
type: string;
|
|
28
|
-
parameters: Record<string, string>;
|
|
29
|
-
index: number;
|
|
30
|
-
startPos: number;
|
|
31
|
-
endPos: number;
|
|
32
|
-
};
|
|
33
|
-
type PlaceholderInputProps = {
|
|
34
|
-
text: string;
|
|
35
|
-
onComplete: (filledText: string) => void;
|
|
36
|
-
onCancel?: () => void;
|
|
37
|
-
className?: string;
|
|
38
|
-
showButtons?: boolean;
|
|
39
|
-
};
|
|
40
|
-
export declare function PlaceholderInput({ text, onComplete, onCancel, className, showButtons, }: PlaceholderInputProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
-
export {};
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
import { Button } from "./button";
|
|
5
|
-
import { X } from "lucide-react";
|
|
6
|
-
import { placeholderInputTypeRegistry } from "./PlaceholderInputTypes";
|
|
7
|
-
function parsePlaceholders(text) {
|
|
8
|
-
const placeholders = [];
|
|
9
|
-
// Match both {placeholder} and <placeholder> formats
|
|
10
|
-
const regex = /\{([^}]+)\}|<([^>]+)>/g;
|
|
11
|
-
let match;
|
|
12
|
-
let index = 0;
|
|
13
|
-
while ((match = regex.exec(text)) !== null) {
|
|
14
|
-
// match[1] is for {placeholder}, match[2] is for <placeholder>
|
|
15
|
-
const placeholderContent = match[1] || match[2];
|
|
16
|
-
if (placeholderContent) {
|
|
17
|
-
// Parse the content: {label|type|param=value|param2=value2}
|
|
18
|
-
const parts = placeholderContent.split("|");
|
|
19
|
-
const label = parts[0]?.trim() || "";
|
|
20
|
-
const type = parts[1]?.trim() || "text"; // Default to "text" type
|
|
21
|
-
// Parse parameters from remaining parts (format: key=value)
|
|
22
|
-
const parameters = {};
|
|
23
|
-
for (let i = 2; i < parts.length; i++) {
|
|
24
|
-
const part = parts[i]?.trim() || "";
|
|
25
|
-
if (!part)
|
|
26
|
-
continue;
|
|
27
|
-
const eqIndex = part.indexOf("=");
|
|
28
|
-
if (eqIndex !== -1) {
|
|
29
|
-
const key = part.substring(0, eqIndex).trim();
|
|
30
|
-
const value = part.substring(eqIndex + 1).trim();
|
|
31
|
-
if (key) {
|
|
32
|
-
parameters[key] = value;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
placeholders.push({
|
|
37
|
-
name: label,
|
|
38
|
-
type,
|
|
39
|
-
parameters,
|
|
40
|
-
index: index++,
|
|
41
|
-
startPos: match.index,
|
|
42
|
-
endPos: match.index + match[0].length,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return placeholders;
|
|
47
|
-
}
|
|
48
|
-
export function PlaceholderInput({ text, onComplete, onCancel, className, showButtons = true, }) {
|
|
49
|
-
const placeholders = React.useMemo(() => parsePlaceholders(text), [text]);
|
|
50
|
-
const [values, setValues] = React.useState({});
|
|
51
|
-
// Create refs for each placeholder using useRef to avoid the null issue
|
|
52
|
-
const inputRefs = React.useRef({});
|
|
53
|
-
// Auto-focus first placeholder on mount
|
|
54
|
-
React.useEffect(() => {
|
|
55
|
-
if (placeholders.length > 0) {
|
|
56
|
-
const firstInput = inputRefs.current[0];
|
|
57
|
-
if (firstInput) {
|
|
58
|
-
setTimeout(() => firstInput.focus(), 0);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}, [placeholders.length]);
|
|
62
|
-
const handleValueChange = (index, value) => {
|
|
63
|
-
setValues((prev) => ({ ...prev, [index]: value }));
|
|
64
|
-
};
|
|
65
|
-
const handleKeyDown = (e, index) => {
|
|
66
|
-
if (e.key === "Tab") {
|
|
67
|
-
e.preventDefault();
|
|
68
|
-
if (e.shiftKey) {
|
|
69
|
-
// Shift+Tab: go to previous input (wrap to last if at first)
|
|
70
|
-
const prevIndex = index - 1;
|
|
71
|
-
if (prevIndex >= 0) {
|
|
72
|
-
inputRefs.current[prevIndex]?.focus();
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
// Wrap to last placeholder
|
|
76
|
-
inputRefs.current[placeholders.length - 1]?.focus();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
// Tab: go to next input (wrap to first if at last)
|
|
81
|
-
const nextIndex = index + 1;
|
|
82
|
-
if (nextIndex < placeholders.length) {
|
|
83
|
-
inputRefs.current[nextIndex]?.focus();
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
// Wrap to first placeholder
|
|
87
|
-
inputRefs.current[0]?.focus();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else if (e.key === "Enter") {
|
|
92
|
-
e.preventDefault();
|
|
93
|
-
handleSubmit();
|
|
94
|
-
}
|
|
95
|
-
else if (e.key === "Escape") {
|
|
96
|
-
e.preventDefault();
|
|
97
|
-
onCancel?.();
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
const handleSubmit = () => {
|
|
101
|
-
// Build the filled text by replacing placeholders with values
|
|
102
|
-
let filledText = text;
|
|
103
|
-
// Replace in reverse order to maintain correct positions
|
|
104
|
-
for (let i = placeholders.length - 1; i >= 0; i--) {
|
|
105
|
-
const placeholder = placeholders[i];
|
|
106
|
-
if (!placeholder)
|
|
107
|
-
continue;
|
|
108
|
-
const value = values[i] || "";
|
|
109
|
-
// Format the value based on placeholder type and parameters
|
|
110
|
-
let formattedValue = value;
|
|
111
|
-
if (placeholder.type === "item" && value.includes("|")) {
|
|
112
|
-
// Parse item value format: "id|path"
|
|
113
|
-
const parts = value.split("|");
|
|
114
|
-
const id = parts[0] || "";
|
|
115
|
-
const path = parts[1] || "";
|
|
116
|
-
const name = path.split("/").pop() || "";
|
|
117
|
-
// For item placeholders, output both ID and name
|
|
118
|
-
formattedValue = `{${id}} (${name})`;
|
|
119
|
-
}
|
|
120
|
-
filledText =
|
|
121
|
-
filledText.substring(0, placeholder.startPos) +
|
|
122
|
-
formattedValue +
|
|
123
|
-
filledText.substring(placeholder.endPos);
|
|
124
|
-
}
|
|
125
|
-
onComplete(filledText);
|
|
126
|
-
};
|
|
127
|
-
if (placeholders.length === 0) {
|
|
128
|
-
// No placeholders, just display text
|
|
129
|
-
return _jsx("div", { className: cn("text-xs", className), children: text });
|
|
130
|
-
}
|
|
131
|
-
// Build segments: text and placeholder inputs
|
|
132
|
-
const segments = [];
|
|
133
|
-
let lastPos = 0;
|
|
134
|
-
placeholders.forEach((placeholder, idx) => {
|
|
135
|
-
// Add text before this placeholder
|
|
136
|
-
if (placeholder.startPos > lastPos) {
|
|
137
|
-
segments.push(_jsx("span", { className: "whitespace-pre-wrap", children: text.substring(lastPos, placeholder.startPos) }, `text-${idx}`));
|
|
138
|
-
}
|
|
139
|
-
// Add input for this placeholder
|
|
140
|
-
// Look up the component for this placeholder type
|
|
141
|
-
const typeConfig = placeholderInputTypeRegistry.get(placeholder.type);
|
|
142
|
-
const InputComponent = typeConfig?.component;
|
|
143
|
-
if (InputComponent) {
|
|
144
|
-
segments.push(_jsx(InputComponent, { placeholder: placeholder, value: values[idx] || "", onChange: (value) => handleValueChange(idx, value), onKeyDown: (e) => handleKeyDown(e, idx), inputRef: (el) => {
|
|
145
|
-
inputRefs.current[idx] = el;
|
|
146
|
-
}, autoFocus: idx === 0 }, `input-${idx}`));
|
|
147
|
-
}
|
|
148
|
-
lastPos = placeholder.endPos;
|
|
149
|
-
});
|
|
150
|
-
// Add remaining text after last placeholder
|
|
151
|
-
if (lastPos < text.length) {
|
|
152
|
-
segments.push(_jsx("span", { className: "whitespace-pre-wrap", children: text.substring(lastPos) }, "text-end"));
|
|
153
|
-
}
|
|
154
|
-
const allFilled = placeholders.every((_, idx) => {
|
|
155
|
-
const value = values[idx];
|
|
156
|
-
return value !== undefined && value.trim() !== "";
|
|
157
|
-
});
|
|
158
|
-
return (_jsxs("div", { className: cn("space-y-2", className), children: [_jsxs("div", { className: cn("relative flex flex-wrap items-center gap-1 rounded-lg border border-blue-200 bg-blue-50/50 p-3 text-xs h-[80px] overflow-y-auto", onCancel && "pr-8"), children: [segments, onCancel && (_jsx("button", { onClick: onCancel, className: "absolute right-2 top-2 rounded p-0.5 text-gray-400 hover:bg-blue-100 hover:text-gray-600 transition-colors", title: "Cancel (Esc)", "aria-label": "Cancel", children: _jsx(X, { size: 14, strokeWidth: 2 }) }))] }), showButtons && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { size: "sm", onClick: handleSubmit, disabled: !allFilled, className: "h-7", children: "Submit" }), onCancel && (_jsx(Button, { size: "sm", variant: "ghost", onClick: onCancel, className: "h-7", children: "Cancel" })), !allFilled && (_jsx("span", { className: "text-xs text-gray-500", children: "Fill all fields (use Tab to navigate)" }))] }))] }));
|
|
159
|
-
}
|
|
160
|
-
//# sourceMappingURL=PlaceholderInput.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PlaceholderInput.js","sourceRoot":"","sources":["../../../src/components/ui/PlaceholderInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { Placeholder } from "./PlaceholderInput";
|
|
3
|
-
/**
|
|
4
|
-
* Props interface that all placeholder input type components must implement
|
|
5
|
-
*/
|
|
6
|
-
export interface PlaceholderInputComponentProps {
|
|
7
|
-
placeholder: Placeholder;
|
|
8
|
-
value: string;
|
|
9
|
-
onChange: (value: string) => void;
|
|
10
|
-
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
11
|
-
inputRef: React.Ref<HTMLInputElement | HTMLTextAreaElement>;
|
|
12
|
-
autoFocus?: boolean;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Configuration for a placeholder input type
|
|
16
|
-
*/
|
|
17
|
-
export interface PlaceholderInputTypeConfig {
|
|
18
|
-
type: string;
|
|
19
|
-
component: React.ComponentType<PlaceholderInputComponentProps>;
|
|
20
|
-
validator?: (value: string) => boolean;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Registry for placeholder input types
|
|
24
|
-
*/
|
|
25
|
-
declare class PlaceholderInputTypeRegistry {
|
|
26
|
-
private types;
|
|
27
|
-
/**
|
|
28
|
-
* Register a new placeholder input type
|
|
29
|
-
*/
|
|
30
|
-
register(config: PlaceholderInputTypeConfig): void;
|
|
31
|
-
/**
|
|
32
|
-
* Get a registered placeholder input type configuration
|
|
33
|
-
*/
|
|
34
|
-
get(type: string): PlaceholderInputTypeConfig | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* Check if a type is registered
|
|
37
|
-
*/
|
|
38
|
-
has(type: string): boolean;
|
|
39
|
-
}
|
|
40
|
-
export declare const placeholderInputTypeRegistry: PlaceholderInputTypeRegistry;
|
|
41
|
-
export {};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Registry for placeholder input types
|
|
4
|
-
*/
|
|
5
|
-
class PlaceholderInputTypeRegistry {
|
|
6
|
-
types = new Map();
|
|
7
|
-
/**
|
|
8
|
-
* Register a new placeholder input type
|
|
9
|
-
*/
|
|
10
|
-
register(config) {
|
|
11
|
-
this.types.set(config.type.toLowerCase(), config);
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Get a registered placeholder input type configuration
|
|
15
|
-
*/
|
|
16
|
-
get(type) {
|
|
17
|
-
return this.types.get(type.toLowerCase());
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Check if a type is registered
|
|
21
|
-
*/
|
|
22
|
-
has(type) {
|
|
23
|
-
return this.types.has(type.toLowerCase());
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
// Create singleton instance
|
|
27
|
-
export const placeholderInputTypeRegistry = new PlaceholderInputTypeRegistry();
|
|
28
|
-
/**
|
|
29
|
-
* Default text input component for placeholders
|
|
30
|
-
*/
|
|
31
|
-
const TextInput = ({ placeholder, value, onChange, onKeyDown, inputRef, autoFocus, }) => {
|
|
32
|
-
return (_jsx("input", { ref: inputRef, type: "text", value: value, onChange: (e) => onChange(e.target.value), onKeyDown: onKeyDown, placeholder: placeholder.name, autoFocus: autoFocus, className: "inline-flex min-w-[80px] max-w-[200px] rounded border border-blue-400 bg-blue-50 px-2 py-0.5 text-xs outline-none transition-all focus:border-blue-600 focus:bg-blue-100 focus:ring-2 focus:ring-blue-500/30 placeholder:text-blue-400", style: {
|
|
33
|
-
width: `${Math.max(80, (value?.length || placeholder.name.length) * 7 + 20)}px`,
|
|
34
|
-
} }));
|
|
35
|
-
};
|
|
36
|
-
// Register default text type
|
|
37
|
-
placeholderInputTypeRegistry.register({
|
|
38
|
-
type: "text",
|
|
39
|
-
component: TextInput,
|
|
40
|
-
});
|
|
41
|
-
// Import and register item selector (dynamic import to avoid circular dependencies)
|
|
42
|
-
import("./PlaceholderItemSelector").then((module) => {
|
|
43
|
-
placeholderInputTypeRegistry.register({
|
|
44
|
-
type: "item",
|
|
45
|
-
component: module.PlaceholderItemSelector,
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
//# sourceMappingURL=PlaceholderInputTypes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PlaceholderInputTypes.js","sourceRoot":"","sources":["../../../src/components/ui/PlaceholderInputTypes.tsx"],"names":[],"mappings":";AAwBA;;GAEG;AACH,MAAM,4BAA4B;IACxB,KAAK,GAA4C,IAAI,GAAG,EAAE,CAAC;IAEnE;;OAEG;IACH,QAAQ,CAAC,MAAkC;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,4BAA4B,EAAE,CAAC;AAE/E;;GAEG;AACH,MAAM,SAAS,GAA6C,CAAC,EAC3D,WAAW,EACX,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,SAAS,GACV,EAAE,EAAE;IACH,OAAO,CACL,gBACE,GAAG,EAAE,QAAuC,EAC5C,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,CAAC,IAAI,EAC7B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAC,wOAAwO,EAClP,KAAK,EAAE;YACL,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI;SAChF,GACD,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,6BAA6B;AAC7B,4BAA4B,CAAC,QAAQ,CAAC;IACpC,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,SAAS;CACrB,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;IAClD,4BAA4B,CAAC,QAAQ,CAAC;QACpC,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,MAAM,CAAC,uBAAuB;KAC1C,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { PlaceholderInputComponentProps } from "./PlaceholderInputTypes";
|
|
3
|
-
/**
|
|
4
|
-
* Item selector component for placeholder inputs
|
|
5
|
-
* Allows selecting a Sitecore item via search or tree browsing
|
|
6
|
-
*/
|
|
7
|
-
export declare const PlaceholderItemSelector: React.FC<PlaceholderInputComponentProps>;
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
import { Popover, PopoverContent, PopoverTrigger } from "./popover";
|
|
5
|
-
import { ItemSearch } from "../../editor/ui/ItemSearch";
|
|
6
|
-
import ContentTree from "../../editor/ContentTree";
|
|
7
|
-
import { useEditContext } from "../../editor/client/editContext";
|
|
8
|
-
import { X, ChevronDown } from "lucide-react";
|
|
9
|
-
import { Splitter } from "../../editor/ui/Splitter";
|
|
10
|
-
/**
|
|
11
|
-
* Item selector component for placeholder inputs
|
|
12
|
-
* Allows selecting a Sitecore item via search or tree browsing
|
|
13
|
-
*/
|
|
14
|
-
export const PlaceholderItemSelector = ({ placeholder, value, onChange, onKeyDown, inputRef, autoFocus, }) => {
|
|
15
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
|
16
|
-
const [selectedItem, setSelectedItem] = React.useState(null);
|
|
17
|
-
const [rootItemId, setRootItemId] = React.useState(null);
|
|
18
|
-
const [isLoadingRoot, setIsLoadingRoot] = React.useState(false);
|
|
19
|
-
const editContext = useEditContext();
|
|
20
|
-
// Parse root parameter from placeholder.parameters
|
|
21
|
-
const rootPathOrId = placeholder.parameters.root || "/sitecore/content";
|
|
22
|
-
// Helper to check if a string is a GUID
|
|
23
|
-
const isGuid = (str) => {
|
|
24
|
-
const guidPattern = /^[{]?[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}[}]?$/;
|
|
25
|
-
return guidPattern.test(str);
|
|
26
|
-
};
|
|
27
|
-
// Resolve root path/ID to an item ID on mount
|
|
28
|
-
React.useEffect(() => {
|
|
29
|
-
const resolveRootItem = async () => {
|
|
30
|
-
if (!editContext)
|
|
31
|
-
return;
|
|
32
|
-
// If it's already a GUID, use it directly
|
|
33
|
-
if (isGuid(rootPathOrId)) {
|
|
34
|
-
setRootItemId(rootPathOrId.replace(/[{}]/g, ""));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Otherwise, resolve the path to an ID
|
|
38
|
-
setIsLoadingRoot(true);
|
|
39
|
-
try {
|
|
40
|
-
const item = await editContext.itemsRepository.getItem({
|
|
41
|
-
id: rootPathOrId, // Try as ID first
|
|
42
|
-
language: "en",
|
|
43
|
-
version: 0,
|
|
44
|
-
});
|
|
45
|
-
if (item?.id) {
|
|
46
|
-
setRootItemId(item.id);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
// If not found by ID, it might be a path - we need to search for it
|
|
50
|
-
console.error("Could not resolve root item:", rootPathOrId);
|
|
51
|
-
// Fallback to Sitecore content root
|
|
52
|
-
setRootItemId("0DE95AE4-41AB-4D01-9EB0-67441B7C2450");
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error("Error resolving root item:", error);
|
|
57
|
-
// Fallback to Sitecore content root
|
|
58
|
-
setRootItemId("0DE95AE4-41AB-4D01-9EB0-67441B7C2450");
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
setIsLoadingRoot(false);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
resolveRootItem();
|
|
65
|
-
}, [editContext, rootPathOrId]);
|
|
66
|
-
const loadItemByIdOrPath = React.useCallback(async (idOrPath) => {
|
|
67
|
-
if (!editContext)
|
|
68
|
-
return;
|
|
69
|
-
try {
|
|
70
|
-
const item = await editContext.itemsRepository.getItem({
|
|
71
|
-
id: idOrPath,
|
|
72
|
-
language: "en",
|
|
73
|
-
version: 0,
|
|
74
|
-
});
|
|
75
|
-
if (item) {
|
|
76
|
-
setSelectedItem({
|
|
77
|
-
id: item.id,
|
|
78
|
-
path: item.path || item.name,
|
|
79
|
-
name: item.name,
|
|
80
|
-
language: "en",
|
|
81
|
-
icon: item.icon,
|
|
82
|
-
});
|
|
83
|
-
const newValue = `${item.id}|${item.path || item.name}`;
|
|
84
|
-
onChange(newValue);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
console.error("Failed to load item:", error);
|
|
89
|
-
}
|
|
90
|
-
}, [editContext, onChange]);
|
|
91
|
-
// Parse existing value (format: "id|path")
|
|
92
|
-
React.useEffect(() => {
|
|
93
|
-
if (!value || !editContext)
|
|
94
|
-
return;
|
|
95
|
-
if (value.includes("|")) {
|
|
96
|
-
const [id, path] = value.split("|");
|
|
97
|
-
const name = path?.split("/").pop() || "";
|
|
98
|
-
setSelectedItem({ id: id || "", path: path || "", name, language: "en" });
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
// Try to load item by ID or path
|
|
102
|
-
loadItemByIdOrPath(value);
|
|
103
|
-
}
|
|
104
|
-
}, [value, editContext, loadItemByIdOrPath]);
|
|
105
|
-
const handleItemSelected = (item) => {
|
|
106
|
-
const resultItem = {
|
|
107
|
-
id: item.id,
|
|
108
|
-
name: item.name || "",
|
|
109
|
-
path: item.path || "",
|
|
110
|
-
language: item.language || "en",
|
|
111
|
-
icon: item.icon,
|
|
112
|
-
idPath: item.idPath,
|
|
113
|
-
};
|
|
114
|
-
setSelectedItem(resultItem);
|
|
115
|
-
const newValue = `${resultItem.id}|${resultItem.path}`;
|
|
116
|
-
onChange(newValue);
|
|
117
|
-
setIsOpen(false);
|
|
118
|
-
};
|
|
119
|
-
const handleClear = (e) => {
|
|
120
|
-
e.stopPropagation();
|
|
121
|
-
setSelectedItem(null);
|
|
122
|
-
onChange("");
|
|
123
|
-
};
|
|
124
|
-
const displayValue = selectedItem ? selectedItem.path : "";
|
|
125
|
-
// Don't render until root is resolved
|
|
126
|
-
if (isLoadingRoot || !rootItemId) {
|
|
127
|
-
return (_jsx("div", { ref: inputRef, className: "inline-flex min-w-[150px] max-w-[300px] items-center gap-1 rounded border border-gray-300 bg-gray-50 px-2 py-0.5 text-xs", children: _jsx("span", { className: "flex-1 text-gray-400", children: "Loading..." }) }));
|
|
128
|
-
}
|
|
129
|
-
return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { ref: inputRef, tabIndex: 0, onKeyDown: onKeyDown, className: cn("inline-flex min-w-[150px] max-w-[300px] cursor-pointer items-center gap-1 rounded border border-blue-400 bg-blue-50 px-2 py-0.5 text-xs outline-none transition-all", "hover:border-blue-500 hover:bg-blue-100", "focus:border-blue-600 focus:bg-blue-100 focus:ring-2 focus:ring-blue-500/30"), children: selectedItem ? (_jsxs(_Fragment, { children: [selectedItem.icon && (_jsx("img", { src: selectedItem.icon, alt: "", className: "h-3 w-3 flex-shrink-0" })), _jsx("span", { className: "flex-1 truncate", children: displayValue }), _jsx("button", { onClick: handleClear, className: "rounded p-0.5 hover:bg-blue-200", title: "Clear selection", children: _jsx(X, { size: 12 }) })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "flex-1 text-blue-400", children: placeholder.name }), _jsx(ChevronDown, { size: 12, className: "text-blue-400" })] })) }) }), _jsx(PopoverContent, { className: "w-[700px] p-0", align: "start", onOpenAutoFocus: (e) => e.preventDefault(), children: _jsx("div", { className: "flex h-[450px]", children: _jsx(Splitter, { direction: "horizontal", localStorageKey: "placeholder-item-selector-split", panels: [
|
|
130
|
-
{
|
|
131
|
-
name: "tree",
|
|
132
|
-
defaultSize: 300,
|
|
133
|
-
content: (_jsx("div", { className: "h-full overflow-auto border-r border-gray-200 p-2", children: _jsx(ContentTree, { rootItemIds: [rootItemId], selectionMode: "single", selectedItemIds: selectedItem ? [selectedItem.id] : [], onSelectionChange: (selection) => {
|
|
134
|
-
const node = selection[0];
|
|
135
|
-
if (node) {
|
|
136
|
-
handleItemSelected({
|
|
137
|
-
id: node.id,
|
|
138
|
-
name: node.name,
|
|
139
|
-
path: node.path || node.name,
|
|
140
|
-
language: "en",
|
|
141
|
-
version: 0,
|
|
142
|
-
icon: node.icon,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}, language: "en" }) })),
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
name: "search",
|
|
149
|
-
defaultSize: "auto",
|
|
150
|
-
content: (_jsx("div", { className: "flex h-full flex-col p-4", children: _jsx(ItemSearch, { rootItemIds: rootItemId ? [rootItemId] : undefined, itemSelected: handleItemSelected, language: "en", autoFocus: true }) })),
|
|
151
|
-
},
|
|
152
|
-
] }) }) })] }));
|
|
153
|
-
};
|
|
154
|
-
//# sourceMappingURL=PlaceholderItemSelector.js.map
|