@midscene/visualizer 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/component/assets/logo-plain.js +128 -0
- package/dist/es/component/assets/logo-plain2.js +128 -0
- package/dist/es/component/detail-panel.js +2 -2
- package/dist/es/component/detail-side.css +1 -1
- package/dist/es/component/detail-side.js +10 -1
- package/dist/es/component/global-hover-preview.css +1 -1
- package/dist/es/component/sidebar.css +2 -1
- package/dist/es/component/sidebar.js +19 -12
- package/dist/es/component/store.js +4 -4
- package/dist/es/component/timeline.js +1 -1
- package/dist/es/index.css +2 -2
- package/dist/es/index.js +11 -6
- package/dist/lib/component/assets/logo-plain.js +156 -0
- package/dist/lib/component/assets/logo-plain2.js +156 -0
- package/dist/lib/component/detail-panel.js +2 -2
- package/dist/lib/component/detail-side.css +1 -1
- package/dist/lib/component/detail-side.js +10 -1
- package/dist/lib/component/global-hover-preview.css +1 -1
- package/dist/lib/component/sidebar.css +2 -1
- package/dist/lib/component/sidebar.js +19 -12
- package/dist/lib/component/store.js +4 -4
- package/dist/lib/component/timeline.js +1 -1
- package/dist/lib/index.css +2 -2
- package/dist/lib/index.js +15 -6
- package/dist/types/component/sidebar.d.ts +4 -1
- package/dist/types/index.d.ts +7 -2
- package/package.json +9 -4
- package/.eslintrc.js +0 -9
- package/dist/es/assets/logo-plain.16842bbc.svg +0 -70
- package/dist/es/assets/logo-plain2.16842bbc.svg +0 -70
- package/dist/lib/assets/logo-plain.16842bbc.svg +0 -70
- package/dist/lib/assets/logo-plain2.16842bbc.svg +0 -70
- package/docs/index.tsx +0 -6
- package/modern.config.ts +0 -15
- package/src/component/assets/logo-plain.svg +0 -70
- package/src/component/assets/logo-plain2.svg +0 -70
- package/src/component/blackboard.less +0 -37
- package/src/component/blackboard.tsx +0 -293
- package/src/component/color.tsx +0 -34
- package/src/component/common.less +0 -21
- package/src/component/detail-panel.less +0 -47
- package/src/component/detail-panel.tsx +0 -124
- package/src/component/detail-side.less +0 -131
- package/src/component/detail-side.tsx +0 -361
- package/src/component/global-hover-preview.less +0 -23
- package/src/component/global-hover-preview.tsx +0 -50
- package/src/component/misc.tsx +0 -20
- package/src/component/panel-title.less +0 -11
- package/src/component/panel-title.tsx +0 -11
- package/src/component/side-item.tsx +0 -0
- package/src/component/sidebar.less +0 -122
- package/src/component/sidebar.tsx +0 -205
- package/src/component/store.tsx +0 -151
- package/src/component/timeline.less +0 -25
- package/src/component/timeline.tsx +0 -486
- package/src/global.d.ts +0 -11
- package/src/index.less +0 -113
- package/src/index.tsx +0 -210
- package/src/utils.ts +0 -58
- package/tsconfig.json +0 -24
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import './sidebar.less';
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
ArrowRightOutlined,
|
|
5
|
-
CheckOutlined,
|
|
6
|
-
ClockCircleOutlined,
|
|
7
|
-
CloseOutlined,
|
|
8
|
-
LogoutOutlined,
|
|
9
|
-
MinusOutlined,
|
|
10
|
-
} from '@ant-design/icons';
|
|
11
|
-
import { ExecutionTask } from '@midscene/core';
|
|
12
|
-
import { Button } from 'antd';
|
|
13
|
-
import PanelTitle from './panel-title';
|
|
14
|
-
import { timeCostStrElement } from './misc';
|
|
15
|
-
import logo from './assets/logo-plain2.svg';
|
|
16
|
-
import { useAllCurrentTasks, useExecutionDump } from '@/component/store';
|
|
17
|
-
import { typeStr } from '@/utils';
|
|
18
|
-
|
|
19
|
-
const SideItem = (props: {
|
|
20
|
-
task: ExecutionTask;
|
|
21
|
-
selected?: boolean;
|
|
22
|
-
onClick?: () => void;
|
|
23
|
-
onItemHover?: (task: ExecutionTask | null, x?: number, y?: number) => any;
|
|
24
|
-
}): JSX.Element => {
|
|
25
|
-
const { task, onClick, selected } = props;
|
|
26
|
-
|
|
27
|
-
const selectedClass = selected ? 'selected' : '';
|
|
28
|
-
let statusIcon = <MinusOutlined />;
|
|
29
|
-
if (task.status === 'success') {
|
|
30
|
-
statusIcon = <CheckOutlined />;
|
|
31
|
-
} else if (task.status === 'fail') {
|
|
32
|
-
statusIcon = <CloseOutlined />;
|
|
33
|
-
} else if (task.status === 'pending') {
|
|
34
|
-
statusIcon = <ClockCircleOutlined />;
|
|
35
|
-
} else if (task.status === 'cancelled') {
|
|
36
|
-
statusIcon = <LogoutOutlined />;
|
|
37
|
-
} else if (task.status === 'running') {
|
|
38
|
-
statusIcon = <ArrowRightOutlined />;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let statusText: JSX.Element | string = task.status;
|
|
42
|
-
if (task.timing?.cost) {
|
|
43
|
-
statusText = timeCostStrElement(task.timing.cost);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const contentRow =
|
|
47
|
-
task.type === 'Planning' ? <div className="side-item-content">{task.param?.userPrompt} </div> : null;
|
|
48
|
-
// add hover listener
|
|
49
|
-
return (
|
|
50
|
-
<div
|
|
51
|
-
className={`side-item ${selectedClass}`}
|
|
52
|
-
onClick={onClick}
|
|
53
|
-
// collect x,y (refer to the body) for hover preview
|
|
54
|
-
onMouseEnter={(event) => {
|
|
55
|
-
const rect = event.currentTarget.getBoundingClientRect();
|
|
56
|
-
const x = rect.left + rect.width;
|
|
57
|
-
const y = rect.top;
|
|
58
|
-
props.onItemHover?.(task, x, y);
|
|
59
|
-
}}
|
|
60
|
-
onMouseLeave={() => {
|
|
61
|
-
props.onItemHover?.(null);
|
|
62
|
-
}}
|
|
63
|
-
>
|
|
64
|
-
{' '}
|
|
65
|
-
<div className={`side-item-name`}>
|
|
66
|
-
<span className={`status-icon status-icon-${task.status}`}>{statusIcon}</span>
|
|
67
|
-
<div className="title">{typeStr(task)}</div>
|
|
68
|
-
<div className="status-text">{statusText}</div>
|
|
69
|
-
</div>
|
|
70
|
-
{contentRow}
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const Sidebar = (): JSX.Element => {
|
|
76
|
-
const groupedDumps = useExecutionDump((store) => store.dump);
|
|
77
|
-
const setActiveTask = useExecutionDump((store) => store.setActiveTask);
|
|
78
|
-
const activeTask = useExecutionDump((store) => store.activeTask);
|
|
79
|
-
const setHoverTask = useExecutionDump((store) => store.setHoverTask);
|
|
80
|
-
const setHoverPreviewConfig = useExecutionDump((store) => store.setHoverPreviewConfig);
|
|
81
|
-
// const selectedTaskIndex = useExecutionDump((store) => store.selectedTaskIndex);
|
|
82
|
-
// const setSelectedTaskIndex = useExecutionDump((store) => store.setSelectedTaskIndex);
|
|
83
|
-
const reset = useExecutionDump((store) => store.reset);
|
|
84
|
-
|
|
85
|
-
const allTasks = useAllCurrentTasks();
|
|
86
|
-
const currentSelectedIndex = allTasks?.findIndex((task) => task === activeTask);
|
|
87
|
-
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
// all tasks
|
|
90
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
91
|
-
if (!allTasks?.length || allTasks?.length <= 1) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
// should be command / ctrl + arrow
|
|
95
|
-
if (e.key === 'ArrowUp' && (e.metaKey || e.ctrlKey)) {
|
|
96
|
-
e.preventDefault();
|
|
97
|
-
const nextIndex = currentSelectedIndex - 1;
|
|
98
|
-
if (nextIndex < 0) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const nextTask = allTasks[nextIndex];
|
|
102
|
-
setActiveTask(nextTask);
|
|
103
|
-
} else if (e.key === 'ArrowDown' && (e.metaKey || e.ctrlKey)) {
|
|
104
|
-
e.preventDefault();
|
|
105
|
-
const nextIndex = currentSelectedIndex + 1;
|
|
106
|
-
if (nextIndex >= allTasks.length) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const nextTask = allTasks[nextIndex];
|
|
110
|
-
setActiveTask(nextTask);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
114
|
-
return () => {
|
|
115
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
116
|
-
};
|
|
117
|
-
}, [currentSelectedIndex, allTasks, setActiveTask]);
|
|
118
|
-
|
|
119
|
-
const sideList = groupedDumps?.length ? (
|
|
120
|
-
groupedDumps.map((group, groupIndex) => {
|
|
121
|
-
const executions = group.executions.map((execution, indexOfExecution) => {
|
|
122
|
-
const { tasks } = execution;
|
|
123
|
-
const taskList = tasks.map((task, index) => {
|
|
124
|
-
return (
|
|
125
|
-
<SideItem
|
|
126
|
-
key={index}
|
|
127
|
-
task={task}
|
|
128
|
-
selected={task === activeTask}
|
|
129
|
-
onClick={() => {
|
|
130
|
-
setActiveTask(task);
|
|
131
|
-
}}
|
|
132
|
-
onItemHover={(hoverTask, x, y) => {
|
|
133
|
-
if (hoverTask && x && y) {
|
|
134
|
-
setHoverPreviewConfig({ x, y });
|
|
135
|
-
setHoverTask(hoverTask);
|
|
136
|
-
} else {
|
|
137
|
-
setHoverPreviewConfig(null);
|
|
138
|
-
setHoverTask(null);
|
|
139
|
-
}
|
|
140
|
-
}}
|
|
141
|
-
/>
|
|
142
|
-
);
|
|
143
|
-
});
|
|
144
|
-
let seperator: JSX.Element;
|
|
145
|
-
switch (indexOfExecution) {
|
|
146
|
-
case 0:
|
|
147
|
-
seperator = <div className="side-seperator side-seperator-space-up" />;
|
|
148
|
-
break;
|
|
149
|
-
// case group.executions.length - 1:
|
|
150
|
-
// seperator = <div className="side-seperator side-seperator-space-down" />;
|
|
151
|
-
// break;
|
|
152
|
-
default:
|
|
153
|
-
seperator = (
|
|
154
|
-
<div className="side-seperator side-seperator-line side-seperator-space-up side-seperator-space-down" />
|
|
155
|
-
);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
return (
|
|
159
|
-
<div key={indexOfExecution}>
|
|
160
|
-
{seperator}
|
|
161
|
-
<div className="side-sub-title">{execution.name}</div>
|
|
162
|
-
{taskList}
|
|
163
|
-
</div>
|
|
164
|
-
);
|
|
165
|
-
});
|
|
166
|
-
return (
|
|
167
|
-
<div key={groupIndex}>
|
|
168
|
-
<PanelTitle title={group.groupName} />
|
|
169
|
-
{executions}
|
|
170
|
-
</div>
|
|
171
|
-
);
|
|
172
|
-
})
|
|
173
|
-
) : (
|
|
174
|
-
<span>no tasks</span>
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<div className="side-bar">
|
|
179
|
-
<div className="top-controls">
|
|
180
|
-
<div className="brand" onClick={reset}>
|
|
181
|
-
<img
|
|
182
|
-
src={logo}
|
|
183
|
-
alt="Logo"
|
|
184
|
-
style={{ width: 70, height: 70, margin: 'auto' }}
|
|
185
|
-
onClick={() => {
|
|
186
|
-
location.reload();
|
|
187
|
-
}}
|
|
188
|
-
/>
|
|
189
|
-
</div>
|
|
190
|
-
<div className="task-list">{sideList}</div>
|
|
191
|
-
<div className="side-seperator side-seperator-line side-seperator-space-up" />
|
|
192
|
-
<div className="task-meta-section">
|
|
193
|
-
<div className="task-meta">use Command + ⬆︎ / ⬇︎ to switch</div>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
<div className="bottom-controls">
|
|
197
|
-
<Button onClick={reset} type="text" className="unload_btn">
|
|
198
|
-
Unload
|
|
199
|
-
</Button>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
);
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
export default Sidebar;
|
package/src/component/store.tsx
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { create } from 'zustand';
|
|
2
|
-
import {
|
|
3
|
-
InsightDump,
|
|
4
|
-
BaseElement,
|
|
5
|
-
ExecutionTaskInsightLocate,
|
|
6
|
-
ExecutionTask,
|
|
7
|
-
GroupedActionDump,
|
|
8
|
-
} from '../../../midscene/dist/types';
|
|
9
|
-
|
|
10
|
-
export const useBlackboardPreference = create<{
|
|
11
|
-
bgVisible: boolean;
|
|
12
|
-
textsVisible: boolean;
|
|
13
|
-
setBgVisible: (visible: boolean) => void;
|
|
14
|
-
setTextsVisible: (visible: boolean) => void;
|
|
15
|
-
}>((set) => ({
|
|
16
|
-
bgVisible: false,
|
|
17
|
-
textsVisible: true,
|
|
18
|
-
setBgVisible: (visible: boolean) => {
|
|
19
|
-
set({ bgVisible: visible });
|
|
20
|
-
},
|
|
21
|
-
setTextsVisible: (visible: boolean) => {
|
|
22
|
-
set({ textsVisible: visible });
|
|
23
|
-
},
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
export const useExecutionDump = create<{
|
|
27
|
-
dump: GroupedActionDump[] | null;
|
|
28
|
-
setGroupedDump: (dump: GroupedActionDump[]) => void;
|
|
29
|
-
activeTask: ExecutionTask | null;
|
|
30
|
-
setActiveTask: (task: ExecutionTask) => void;
|
|
31
|
-
hoverTask: ExecutionTask | null;
|
|
32
|
-
setHoverTask: (task: ExecutionTask | null) => void;
|
|
33
|
-
hoverPreviewConfig: { x: number; y: number } | null;
|
|
34
|
-
setHoverPreviewConfig: (config: { x: number; y: number } | null) => void;
|
|
35
|
-
reset: () => void;
|
|
36
|
-
}>((set) => {
|
|
37
|
-
const initData = {
|
|
38
|
-
dump: null,
|
|
39
|
-
activeTask: null,
|
|
40
|
-
hoverTask: null,
|
|
41
|
-
hoverPreviewConfig: null,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const syncToInsightDump = (dump: InsightDump) => {
|
|
45
|
-
const { loadData } = useInsightDump.getState();
|
|
46
|
-
loadData(dump);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const resetInsightDump = () => {
|
|
50
|
-
const { reset } = useInsightDump.getState();
|
|
51
|
-
reset();
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
...initData,
|
|
56
|
-
setGroupedDump: (dump: GroupedActionDump[]) => {
|
|
57
|
-
console.log('will set ExecutionDump', dump);
|
|
58
|
-
set({
|
|
59
|
-
dump,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// set the first one as selected
|
|
63
|
-
for (const item of dump) {
|
|
64
|
-
if (item.executions.length > 0 && item.executions[0].tasks.length > 0) {
|
|
65
|
-
set({ activeTask: item.executions[0].tasks[0] });
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
setActiveTask(task: ExecutionTask) {
|
|
71
|
-
set({ activeTask: task });
|
|
72
|
-
if ((task as ExecutionTaskInsightLocate).log?.dump?.matchedElement) {
|
|
73
|
-
syncToInsightDump((task as ExecutionTaskInsightLocate).log!.dump!);
|
|
74
|
-
} else {
|
|
75
|
-
resetInsightDump();
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
setHoverTask(task: ExecutionTask | null) {
|
|
79
|
-
set({ hoverTask: task });
|
|
80
|
-
},
|
|
81
|
-
setHoverPreviewConfig(config: { x: number; y: number } | null) {
|
|
82
|
-
if (config) {
|
|
83
|
-
set({
|
|
84
|
-
hoverPreviewConfig: {
|
|
85
|
-
x: Math.floor(config.x),
|
|
86
|
-
y: Math.floor(config.y),
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
} else {
|
|
90
|
-
set({ hoverPreviewConfig: null });
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
reset: () => {
|
|
94
|
-
set(initData);
|
|
95
|
-
resetInsightDump();
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
export const useAllCurrentTasks = (): ExecutionTask[] => {
|
|
101
|
-
const groupedDumps = useExecutionDump((store) => store.dump);
|
|
102
|
-
|
|
103
|
-
const allTasks =
|
|
104
|
-
groupedDumps?.reduce<ExecutionTask[]>((acc, group) => {
|
|
105
|
-
const tasksInside = group.executions.reduce<ExecutionTask[]>(
|
|
106
|
-
(acc2, execution) => acc2.concat(execution.tasks),
|
|
107
|
-
[],
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
return acc.concat(tasksInside);
|
|
111
|
-
}, []) || [];
|
|
112
|
-
|
|
113
|
-
return allTasks;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const useInsightDump = create<{
|
|
117
|
-
_loadId: number;
|
|
118
|
-
data: InsightDump | null;
|
|
119
|
-
highlightSectionNames: string[];
|
|
120
|
-
setHighlightSectionNames: (sections: string[]) => void;
|
|
121
|
-
highlightElements: BaseElement[];
|
|
122
|
-
setHighlightElements: (elements: BaseElement[]) => void;
|
|
123
|
-
loadData: (data: InsightDump) => void;
|
|
124
|
-
reset: () => void;
|
|
125
|
-
}>((set) => {
|
|
126
|
-
let loadId = 0;
|
|
127
|
-
const initData = { _loadId: 0, highlightSectionNames: [], highlightElements: [], data: null };
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
...initData,
|
|
131
|
-
loadData: (data: InsightDump) => {
|
|
132
|
-
// console.log('will load dump data');
|
|
133
|
-
// console.log(data);
|
|
134
|
-
set({
|
|
135
|
-
_loadId: ++loadId,
|
|
136
|
-
data,
|
|
137
|
-
highlightSectionNames: [],
|
|
138
|
-
highlightElements: [],
|
|
139
|
-
});
|
|
140
|
-
},
|
|
141
|
-
setHighlightSectionNames: (sections: string[]) => {
|
|
142
|
-
set({ highlightSectionNames: sections });
|
|
143
|
-
},
|
|
144
|
-
setHighlightElements: (elements: BaseElement[]) => {
|
|
145
|
-
set({ highlightElements: elements });
|
|
146
|
-
},
|
|
147
|
-
reset: () => {
|
|
148
|
-
set(initData);
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
@import './common.less';
|
|
2
|
-
|
|
3
|
-
@base-height: 110px;
|
|
4
|
-
|
|
5
|
-
.timeline-wrapper {
|
|
6
|
-
flex-basis: @base-height;
|
|
7
|
-
flex-grow: 0;
|
|
8
|
-
flex-shrink: 0;
|
|
9
|
-
|
|
10
|
-
width: 100%;
|
|
11
|
-
height: 100%;
|
|
12
|
-
border-bottom: 1px solid @border-color;
|
|
13
|
-
position: relative;
|
|
14
|
-
box-sizing: border-box;
|
|
15
|
-
|
|
16
|
-
.timeline-canvas-wrapper {
|
|
17
|
-
width: 100%;
|
|
18
|
-
height: 100%;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
canvas {
|
|
22
|
-
width: 100%;
|
|
23
|
-
height: 100%;
|
|
24
|
-
}
|
|
25
|
-
}
|