@midscene/visualizer 0.0.1

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 (92) hide show
  1. package/.eslintrc.js +9 -0
  2. package/README.md +24 -0
  3. package/dist/es/assets/logo-plain.16842bbc.svg +70 -0
  4. package/dist/es/assets/logo-plain2.16842bbc.svg +70 -0
  5. package/dist/es/component/blackboard.css +25 -0
  6. package/dist/es/component/blackboard.js +256 -0
  7. package/dist/es/component/color.js +34 -0
  8. package/dist/es/component/common.css +0 -0
  9. package/dist/es/component/detail-panel.css +34 -0
  10. package/dist/es/component/detail-panel.js +106 -0
  11. package/dist/es/component/detail-side.css +99 -0
  12. package/dist/es/component/detail-side.js +285 -0
  13. package/dist/es/component/global-hover-preview.css +19 -0
  14. package/dist/es/component/global-hover-preview.js +44 -0
  15. package/dist/es/component/misc.js +24 -0
  16. package/dist/es/component/panel-title.css +8 -0
  17. package/dist/es/component/panel-title.js +9 -0
  18. package/dist/es/component/side-item.js +0 -0
  19. package/dist/es/component/sidebar.css +87 -0
  20. package/dist/es/component/sidebar.js +175 -0
  21. package/dist/es/component/store.js +128 -0
  22. package/dist/es/component/timeline.css +18 -0
  23. package/dist/es/component/timeline.js +438 -0
  24. package/dist/es/index.css +89 -0
  25. package/dist/es/index.js +174 -0
  26. package/dist/es/utils.js +76 -0
  27. package/dist/lib/assets/logo-plain.16842bbc.svg +70 -0
  28. package/dist/lib/assets/logo-plain2.16842bbc.svg +70 -0
  29. package/dist/lib/component/blackboard.css +25 -0
  30. package/dist/lib/component/blackboard.js +286 -0
  31. package/dist/lib/component/color.js +59 -0
  32. package/dist/lib/component/common.css +0 -0
  33. package/dist/lib/component/detail-panel.css +34 -0
  34. package/dist/lib/component/detail-panel.js +136 -0
  35. package/dist/lib/component/detail-side.css +99 -0
  36. package/dist/lib/component/detail-side.js +313 -0
  37. package/dist/lib/component/global-hover-preview.css +19 -0
  38. package/dist/lib/component/global-hover-preview.js +64 -0
  39. package/dist/lib/component/misc.js +48 -0
  40. package/dist/lib/component/panel-title.css +8 -0
  41. package/dist/lib/component/panel-title.js +29 -0
  42. package/dist/lib/component/side-item.js +1 -0
  43. package/dist/lib/component/sidebar.css +87 -0
  44. package/dist/lib/component/sidebar.js +198 -0
  45. package/dist/lib/component/store.js +153 -0
  46. package/dist/lib/component/timeline.css +18 -0
  47. package/dist/lib/component/timeline.js +466 -0
  48. package/dist/lib/index.css +89 -0
  49. package/dist/lib/index.js +202 -0
  50. package/dist/lib/utils.js +111 -0
  51. package/dist/types/component/blackboard.d.ts +4 -0
  52. package/dist/types/component/color.d.ts +2 -0
  53. package/dist/types/component/detail-panel.d.ts +4 -0
  54. package/dist/types/component/detail-side.d.ts +4 -0
  55. package/dist/types/component/global-hover-preview.d.ts +4 -0
  56. package/dist/types/component/misc.d.ts +2 -0
  57. package/dist/types/component/panel-title.d.ts +6 -0
  58. package/dist/types/component/side-item.d.ts +0 -0
  59. package/dist/types/component/sidebar.d.ts +4 -0
  60. package/dist/types/component/store.d.ts +35 -0
  61. package/dist/types/component/timeline.d.ts +4 -0
  62. package/dist/types/index.d.ts +4 -0
  63. package/dist/types/utils.d.ts +5 -0
  64. package/docs/index.tsx +6 -0
  65. package/modern.config.ts +15 -0
  66. package/package.json +46 -0
  67. package/src/component/assets/logo-plain.svg +70 -0
  68. package/src/component/assets/logo-plain2.svg +70 -0
  69. package/src/component/blackboard.less +37 -0
  70. package/src/component/blackboard.tsx +293 -0
  71. package/src/component/color.tsx +34 -0
  72. package/src/component/common.less +21 -0
  73. package/src/component/detail-panel.less +47 -0
  74. package/src/component/detail-panel.tsx +124 -0
  75. package/src/component/detail-side.less +131 -0
  76. package/src/component/detail-side.tsx +361 -0
  77. package/src/component/global-hover-preview.less +23 -0
  78. package/src/component/global-hover-preview.tsx +50 -0
  79. package/src/component/misc.tsx +20 -0
  80. package/src/component/panel-title.less +11 -0
  81. package/src/component/panel-title.tsx +11 -0
  82. package/src/component/side-item.tsx +0 -0
  83. package/src/component/sidebar.less +122 -0
  84. package/src/component/sidebar.tsx +205 -0
  85. package/src/component/store.tsx +151 -0
  86. package/src/component/timeline.less +25 -0
  87. package/src/component/timeline.tsx +486 -0
  88. package/src/global.d.ts +11 -0
  89. package/src/index.less +113 -0
  90. package/src/index.tsx +210 -0
  91. package/src/utils.ts +58 -0
  92. package/tsconfig.json +24 -0
@@ -0,0 +1,99 @@
1
+ .detail-side h2 {
2
+ padding-top: 0;
3
+ margin-top: 0;
4
+ margin-bottom: 4px;
5
+ }
6
+ .detail-side .ant-tag {
7
+ margin-top: 2px;
8
+ }
9
+ .detail-side .meta-kv {
10
+ padding: 10px 10px calc(10px + 4px);
11
+ }
12
+ .detail-side .meta-kv .meta {
13
+ box-sizing: border-box;
14
+ padding: 2px 0;
15
+ width: 100%;
16
+ display: flex;
17
+ flex-direction: row;
18
+ line-height: 1.5;
19
+ }
20
+ .detail-side .meta-kv .meta .meta-key {
21
+ width: 100px;
22
+ text-align: right;
23
+ padding-right: 10px;
24
+ }
25
+ .detail-side .meta-kv .meta .meta-value {
26
+ flex: 1 1;
27
+ }
28
+ .detail-side .item-list {
29
+ padding: 10px 10px;
30
+ cursor: default;
31
+ margin-bottom: 10px;
32
+ }
33
+ .detail-side .item-list .item {
34
+ padding: 16px 10px 10px;
35
+ transition: 0.1s;
36
+ border: 1px solid #DDD;
37
+ border-radius: 5px;
38
+ margin-bottom: 10px;
39
+ position: relative;
40
+ }
41
+ .detail-side .item-list .item.item-lite {
42
+ border: none;
43
+ padding: 0;
44
+ }
45
+ .detail-side .item-list .item-highlight {
46
+ color: #FFF;
47
+ }
48
+ .detail-side .item-list .item-highlight .subtitle {
49
+ color: #CCC;
50
+ }
51
+ .detail-side .item-list .item-extra {
52
+ position: absolute;
53
+ right: 10px;
54
+ top: 10px;
55
+ color: #777;
56
+ }
57
+ .detail-side .item-list .title-right-padding {
58
+ padding-right: 15px;
59
+ }
60
+ .detail-side .item-list .title {
61
+ font-size: 18px;
62
+ font-weight: bold;
63
+ margin-bottom: 5px;
64
+ }
65
+ .detail-side .item-list .title .title-tag {
66
+ display: inline-block;
67
+ margin-left: 6px;
68
+ color: #777;
69
+ font-size: 14px;
70
+ line-height: 18px;
71
+ }
72
+ .detail-side .item-list .subtitle {
73
+ font-weight: normal;
74
+ font-size: 14px;
75
+ color: #777;
76
+ }
77
+ .detail-side .item-list .description {
78
+ margin-top: 5px;
79
+ }
80
+ .detail-side .item-list .description-content {
81
+ font-size: 14px;
82
+ margin-top: 10px;
83
+ white-space: break-spaces;
84
+ margin: 0;
85
+ }
86
+ .detail-side .item-list .element-button:hover {
87
+ color: #fff;
88
+ background: #F9483E;
89
+ }
90
+ .detail-side .item-list .section-button:hover {
91
+ color: #fff;
92
+ background: #01204E;
93
+ }
94
+ .detail-side .context pre {
95
+ text-wrap: balance;
96
+ }
97
+ .detail-side .item-list-space-up {
98
+ margin-top: 10px;
99
+ }
@@ -0,0 +1,285 @@
1
+ "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __spreadValues = (a, b) => {
8
+ for (var prop in b || (b = {}))
9
+ if (__hasOwnProp.call(b, prop))
10
+ __defNormalProp(a, prop, b[prop]);
11
+ if (__getOwnPropSymbols)
12
+ for (var prop of __getOwnPropSymbols(b)) {
13
+ if (__propIsEnum.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ }
16
+ return a;
17
+ };
18
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
19
+ import "./detail-side.css";
20
+ import { RadiusSettingOutlined } from "@ant-design/icons";
21
+ import { Tooltip, Tag, Timeline } from "antd";
22
+ import { highlightColorForType } from "./color";
23
+ import { useExecutionDump, useInsightDump } from "./store";
24
+ import PanelTitle from "./panel-title";
25
+ import { timeCostStrElement } from "./misc";
26
+ import { timeStr, typeStr } from "../utils";
27
+ const noop = () => {
28
+ };
29
+ const Card = (props) => {
30
+ const { highlightWithColor, title, subtitle, onMouseEnter, onMouseLeave, content, characteristic } = props;
31
+ const titleTag = props.characteristic ? /* @__PURE__ */ jsx("div", { className: "item-extra", children: /* @__PURE__ */ jsx("div", { className: "title-tag", children: /* @__PURE__ */ jsx(Tooltip, { placement: "bottomRight", title: characteristic, mouseEnterDelay: 0, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(RadiusSettingOutlined, {}) }) }) }) }) : null;
32
+ const titleRightPaddingClass = props.characteristic ? "title-right-padding" : "";
33
+ const modeClass = props.liteMode ? "item-lite" : "";
34
+ const highlightStyle = highlightWithColor ? { backgroundColor: highlightWithColor } : {};
35
+ return /* @__PURE__ */ jsxs(
36
+ "div",
37
+ {
38
+ className: `item ${modeClass} ${highlightWithColor ? "item-highlight" : ""}`,
39
+ style: __spreadValues({}, highlightStyle),
40
+ onMouseEnter,
41
+ onMouseLeave,
42
+ children: [
43
+ /* @__PURE__ */ jsxs("div", { className: `title ${titleRightPaddingClass}`, style: { display: title ? "block" : "none" }, children: [
44
+ title,
45
+ titleTag
46
+ ] }),
47
+ /* @__PURE__ */ jsx("div", { className: `subtitle ${titleRightPaddingClass}`, style: { display: subtitle ? "block" : "none" }, children: subtitle }),
48
+ /* @__PURE__ */ jsx("div", { className: "description", style: { display: content ? "block" : "none" }, children: content })
49
+ ]
50
+ }
51
+ );
52
+ };
53
+ const MetaKV = (props) => {
54
+ return /* @__PURE__ */ jsx("div", { className: "meta-kv", children: props.data.map((item, index) => {
55
+ return /* @__PURE__ */ jsxs("div", { className: "meta", children: [
56
+ /* @__PURE__ */ jsx("div", { className: "meta-key", children: item.key }),
57
+ /* @__PURE__ */ jsx("div", { className: "meta-value", children: item.content })
58
+ ] }, index);
59
+ }) });
60
+ };
61
+ const objectWithoutKeys = (obj, keys) => Object.keys(obj).reduce((acc, key) => {
62
+ if (!keys.includes(key)) {
63
+ acc[key] = obj[key];
64
+ }
65
+ return acc;
66
+ }, {});
67
+ const DetailSide = () => {
68
+ var _a, _b, _c, _d, _e, _f, _g, _h;
69
+ const task = useExecutionDump((store) => store.activeTask);
70
+ const dump = useInsightDump((store) => store.data);
71
+ const { matchedSection: sections, matchedElement: elements } = dump || {};
72
+ const highlightSectionNames = useInsightDump((store) => store.highlightSectionNames);
73
+ const highlightElements = useInsightDump((store) => store.highlightElements);
74
+ const setHighlightSectionNames = useInsightDump((store) => store.setHighlightSectionNames);
75
+ const setHighlightElements = useInsightDump((store) => store.setHighlightElements);
76
+ const setHighlightSectionName = function(name) {
77
+ setHighlightSectionNames([name]);
78
+ };
79
+ const setHighlightElement = function(element) {
80
+ setHighlightElements([element]);
81
+ };
82
+ const unhighlightSection = function() {
83
+ setHighlightSectionNames([]);
84
+ };
85
+ const unhighlightElement = function() {
86
+ setHighlightElements([]);
87
+ };
88
+ const kv = function(data) {
89
+ const isElementItem = (value) => Boolean(value) && typeof value === "object" && typeof value.content !== "undefined" && Boolean(value.center) && Boolean(value.rect);
90
+ const isSectionItem = (value) => Boolean(value) && typeof (value == null ? void 0 : value.sectionCharacteristics) !== "undefined" && typeof (value == null ? void 0 : value.rect) !== "undefined";
91
+ const elementEl = (value) => /* @__PURE__ */ jsx(
92
+ "span",
93
+ {
94
+ onMouseEnter: () => {
95
+ setHighlightElement(value);
96
+ },
97
+ onMouseLeave: unhighlightElement,
98
+ children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "orange", className: "element-button", children: "Element" })
99
+ }
100
+ );
101
+ const sectionEl = (value) => /* @__PURE__ */ jsx(
102
+ "span",
103
+ {
104
+ onMouseEnter: () => {
105
+ setHighlightSectionName(value.name);
106
+ },
107
+ onMouseLeave: unhighlightSection,
108
+ children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "blue", className: "section-button", children: "Section" })
109
+ }
110
+ );
111
+ if (Array.isArray(data) || typeof data !== "object") {
112
+ return /* @__PURE__ */ jsx("pre", { className: "description-content", children: JSON.stringify(data, void 0, 2) });
113
+ }
114
+ return Object.keys(data).map((key) => {
115
+ const value = data[key];
116
+ let content;
117
+ if (typeof value === "object" && isElementItem(value)) {
118
+ content = elementEl(value);
119
+ } else if (Array.isArray(value) && value.some((item) => isElementItem(item))) {
120
+ content = value.map((item, index) => /* @__PURE__ */ jsx("span", { children: elementEl(item) }, index));
121
+ } else if (typeof value === "object" && isSectionItem(value)) {
122
+ content = sectionEl(value);
123
+ } else if (Array.isArray(value) && value.some((item) => isSectionItem(item))) {
124
+ content = value.map((item, index) => /* @__PURE__ */ jsx("span", { children: sectionEl(item) }, index));
125
+ } else {
126
+ content = typeof value === "string" ? value : JSON.stringify(value, void 0, 2);
127
+ }
128
+ return /* @__PURE__ */ jsxs("pre", { className: "description-content", children: [
129
+ key,
130
+ ": ",
131
+ content
132
+ ] }, key);
133
+ });
134
+ };
135
+ const metaKVElement = MetaKV({
136
+ data: [
137
+ {
138
+ key: "Status",
139
+ content: (task == null ? void 0 : task.status) || ""
140
+ },
141
+ {
142
+ key: "Start",
143
+ content: timeStr((_a = task == null ? void 0 : task.timing) == null ? void 0 : _a.start)
144
+ },
145
+ {
146
+ key: "End",
147
+ content: timeStr((_b = task == null ? void 0 : task.timing) == null ? void 0 : _b.end)
148
+ },
149
+ {
150
+ key: "Time Cost",
151
+ content: timeCostStrElement((_c = task == null ? void 0 : task.timing) == null ? void 0 : _c.cost)
152
+ }
153
+ ]
154
+ });
155
+ let taskParam = null;
156
+ if ((task == null ? void 0 : task.type) === "Planning") {
157
+ taskParam = MetaKV({
158
+ data: [
159
+ { key: "type", content: task && typeStr(task) || "" },
160
+ { key: "param", content: (_d = task == null ? void 0 : task.param) == null ? void 0 : _d.userPrompt }
161
+ ]
162
+ });
163
+ } else if ((task == null ? void 0 : task.type) === "Insight") {
164
+ taskParam = MetaKV({
165
+ data: [
166
+ { key: "type", content: task && typeStr(task) || "" },
167
+ {
168
+ key: "param",
169
+ content: JSON.stringify(
170
+ ((_e = task == null ? void 0 : task.param) == null ? void 0 : _e.prompt) || ((_f = task == null ? void 0 : task.param) == null ? void 0 : _f.dataDemand)
171
+ )
172
+ }
173
+ ]
174
+ });
175
+ } else if ((task == null ? void 0 : task.type) === "Action") {
176
+ taskParam = MetaKV({
177
+ data: [
178
+ { key: "type", content: task && typeStr(task) || "" },
179
+ {
180
+ key: "value",
181
+ content: JSON.stringify((_g = task == null ? void 0 : task.param) == null ? void 0 : _g.value, void 0, 2)
182
+ }
183
+ ]
184
+ });
185
+ }
186
+ const matchedSectionsEl = (sections == null ? void 0 : sections.length) ? sections.map((section) => {
187
+ const { name } = section;
188
+ const ifHighlight = highlightSectionNames.includes(name);
189
+ const kvToShow = objectWithoutKeys(section, [
190
+ "name",
191
+ "description",
192
+ "texts",
193
+ "rect",
194
+ "sectionCharacteristics"
195
+ ]);
196
+ const sectionKV = Object.keys(kvToShow).length ? kv(kvToShow) : null;
197
+ const highlightColor = ifHighlight ? highlightColorForType("section") : void 0;
198
+ return /* @__PURE__ */ jsx(
199
+ Card,
200
+ {
201
+ title: section.name,
202
+ highlightWithColor: highlightColor,
203
+ subtitle: section.description,
204
+ characteristic: section.sectionCharacteristics,
205
+ onMouseEnter: setHighlightSectionName.bind(void 0, name),
206
+ onMouseLeave: unhighlightSection,
207
+ content: sectionKV
208
+ },
209
+ name
210
+ );
211
+ }) : null;
212
+ const matchedElementsEl = (elements == null ? void 0 : elements.length) ? elements.map((element, idx) => {
213
+ const ifHighlight = highlightElements.includes(element);
214
+ const highlightColor = ifHighlight ? highlightColorForType("element") : void 0;
215
+ const elementKV = kv(
216
+ objectWithoutKeys(element, [
217
+ "content",
218
+ "rect",
219
+ "center",
220
+ "left",
221
+ "top",
222
+ "right",
223
+ "bottom",
224
+ "locator"
225
+ ])
226
+ );
227
+ return /* @__PURE__ */ jsx(
228
+ Card,
229
+ {
230
+ title: element.content,
231
+ highlightWithColor: highlightColor,
232
+ subtitle: "",
233
+ onMouseEnter: setHighlightElement.bind(void 0, element),
234
+ onMouseLeave: unhighlightElement,
235
+ content: elementKV
236
+ },
237
+ idx
238
+ );
239
+ }) : null;
240
+ const errorSection = (dump == null ? void 0 : dump.error) ? /* @__PURE__ */ jsx(
241
+ Card,
242
+ {
243
+ liteMode: true,
244
+ title: "Error",
245
+ onMouseEnter: noop,
246
+ onMouseLeave: noop,
247
+ content: /* @__PURE__ */ jsx("pre", { className: "description-content", style: { color: "#F00" }, children: dump.error })
248
+ }
249
+ ) : null;
250
+ const dataCard = (dump == null ? void 0 : dump.data) ? /* @__PURE__ */ jsx(Card, { liteMode: true, onMouseEnter: noop, onMouseLeave: noop, content: /* @__PURE__ */ jsx("pre", { children: kv(dump.data) }) }) : null;
251
+ const plans = (_h = task == null ? void 0 : task.output) == null ? void 0 : _h.plans;
252
+ let timelineData = [];
253
+ if (plans) {
254
+ timelineData = timelineData.concat(
255
+ plans.map((item) => {
256
+ return {
257
+ color: "#06B1AB",
258
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
259
+ /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("b", { children: typeStr(item) }) }),
260
+ /* @__PURE__ */ jsx("p", { children: item.thought }),
261
+ /* @__PURE__ */ jsx("p", { children: item.param ? JSON.stringify(item.param || {}, void 0, 2) : null })
262
+ ] })
263
+ };
264
+ })
265
+ );
266
+ }
267
+ return /* @__PURE__ */ jsxs("div", { className: "detail-side", children: [
268
+ /* @__PURE__ */ jsx(PanelTitle, { title: "Task Meta" }),
269
+ metaKVElement,
270
+ /* @__PURE__ */ jsx(PanelTitle, { title: "Param" }),
271
+ taskParam,
272
+ /* @__PURE__ */ jsx(PanelTitle, { title: "Output" }),
273
+ /* @__PURE__ */ jsxs("div", { className: "item-list item-list-space-up", children: [
274
+ errorSection,
275
+ dataCard,
276
+ matchedSectionsEl,
277
+ matchedElementsEl,
278
+ /* @__PURE__ */ jsx(Timeline, { items: timelineData })
279
+ ] })
280
+ ] });
281
+ };
282
+ var detail_side_default = DetailSide;
283
+ export {
284
+ detail_side_default as default
285
+ };
@@ -0,0 +1,19 @@
1
+ .global-hover-preview {
2
+ position: fixed;
3
+ display: block;
4
+ max-width: 400px;
5
+ max-height: 400px;
6
+ overflow: hidden;
7
+ z-index: 10;
8
+ text-align: center;
9
+ border: 1px solid #CCCCCC;
10
+ box-sizing: border-box;
11
+ background: #ECECEC;
12
+ box-shadow: 1px 1px 5px 0 rgba(0, 0, 0, 0.2);
13
+ }
14
+ .global-hover-preview img {
15
+ max-width: 400px;
16
+ max-height: 400px;
17
+ width: auto;
18
+ height: auto;
19
+ }
@@ -0,0 +1,44 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useRef, useState } from "react";
3
+ import { useExecutionDump } from "./store";
4
+ import "./global-hover-preview.css";
5
+ const size = 400;
6
+ const GlobalHoverPreview = () => {
7
+ var _a;
8
+ const wrapperRef = useRef(null);
9
+ const hoverTask = useExecutionDump((store) => store.hoverTask);
10
+ const hoverPreviewConfig = useExecutionDump((store) => store.hoverPreviewConfig);
11
+ const [imageW, setImageW] = useState(size);
12
+ const [imageH, setImageH] = useState(size);
13
+ const images = (_a = hoverTask == null ? void 0 : hoverTask.recorder) == null ? void 0 : _a.filter((item) => {
14
+ return item.screenshot;
15
+ }).map((item) => item.screenshot);
16
+ const { x, y } = hoverPreviewConfig || {};
17
+ let left = 0;
18
+ let top = 0;
19
+ const shouldShow = (images == null ? void 0 : images.length) && typeof x !== "undefined" && typeof y !== "undefined";
20
+ if (shouldShow) {
21
+ const { clientWidth, clientHeight } = document.body;
22
+ const widthInPractice = imageW >= imageH ? size : size * (imageW / imageH);
23
+ const heightInPractice = imageW >= imageH ? size * (imageH / imageW) : size;
24
+ left = x + widthInPractice > clientWidth ? clientWidth - widthInPractice : x;
25
+ top = y + heightInPractice > clientHeight ? clientHeight - heightInPractice : y;
26
+ }
27
+ return shouldShow ? /* @__PURE__ */ jsx("div", { className: "global-hover-preview", style: { left, top }, ref: wrapperRef, children: (images == null ? void 0 : images.length) ? /* @__PURE__ */ jsx(
28
+ "img",
29
+ {
30
+ src: images[0],
31
+ onLoad: (img) => {
32
+ const imgElement = img.target;
33
+ const width = imgElement.naturalWidth;
34
+ const height = imgElement.naturalHeight;
35
+ setImageW(width);
36
+ setImageH(height);
37
+ }
38
+ }
39
+ ) : null }) : null;
40
+ };
41
+ var global_hover_preview_default = GlobalHoverPreview;
42
+ export {
43
+ global_hover_preview_default as default
44
+ };
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ function timeCostStrElement(timeCost) {
3
+ let str;
4
+ if (typeof timeCost !== "number") {
5
+ str = "- ms";
6
+ } else if (timeCost > 1e3) {
7
+ str = `${(timeCost / 1e3).toFixed(2)}s`;
8
+ } else {
9
+ str = `${timeCost}ms`;
10
+ }
11
+ return /* @__PURE__ */ jsx(
12
+ "span",
13
+ {
14
+ style: {
15
+ fontVariantNumeric: "tabular-nums",
16
+ fontFeatureSettings: "tnum"
17
+ },
18
+ children: str
19
+ }
20
+ );
21
+ }
22
+ export {
23
+ timeCostStrElement
24
+ };
@@ -0,0 +1,8 @@
1
+ .task-list-name {
2
+ padding: 2px 10px;
3
+ font-weight: bold;
4
+ background: #DDDDDD;
5
+ border-top: 1px solid #CCCCCC;
6
+ border-bottom: 1px solid #CCCCCC;
7
+ margin-top: -1px;
8
+ }
@@ -0,0 +1,9 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import "./panel-title.css";
3
+ const PanelTitle = (props) => {
4
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("div", { className: "task-list-name", children: props.title }) });
5
+ };
6
+ var panel_title_default = PanelTitle;
7
+ export {
8
+ panel_title_default as default
9
+ };
File without changes
@@ -0,0 +1,87 @@
1
+ .side-bar {
2
+ display: flex;
3
+ flex-direction: column;
4
+ justify-content: space-between;
5
+ width: 100%;
6
+ height: 100%;
7
+ border-right: 1px solid #CCCCCC;
8
+ overflow: auto;
9
+ background: #ECECEC;
10
+ }
11
+ .side-bar .brand {
12
+ padding: 10px 5px;
13
+ cursor: pointer;
14
+ }
15
+ .side-bar .task-meta-section {
16
+ margin-top: 6px;
17
+ }
18
+ .side-bar .task-meta {
19
+ color: #777;
20
+ font-weight: normal;
21
+ padding-left: 10px;
22
+ }
23
+ .side-bar .side-seperator {
24
+ border-top: 1px solid none;
25
+ }
26
+ .side-bar .side-seperator.side-seperator-line {
27
+ border-top: 1px solid #CCCCCC;
28
+ }
29
+ .side-bar .side-seperator.side-seperator-space-up {
30
+ margin-top: 10px;
31
+ }
32
+ .side-bar .side-seperator.side-seperator-space-down {
33
+ margin-bottom: 10px;
34
+ }
35
+ .side-bar .side-sub-title {
36
+ padding: 0 10px;
37
+ font-weight: bold;
38
+ }
39
+ .side-bar .side-item {
40
+ cursor: pointer;
41
+ transition: 0.1s;
42
+ padding: 2px 0;
43
+ }
44
+ .side-bar .side-item:hover {
45
+ background: #A3D6D2;
46
+ color: #333;
47
+ }
48
+ .side-bar .side-item.selected {
49
+ background: #06B1AB;
50
+ color: #ffffff;
51
+ }
52
+ .side-bar .side-item.selected .status-text {
53
+ color: #ffffff;
54
+ }
55
+ .side-bar .side-item .side-item-content {
56
+ padding: 0 10px 0 calc(10px + 16px);
57
+ }
58
+ .side-bar .side-item-name {
59
+ padding: 0 10px 0 calc(10px + 16px);
60
+ position: relative;
61
+ display: flex;
62
+ justify-content: space-between;
63
+ }
64
+ .side-bar .side-item-name .status-icon {
65
+ position: absolute;
66
+ left: 10px;
67
+ display: inline-block;
68
+ color: #AAA;
69
+ font-size: 10px;
70
+ line-height: 10px;
71
+ top: 50%;
72
+ margin-top: -5px;
73
+ }
74
+ .side-bar .side-item-name .status-icon-success {
75
+ color: #3a773a;
76
+ }
77
+ .side-bar .side-item-name .status-icon-fail {
78
+ color: #ff0a0a;
79
+ }
80
+ .side-bar .side-item-name .status-text {
81
+ color: #777;
82
+ }
83
+ .side-bar .bottom-controls {
84
+ padding: 10px 10px;
85
+ text-align: left;
86
+ text-align: center;
87
+ }