@auto-wiz/ui 1.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.
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface FlowControlsProps {
|
|
2
|
+
recording: boolean;
|
|
3
|
+
pickerOn: boolean;
|
|
4
|
+
isRunning: boolean;
|
|
5
|
+
hasSteps: boolean;
|
|
6
|
+
onTogglePicker: () => void;
|
|
7
|
+
onStartRecording: () => void;
|
|
8
|
+
onStopRecording: () => void;
|
|
9
|
+
onRun: () => void;
|
|
10
|
+
onStop: () => void;
|
|
11
|
+
onClear: () => void;
|
|
12
|
+
onUndo: () => void;
|
|
13
|
+
onSendToBackend: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Flow 제어 버튼들을 표시하는 컴포넌트
|
|
17
|
+
*/
|
|
18
|
+
export declare function FlowControls({ recording, pickerOn, isRunning, hasSteps, onTogglePicker, onStartRecording, onStopRecording, onRun, onStop, onClear, onUndo, onSendToBackend, }: FlowControlsProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Target, Circle, Square, Play, Pause, Undo, Trash2, Send, } from "lucide-react";
|
|
3
|
+
/**
|
|
4
|
+
* Flow 제어 버튼들을 표시하는 컴포넌트
|
|
5
|
+
*/
|
|
6
|
+
export function FlowControls({ recording, pickerOn, isRunning, hasSteps, onTogglePicker, onStartRecording, onStopRecording, onRun, onStop, onClear, onUndo, onSendToBackend, }) {
|
|
7
|
+
return (_jsxs("div", { style: {
|
|
8
|
+
padding: "20px",
|
|
9
|
+
background: "#ffffff",
|
|
10
|
+
borderBottom: "1px solid #e5e5e5",
|
|
11
|
+
}, children: [_jsxs("div", { style: { display: "flex", gap: "10px", marginBottom: "12px" }, children: [_jsxs("button", { onClick: onTogglePicker, style: {
|
|
12
|
+
flex: 1,
|
|
13
|
+
padding: "11px 16px",
|
|
14
|
+
background: pickerOn ? "#1a1a1a" : "#f5f5f5",
|
|
15
|
+
color: pickerOn ? "#ffffff" : "#404040",
|
|
16
|
+
border: "1px solid #e5e5e5",
|
|
17
|
+
borderRadius: "8px",
|
|
18
|
+
cursor: "pointer",
|
|
19
|
+
fontSize: "13px",
|
|
20
|
+
fontWeight: 500,
|
|
21
|
+
boxShadow: "none",
|
|
22
|
+
letterSpacing: "-0.01em",
|
|
23
|
+
transition: "all 0.15s ease",
|
|
24
|
+
display: "flex",
|
|
25
|
+
alignItems: "center",
|
|
26
|
+
justifyContent: "center",
|
|
27
|
+
gap: "8px",
|
|
28
|
+
}, children: [_jsx(Target, { size: 16, strokeWidth: 2 }), pickerOn ? "Picker Active" : "Enable Picker"] }), recording ? (_jsxs("button", { onClick: onStopRecording, style: {
|
|
29
|
+
flex: 1,
|
|
30
|
+
padding: "11px 16px",
|
|
31
|
+
background: "#1a1a1a",
|
|
32
|
+
color: "#ffffff",
|
|
33
|
+
border: "1px solid #1a1a1a",
|
|
34
|
+
borderRadius: "8px",
|
|
35
|
+
cursor: "pointer",
|
|
36
|
+
fontSize: "13px",
|
|
37
|
+
fontWeight: 500,
|
|
38
|
+
boxShadow: "none",
|
|
39
|
+
letterSpacing: "-0.01em",
|
|
40
|
+
animation: "pulse 1.5s ease-in-out infinite",
|
|
41
|
+
display: "flex",
|
|
42
|
+
alignItems: "center",
|
|
43
|
+
justifyContent: "center",
|
|
44
|
+
gap: "8px",
|
|
45
|
+
}, children: [_jsx(Square, { size: 16, strokeWidth: 2, fill: "currentColor" }), "Stop Recording"] })) : (_jsxs("button", { onClick: onStartRecording, style: {
|
|
46
|
+
flex: 1,
|
|
47
|
+
padding: "11px 16px",
|
|
48
|
+
background: "#1a1a1a",
|
|
49
|
+
color: "#ffffff",
|
|
50
|
+
border: "1px solid #1a1a1a",
|
|
51
|
+
borderRadius: "8px",
|
|
52
|
+
cursor: "pointer",
|
|
53
|
+
fontSize: "13px",
|
|
54
|
+
fontWeight: 500,
|
|
55
|
+
boxShadow: "none",
|
|
56
|
+
letterSpacing: "-0.01em",
|
|
57
|
+
display: "flex",
|
|
58
|
+
alignItems: "center",
|
|
59
|
+
justifyContent: "center",
|
|
60
|
+
gap: "8px",
|
|
61
|
+
}, children: [_jsx(Circle, { size: 16, strokeWidth: 2, fill: "currentColor" }), "Start Recording"] }))] }), _jsx("div", { style: { display: "flex", gap: "10px", marginBottom: "12px" }, children: isRunning ? (_jsxs("button", { onClick: onStop, style: {
|
|
62
|
+
width: "100%",
|
|
63
|
+
padding: "11px 16px",
|
|
64
|
+
background: "#fee2e2",
|
|
65
|
+
color: "#dc2626",
|
|
66
|
+
border: "1px solid #fecaca",
|
|
67
|
+
borderRadius: "8px",
|
|
68
|
+
cursor: "pointer",
|
|
69
|
+
fontSize: "13px",
|
|
70
|
+
fontWeight: 600,
|
|
71
|
+
boxShadow: "none",
|
|
72
|
+
letterSpacing: "-0.01em",
|
|
73
|
+
display: "flex",
|
|
74
|
+
alignItems: "center",
|
|
75
|
+
justifyContent: "center",
|
|
76
|
+
gap: "8px",
|
|
77
|
+
}, children: [_jsx(Pause, { size: 16, strokeWidth: 2, fill: "currentColor" }), "Stop Execution"] })) : (_jsxs("button", { onClick: onRun, disabled: !hasSteps || recording, style: {
|
|
78
|
+
width: "100%",
|
|
79
|
+
padding: "11px 16px",
|
|
80
|
+
background: !hasSteps || recording ? "#f5f5f5" : "#16a34a",
|
|
81
|
+
color: !hasSteps || recording ? "#a3a3a3" : "#ffffff",
|
|
82
|
+
border: !hasSteps || recording
|
|
83
|
+
? "1px solid #e5e5e5"
|
|
84
|
+
: "1px solid #16a34a",
|
|
85
|
+
borderRadius: "8px",
|
|
86
|
+
cursor: !hasSteps || recording ? "not-allowed" : "pointer",
|
|
87
|
+
fontSize: "13px",
|
|
88
|
+
fontWeight: 600,
|
|
89
|
+
boxShadow: "none",
|
|
90
|
+
letterSpacing: "-0.01em",
|
|
91
|
+
display: "flex",
|
|
92
|
+
alignItems: "center",
|
|
93
|
+
justifyContent: "center",
|
|
94
|
+
gap: "8px",
|
|
95
|
+
}, children: [_jsx(Play, { size: 16, strokeWidth: 2, fill: "currentColor" }), "Run Flow"] })) }), _jsxs("div", { style: { display: "flex", gap: "10px" }, children: [_jsxs("button", { onClick: onUndo, disabled: !hasSteps || isRunning, style: {
|
|
96
|
+
flex: 1,
|
|
97
|
+
padding: "11px 16px",
|
|
98
|
+
background: !hasSteps || isRunning ? "#fafafa" : "#f5f5f5",
|
|
99
|
+
color: !hasSteps || isRunning ? "#a3a3a3" : "#404040",
|
|
100
|
+
border: "1px solid #e5e5e5",
|
|
101
|
+
borderRadius: "8px",
|
|
102
|
+
cursor: !hasSteps || isRunning ? "not-allowed" : "pointer",
|
|
103
|
+
fontSize: "13px",
|
|
104
|
+
fontWeight: 500,
|
|
105
|
+
boxShadow: "none",
|
|
106
|
+
letterSpacing: "-0.01em",
|
|
107
|
+
opacity: !hasSteps || isRunning ? 0.4 : 1,
|
|
108
|
+
display: "flex",
|
|
109
|
+
alignItems: "center",
|
|
110
|
+
justifyContent: "center",
|
|
111
|
+
gap: "8px",
|
|
112
|
+
}, children: [_jsx(Undo, { size: 16, strokeWidth: 2 }), "Undo"] }), _jsxs("button", { onClick: onClear, disabled: !hasSteps || recording || isRunning, style: {
|
|
113
|
+
flex: 1,
|
|
114
|
+
padding: "11px 16px",
|
|
115
|
+
background: !hasSteps || recording || isRunning ? "#fafafa" : "#ffffff",
|
|
116
|
+
color: !hasSteps || recording || isRunning ? "#a3a3a3" : "#dc2626",
|
|
117
|
+
border: "1px solid #e5e5e5",
|
|
118
|
+
borderRadius: "8px",
|
|
119
|
+
cursor: !hasSteps || recording || isRunning ? "not-allowed" : "pointer",
|
|
120
|
+
fontSize: "13px",
|
|
121
|
+
fontWeight: 500,
|
|
122
|
+
boxShadow: "none",
|
|
123
|
+
letterSpacing: "-0.01em",
|
|
124
|
+
opacity: !hasSteps || recording || isRunning ? 0.4 : 1,
|
|
125
|
+
display: "flex",
|
|
126
|
+
alignItems: "center",
|
|
127
|
+
justifyContent: "center",
|
|
128
|
+
gap: "8px",
|
|
129
|
+
}, children: [_jsx(Trash2, { size: 16, strokeWidth: 2 }), "Clear"] }), _jsxs("button", { onClick: onSendToBackend, disabled: !hasSteps || isRunning, style: {
|
|
130
|
+
flex: 2,
|
|
131
|
+
padding: "11px 16px",
|
|
132
|
+
background: !hasSteps || isRunning ? "#fafafa" : "#f5f5f5",
|
|
133
|
+
color: !hasSteps || isRunning ? "#a3a3a3" : "#404040",
|
|
134
|
+
border: "1px solid #e5e5e5",
|
|
135
|
+
borderRadius: "8px",
|
|
136
|
+
cursor: !hasSteps || isRunning ? "not-allowed" : "pointer",
|
|
137
|
+
fontSize: "13px",
|
|
138
|
+
fontWeight: 500,
|
|
139
|
+
boxShadow: "none",
|
|
140
|
+
letterSpacing: "-0.01em",
|
|
141
|
+
opacity: !hasSteps || isRunning ? 0.4 : 1,
|
|
142
|
+
display: "flex",
|
|
143
|
+
alignItems: "center",
|
|
144
|
+
justifyContent: "center",
|
|
145
|
+
gap: "8px",
|
|
146
|
+
}, children: [_jsx(Send, { size: 16, strokeWidth: 2 }), "Send"] })] }), _jsx("style", { children: `
|
|
147
|
+
@keyframes pulse {
|
|
148
|
+
0%, 100% {
|
|
149
|
+
opacity: 1;
|
|
150
|
+
}
|
|
151
|
+
50% {
|
|
152
|
+
opacity: 0.7;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
` })] }));
|
|
156
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Step } from "@auto-wiz/core";
|
|
2
|
+
interface FlowStepItemProps {
|
|
3
|
+
step: Step;
|
|
4
|
+
index: number;
|
|
5
|
+
isExecuting: boolean;
|
|
6
|
+
isCompleted: boolean;
|
|
7
|
+
extractedData?: any;
|
|
8
|
+
screenshot?: {
|
|
9
|
+
screenshot: string;
|
|
10
|
+
elementInfo: any;
|
|
11
|
+
};
|
|
12
|
+
onRemove: (index: number) => void;
|
|
13
|
+
onMoveUp?: (index: number) => void;
|
|
14
|
+
onMoveDown?: (index: number) => void;
|
|
15
|
+
totalSteps?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Flow의 개별 Step을 표시하는 컴포넌트
|
|
19
|
+
*/
|
|
20
|
+
export declare function FlowStepItem({ step, index, isExecuting, isCompleted, extractedData, screenshot, onRemove, onMoveUp, onMoveDown, totalSteps, }: FlowStepItemProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { MousePointer2, Keyboard, ListChecks, Download, Globe, Clock, X, Shield, ShieldAlert, ChevronUp, ChevronDown, } from "lucide-react";
|
|
3
|
+
/**
|
|
4
|
+
* Flow의 개별 Step을 표시하는 컴포넌트
|
|
5
|
+
*/
|
|
6
|
+
export function FlowStepItem({ step, index, isExecuting, isCompleted, extractedData, screenshot, onRemove, onMoveUp, onMoveDown, totalSteps = 0, }) {
|
|
7
|
+
const getStepIcon = (type) => {
|
|
8
|
+
const iconProps = { size: 16, strokeWidth: 2 };
|
|
9
|
+
switch (type) {
|
|
10
|
+
case "click":
|
|
11
|
+
return _jsx(MousePointer2, { ...iconProps });
|
|
12
|
+
case "type":
|
|
13
|
+
return _jsx(Keyboard, { ...iconProps });
|
|
14
|
+
case "select":
|
|
15
|
+
return _jsx(ListChecks, { ...iconProps });
|
|
16
|
+
case "extract":
|
|
17
|
+
return _jsx(Download, { ...iconProps });
|
|
18
|
+
case "navigate":
|
|
19
|
+
return _jsx(Globe, { ...iconProps });
|
|
20
|
+
case "waitFor":
|
|
21
|
+
return _jsx(Clock, { ...iconProps });
|
|
22
|
+
default:
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const getStepLabel = (type) => {
|
|
27
|
+
switch (type) {
|
|
28
|
+
case "click":
|
|
29
|
+
return "Click";
|
|
30
|
+
case "type":
|
|
31
|
+
return "Type";
|
|
32
|
+
case "select":
|
|
33
|
+
return "Select";
|
|
34
|
+
case "extract":
|
|
35
|
+
return "Extract";
|
|
36
|
+
case "navigate":
|
|
37
|
+
return "Navigate";
|
|
38
|
+
case "waitFor":
|
|
39
|
+
return "Wait";
|
|
40
|
+
default:
|
|
41
|
+
return "Action";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* 메타데이터를 활용해서 사람이 읽기 쉬운 요소 설명 생성
|
|
46
|
+
*/
|
|
47
|
+
const getElementDescription = (step) => {
|
|
48
|
+
if (step.type === "navigate" || step.type === "waitForNavigation") {
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
const locator = "locator" in step ? step.locator : undefined;
|
|
52
|
+
const metadata = locator?.metadata;
|
|
53
|
+
if (!metadata) {
|
|
54
|
+
// fallback: selector를 간략하게 표시
|
|
55
|
+
const selector = "selector" in step ? step.selector : "";
|
|
56
|
+
return simplifySelector(selector);
|
|
57
|
+
}
|
|
58
|
+
// 메타데이터에서 가장 의미있는 정보 추출
|
|
59
|
+
const parts = [];
|
|
60
|
+
// 1순위: text content
|
|
61
|
+
if (metadata.text) {
|
|
62
|
+
parts.push(`"${truncateText(metadata.text, 30)}"`);
|
|
63
|
+
}
|
|
64
|
+
// 2순위: placeholder (input 필드인 경우)
|
|
65
|
+
else if (metadata.placeholder) {
|
|
66
|
+
parts.push(`"${metadata.placeholder}"`);
|
|
67
|
+
}
|
|
68
|
+
// 3순위: aria-label
|
|
69
|
+
else if (metadata.ariaLabel) {
|
|
70
|
+
parts.push(`"${metadata.ariaLabel}"`);
|
|
71
|
+
}
|
|
72
|
+
// 4순위: title
|
|
73
|
+
else if (metadata.title) {
|
|
74
|
+
parts.push(`"${metadata.title}"`);
|
|
75
|
+
}
|
|
76
|
+
// 요소 타입 정보
|
|
77
|
+
if (metadata.role) {
|
|
78
|
+
parts.push(metadata.role);
|
|
79
|
+
}
|
|
80
|
+
else if (metadata.tagName &&
|
|
81
|
+
metadata.tagName !== "div" &&
|
|
82
|
+
metadata.tagName !== "span") {
|
|
83
|
+
parts.push(metadata.tagName);
|
|
84
|
+
}
|
|
85
|
+
// testId가 있으면 힌트로 표시
|
|
86
|
+
if (metadata.testId && parts.length === 0) {
|
|
87
|
+
parts.push(`[${metadata.testId}]`);
|
|
88
|
+
}
|
|
89
|
+
return parts.length > 0
|
|
90
|
+
? parts.join(" ")
|
|
91
|
+
: simplifySelector("selector" in step ? step.selector : "");
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Selector를 간략하게 표시 (ID나 class만 추출)
|
|
95
|
+
*/
|
|
96
|
+
const simplifySelector = (selector) => {
|
|
97
|
+
if (!selector)
|
|
98
|
+
return "element";
|
|
99
|
+
// ID selector
|
|
100
|
+
const idMatch = selector.match(/#([\w-]+)/);
|
|
101
|
+
if (idMatch)
|
|
102
|
+
return `#${idMatch[1]}`;
|
|
103
|
+
// data-testid
|
|
104
|
+
const testIdMatch = selector.match(/\[data-testid=["']([^"']+)["']\]/);
|
|
105
|
+
if (testIdMatch)
|
|
106
|
+
return `[${testIdMatch[1]}]`;
|
|
107
|
+
// class (첫 번째만)
|
|
108
|
+
const classMatch = selector.match(/\.([\w-]+)/);
|
|
109
|
+
if (classMatch)
|
|
110
|
+
return `.${classMatch[1]}`;
|
|
111
|
+
// 태그명
|
|
112
|
+
const tagMatch = selector.match(/^(\w+)/);
|
|
113
|
+
if (tagMatch)
|
|
114
|
+
return tagMatch[1];
|
|
115
|
+
return "element";
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* 텍스트를 truncate
|
|
119
|
+
*/
|
|
120
|
+
const truncateText = (text, maxLength) => {
|
|
121
|
+
if (text.length <= maxLength)
|
|
122
|
+
return text;
|
|
123
|
+
return text.substring(0, maxLength) + "...";
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Step의 주요 액션을 사람이 읽기 쉬운 형태로 표시
|
|
127
|
+
*/
|
|
128
|
+
const getStepDescription = (step) => {
|
|
129
|
+
const elementDesc = getElementDescription(step);
|
|
130
|
+
switch (step.type) {
|
|
131
|
+
case "click":
|
|
132
|
+
return elementDesc ? `Click ${elementDesc}` : "Click element";
|
|
133
|
+
case "type":
|
|
134
|
+
const textToShow = step.text || step.originalText || "";
|
|
135
|
+
const displayText = textToShow.length > 30
|
|
136
|
+
? textToShow.substring(0, 30) + "..."
|
|
137
|
+
: textToShow;
|
|
138
|
+
return `Type "${displayText}"${elementDesc ? ` into ${elementDesc}` : ""}${step.submit ? " ⏎" : ""}`;
|
|
139
|
+
case "select":
|
|
140
|
+
return `Select "${step.value}"${elementDesc ? ` from ${elementDesc}` : ""}`;
|
|
141
|
+
case "extract":
|
|
142
|
+
return elementDesc ? `Extract from ${elementDesc}` : "Extract data";
|
|
143
|
+
case "navigate":
|
|
144
|
+
const url = step.url.length > 50 ? step.url.substring(0, 50) + "..." : step.url;
|
|
145
|
+
return `Navigate to ${url}`;
|
|
146
|
+
case "waitFor":
|
|
147
|
+
if (step.selector) {
|
|
148
|
+
return elementDesc ? `Wait for ${elementDesc}` : "Wait for element";
|
|
149
|
+
}
|
|
150
|
+
return `Wait ${step.timeoutMs}ms`;
|
|
151
|
+
default:
|
|
152
|
+
return JSON.stringify(step);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Selector 신뢰도 계산 (높을수록 견고함)
|
|
157
|
+
*/
|
|
158
|
+
const getSelectorReliability = (step) => {
|
|
159
|
+
if (step.type === "navigate" || step.type === "waitForNavigation") {
|
|
160
|
+
return "high"; // URL은 항상 신뢰도 높음
|
|
161
|
+
}
|
|
162
|
+
const locator = "locator" in step ? step.locator : undefined;
|
|
163
|
+
if (!locator) {
|
|
164
|
+
return "low"; // locator가 없으면 낮음
|
|
165
|
+
}
|
|
166
|
+
const metadata = locator.metadata;
|
|
167
|
+
const fallbackCount = locator.fallbacks?.length || 0;
|
|
168
|
+
// testId나 role이 있고 fallback이 있으면 높음
|
|
169
|
+
if (metadata?.testId || metadata?.role) {
|
|
170
|
+
return fallbackCount >= 1 ? "high" : "medium";
|
|
171
|
+
}
|
|
172
|
+
// fallback이 2개 이상이면 중간
|
|
173
|
+
if (fallbackCount >= 2) {
|
|
174
|
+
return "medium";
|
|
175
|
+
}
|
|
176
|
+
return "low";
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* 신뢰도 뱃지 렌더링
|
|
180
|
+
*/
|
|
181
|
+
const renderReliabilityBadge = (reliability) => {
|
|
182
|
+
if (reliability === "high") {
|
|
183
|
+
return (_jsxs("span", { style: {
|
|
184
|
+
display: "inline-flex",
|
|
185
|
+
alignItems: "center",
|
|
186
|
+
gap: "4px",
|
|
187
|
+
fontSize: "11px",
|
|
188
|
+
padding: "4px 8px",
|
|
189
|
+
background: "#dcfce7",
|
|
190
|
+
color: "#16a34a",
|
|
191
|
+
borderRadius: "4px",
|
|
192
|
+
fontWeight: 600,
|
|
193
|
+
}, title: "Highly reliable selector with multiple fallbacks", children: [_jsx(Shield, { size: 11, strokeWidth: 2.5 }), "Robust"] }));
|
|
194
|
+
}
|
|
195
|
+
if (reliability === "low") {
|
|
196
|
+
return (_jsxs("span", { style: {
|
|
197
|
+
display: "inline-flex",
|
|
198
|
+
alignItems: "center",
|
|
199
|
+
gap: "4px",
|
|
200
|
+
fontSize: "11px",
|
|
201
|
+
padding: "4px 8px",
|
|
202
|
+
background: "#fee2e2",
|
|
203
|
+
color: "#dc2626",
|
|
204
|
+
borderRadius: "4px",
|
|
205
|
+
fontWeight: 600,
|
|
206
|
+
}, title: "Basic CSS selector - may be fragile", children: [_jsx(ShieldAlert, { size: 11, strokeWidth: 2.5 }), "Basic"] }));
|
|
207
|
+
}
|
|
208
|
+
return null; // medium은 표시 안함 (노이즈 줄이기)
|
|
209
|
+
};
|
|
210
|
+
return (_jsxs("div", { style: {
|
|
211
|
+
padding: "16px 0",
|
|
212
|
+
borderBottom: "1px solid #f5f5f5",
|
|
213
|
+
borderLeft: isExecuting
|
|
214
|
+
? "3px solid #1a1a1a"
|
|
215
|
+
: isCompleted
|
|
216
|
+
? "3px solid #737373"
|
|
217
|
+
: "3px solid transparent",
|
|
218
|
+
paddingLeft: "12px",
|
|
219
|
+
background: isExecuting
|
|
220
|
+
? "#fafafa"
|
|
221
|
+
: isCompleted
|
|
222
|
+
? "#f9f9f9"
|
|
223
|
+
: "transparent",
|
|
224
|
+
transition: "all 0.15s ease",
|
|
225
|
+
}, children: [_jsx("div", { style: { marginBottom: "12px" }, children: _jsxs("div", { style: {
|
|
226
|
+
display: "flex",
|
|
227
|
+
alignItems: "center",
|
|
228
|
+
gap: "8px",
|
|
229
|
+
marginBottom: "0",
|
|
230
|
+
}, children: [_jsx("span", { style: {
|
|
231
|
+
fontSize: "13px",
|
|
232
|
+
fontWeight: 600,
|
|
233
|
+
color: "#737373",
|
|
234
|
+
minWidth: "20px",
|
|
235
|
+
}, children: index + 1 }), _jsxs("span", { style: {
|
|
236
|
+
fontSize: "12px",
|
|
237
|
+
padding: "4px 10px",
|
|
238
|
+
background: "#f5f5f5",
|
|
239
|
+
borderRadius: "4px",
|
|
240
|
+
fontWeight: 500,
|
|
241
|
+
color: "#404040",
|
|
242
|
+
display: "inline-flex",
|
|
243
|
+
alignItems: "center",
|
|
244
|
+
gap: "6px",
|
|
245
|
+
}, children: [getStepIcon(step.type), getStepLabel(step.type)] }), renderReliabilityBadge(getSelectorReliability(step)), isExecuting && (_jsx("span", { style: {
|
|
246
|
+
fontSize: "11px",
|
|
247
|
+
padding: "4px 10px",
|
|
248
|
+
background: "#1a1a1a",
|
|
249
|
+
color: "#ffffff",
|
|
250
|
+
borderRadius: "4px",
|
|
251
|
+
fontWeight: 600,
|
|
252
|
+
}, children: "Running" })), isCompleted && (_jsx("span", { style: {
|
|
253
|
+
fontSize: "11px",
|
|
254
|
+
padding: "4px 10px",
|
|
255
|
+
background: "#737373",
|
|
256
|
+
color: "#ffffff",
|
|
257
|
+
borderRadius: "4px",
|
|
258
|
+
fontWeight: 600,
|
|
259
|
+
}, children: "Done" })), _jsxs("div", { style: {
|
|
260
|
+
display: "flex",
|
|
261
|
+
gap: "4px",
|
|
262
|
+
marginLeft: "auto",
|
|
263
|
+
alignItems: "center",
|
|
264
|
+
paddingRight: "12px",
|
|
265
|
+
}, children: [(onMoveUp || onMoveDown) && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => onMoveUp?.(index), disabled: index === 0, style: {
|
|
266
|
+
padding: "4px",
|
|
267
|
+
background: "transparent",
|
|
268
|
+
color: index === 0 ? "#d4d4d4" : "#737373",
|
|
269
|
+
border: "none",
|
|
270
|
+
cursor: index === 0 ? "not-allowed" : "pointer",
|
|
271
|
+
display: "flex",
|
|
272
|
+
alignItems: "center",
|
|
273
|
+
justifyContent: "center",
|
|
274
|
+
opacity: index === 0 ? 0.3 : 1,
|
|
275
|
+
}, title: "Move up", children: _jsx(ChevronUp, { size: 16, strokeWidth: 2 }) }), _jsx("button", { onClick: () => onMoveDown?.(index), disabled: index === totalSteps - 1, style: {
|
|
276
|
+
padding: "4px",
|
|
277
|
+
background: "transparent",
|
|
278
|
+
color: index === totalSteps - 1 ? "#d4d4d4" : "#737373",
|
|
279
|
+
border: "none",
|
|
280
|
+
cursor: index === totalSteps - 1 ? "not-allowed" : "pointer",
|
|
281
|
+
display: "flex",
|
|
282
|
+
alignItems: "center",
|
|
283
|
+
justifyContent: "center",
|
|
284
|
+
opacity: index === totalSteps - 1 ? 0.3 : 1,
|
|
285
|
+
}, title: "Move down", children: _jsx(ChevronDown, { size: 16, strokeWidth: 2 }) })] })), _jsx("button", { onClick: () => onRemove(index), style: {
|
|
286
|
+
padding: "4px",
|
|
287
|
+
background: "transparent",
|
|
288
|
+
color: "#a3a3a3",
|
|
289
|
+
border: "none",
|
|
290
|
+
cursor: "pointer",
|
|
291
|
+
display: "flex",
|
|
292
|
+
alignItems: "center",
|
|
293
|
+
justifyContent: "center",
|
|
294
|
+
}, title: "Remove", children: _jsx(X, { size: 16, strokeWidth: 2 }) })] })] }) }), _jsx("div", { style: {
|
|
295
|
+
fontSize: "14px",
|
|
296
|
+
color: "#404040",
|
|
297
|
+
marginBottom: extractedData || screenshot ? "10px" : "0",
|
|
298
|
+
paddingRight: "12px",
|
|
299
|
+
wordBreak: "break-word",
|
|
300
|
+
lineHeight: "1.5",
|
|
301
|
+
}, children: getStepDescription(step) }), extractedData !== undefined && (_jsxs("div", { style: {
|
|
302
|
+
marginTop: "12px",
|
|
303
|
+
marginRight: "12px",
|
|
304
|
+
padding: "12px",
|
|
305
|
+
background: "#fafafa",
|
|
306
|
+
border: "1px solid #e5e5e5",
|
|
307
|
+
borderRadius: "6px",
|
|
308
|
+
fontSize: "12px",
|
|
309
|
+
color: "#404040",
|
|
310
|
+
fontFamily: "'SF Mono', 'Monaco', 'Menlo', monospace",
|
|
311
|
+
lineHeight: "1.6",
|
|
312
|
+
}, children: [_jsx("strong", { style: { fontWeight: 500 }, children: "Extracted:" }), " ", JSON.stringify(extractedData)] })), screenshot && (_jsx("div", { style: { marginTop: "12px", marginRight: "12px" }, children: _jsx("img", { src: screenshot.screenshot, alt: "Element screenshot", style: {
|
|
313
|
+
maxWidth: "100%",
|
|
314
|
+
borderRadius: "6px",
|
|
315
|
+
border: "1px solid #e5e5e5",
|
|
316
|
+
} }) }))] }));
|
|
317
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@auto-wiz/ui",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "JaeSang",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/JaeSang1998/automation-wizard.git"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"require": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"lucide-react": "^0.553.0",
|
|
27
|
+
"react": "^19.1.1",
|
|
28
|
+
"react-dom": "^19.1.1",
|
|
29
|
+
"@auto-wiz/core": "1.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/react": "^19.1.12",
|
|
33
|
+
"@types/react-dom": "^19.1.9",
|
|
34
|
+
"typescript": "^5.0.0"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc"
|
|
38
|
+
}
|
|
39
|
+
}
|