@midscene/visualizer 0.6.1 → 0.6.2
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/player.js +26 -23
- package/dist/es/component/replay-scripts.js +4 -4
- package/dist/es/component/store.js +64 -22
- package/dist/es/index.css +20 -0
- package/dist/es/index.js +54 -40
- package/dist/index.css +20 -0
- package/dist/index.js +1 -1
- package/dist/lib/component/player.js +25 -19
- package/dist/lib/component/replay-scripts.js +4 -4
- package/dist/lib/component/store.js +64 -22
- package/dist/lib/index.css +20 -0
- package/dist/lib/index.js +49 -38
- package/dist/report/demo-mobile.html +21 -1
- package/dist/report/demo.html +21 -1
- package/dist/report/empty-error.html +21 -1
- package/dist/report/index.css +20 -0
- package/dist/report/index.html +21 -1
- package/dist/report/index.js +1 -1
- package/dist/report/multi.html +21 -1
- package/dist/types/component/store.d.ts +5 -2
- package/package.json +4 -2
|
@@ -40,10 +40,7 @@ import * as PIXI from "pixi.js";
|
|
|
40
40
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
41
41
|
import "./player.css";
|
|
42
42
|
import { mouseLoading, mousePointer } from "../utils";
|
|
43
|
-
import {
|
|
44
|
-
LoadingOutlined,
|
|
45
|
-
PlayCircleOutlined
|
|
46
|
-
} from "@ant-design/icons";
|
|
43
|
+
import { CaretRightOutlined, LoadingOutlined } from "@ant-design/icons";
|
|
47
44
|
import { ConfigProvider, Spin } from "antd";
|
|
48
45
|
import { rectMarkForItem } from "./blackboard";
|
|
49
46
|
import { useExecutionDump } from "./store";
|
|
@@ -68,7 +65,7 @@ const linear = (t) => {
|
|
|
68
65
|
const sleep = (ms) => {
|
|
69
66
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
70
67
|
};
|
|
71
|
-
const ERROR_FRAME_CANCEL = "frame cancel";
|
|
68
|
+
const ERROR_FRAME_CANCEL = "frame cancel (this is an error on purpose)";
|
|
72
69
|
const frameKit = () => {
|
|
73
70
|
let cancelFlag = false;
|
|
74
71
|
return {
|
|
@@ -95,7 +92,6 @@ const frameKit = () => {
|
|
|
95
92
|
}, ms);
|
|
96
93
|
},
|
|
97
94
|
cancel: () => {
|
|
98
|
-
console.log("set frame cancel");
|
|
99
95
|
cancelFlag = true;
|
|
100
96
|
}
|
|
101
97
|
};
|
|
@@ -109,13 +105,16 @@ const Player = () => {
|
|
|
109
105
|
var _a;
|
|
110
106
|
const [titleText, setTitleText] = useState("");
|
|
111
107
|
const [subTitleText, setSubTitleText] = useState("");
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
(store) => store.activeExecutionScreenshotWidth
|
|
108
|
+
const taskScripts = useExecutionDump(
|
|
109
|
+
(store) => store.activeExecutionAnimation
|
|
115
110
|
);
|
|
116
|
-
const
|
|
117
|
-
|
|
111
|
+
const replayAllMode = useExecutionDump((store) => store.replayAllMode);
|
|
112
|
+
const replayAllScripts = useExecutionDump(
|
|
113
|
+
(store) => store.allExecutionAnimation
|
|
118
114
|
);
|
|
115
|
+
const scripts = replayAllMode ? replayAllScripts : taskScripts;
|
|
116
|
+
const imageWidth = useExecutionDump((store) => store.insightWidth) || 1920;
|
|
117
|
+
const imageHeight = useExecutionDump((store) => store.insightHeight) || 1080;
|
|
119
118
|
const canvasWidth = imageWidth + canvasPaddingLeft * 2;
|
|
120
119
|
const canvasHeight = imageHeight + canvasPaddingTop * 2;
|
|
121
120
|
const currentImg = useRef(((_a = scripts == null ? void 0 : scripts[0]) == null ? void 0 : _a.img) || null);
|
|
@@ -139,8 +138,8 @@ const Player = () => {
|
|
|
139
138
|
top: 0,
|
|
140
139
|
width: imageWidth,
|
|
141
140
|
pointer: {
|
|
142
|
-
left: imageWidth / 2,
|
|
143
|
-
top: imageHeight / 2
|
|
141
|
+
left: Math.round(imageWidth / 2),
|
|
142
|
+
top: Math.round(imageHeight / 2)
|
|
144
143
|
}
|
|
145
144
|
};
|
|
146
145
|
const [animationProgress, setAnimationProgress] = useState(-1);
|
|
@@ -285,14 +284,18 @@ const Player = () => {
|
|
|
285
284
|
const animate = (currentTime) => {
|
|
286
285
|
const nextState = __spreadValues({}, cameraState.current);
|
|
287
286
|
const elapsedTime = currentTime - startTime;
|
|
288
|
-
if (shouldMovePointer
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
287
|
+
if (shouldMovePointer) {
|
|
288
|
+
if (elapsedTime <= pointerMoveDuration) {
|
|
289
|
+
const rawMouseProgress = Math.min(
|
|
290
|
+
elapsedTime / pointerMoveDuration,
|
|
291
|
+
1
|
|
292
|
+
);
|
|
293
|
+
const mouseProgress = cubicMouse(rawMouseProgress);
|
|
294
|
+
nextState.pointer.left = startPointer.left + (targetState.pointer.left - startPointer.left) * mouseProgress;
|
|
295
|
+
nextState.pointer.top = startPointer.top + (targetState.pointer.top - startPointer.top) * mouseProgress;
|
|
296
|
+
} else {
|
|
297
|
+
nextState.pointer = targetState.pointer;
|
|
298
|
+
}
|
|
296
299
|
}
|
|
297
300
|
if (elapsedTime > cameraMoveStart) {
|
|
298
301
|
const cameraElapsedTime = elapsedTime - cameraMoveStart;
|
|
@@ -547,13 +550,13 @@ const Player = () => {
|
|
|
547
550
|
if (animationProgress < 1) {
|
|
548
551
|
statusIconElement = /* @__PURE__ */ jsx(Spin, { indicator: /* @__PURE__ */ jsx(LoadingOutlined, { spin: true }), size: "default" });
|
|
549
552
|
} else if (mouseOverStatusIcon) {
|
|
550
|
-
statusIconElement = /* @__PURE__ */ jsx(Spin, { indicator: /* @__PURE__ */ jsx(
|
|
553
|
+
statusIconElement = /* @__PURE__ */ jsx(Spin, { indicator: /* @__PURE__ */ jsx(CaretRightOutlined, {}), size: "default" });
|
|
551
554
|
statusStyle.cursor = "pointer";
|
|
552
555
|
statusStyle.background = "#888";
|
|
553
556
|
statusOnClick = () => setReplayMark(Date.now());
|
|
554
557
|
} else {
|
|
555
558
|
statusIconElement = // <Spin indicator={<CheckCircleOutlined />} size="default" />
|
|
556
|
-
/* @__PURE__ */ jsx(Spin, { indicator: /* @__PURE__ */ jsx(
|
|
559
|
+
/* @__PURE__ */ jsx(Spin, { indicator: /* @__PURE__ */ jsx(CaretRightOutlined, {}), size: "default" });
|
|
557
560
|
}
|
|
558
561
|
return /* @__PURE__ */ jsxs("div", { className: "player-container", children: [
|
|
559
562
|
/* @__PURE__ */ jsx("div", { className: "canvas-container", ref: divContainerRef }),
|
|
@@ -50,9 +50,9 @@ const cameraStateForRect = (rect, imageWidth, imageHeight) => {
|
|
|
50
50
|
);
|
|
51
51
|
top = Math.max(top, 0);
|
|
52
52
|
return {
|
|
53
|
-
left,
|
|
54
|
-
top,
|
|
55
|
-
width: cameraWidth
|
|
53
|
+
left: Math.round(left),
|
|
54
|
+
top: Math.round(top),
|
|
55
|
+
width: Math.round(cameraWidth)
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
58
|
const mergeTwoCameraState = (cameraState1, cameraState2) => {
|
|
@@ -208,7 +208,7 @@ const generateAnimationScripts = (execution, imageWidth, imageHeight) => {
|
|
|
208
208
|
title: "Done",
|
|
209
209
|
subTitle: initSubTitle,
|
|
210
210
|
type: "img",
|
|
211
|
-
duration: stillDuration
|
|
211
|
+
duration: stillDuration,
|
|
212
212
|
camera: fullPageCameraState
|
|
213
213
|
});
|
|
214
214
|
return scripts;
|
|
@@ -35,11 +35,13 @@ const useExecutionDump = create((set, get) => {
|
|
|
35
35
|
const initData = {
|
|
36
36
|
dump: null,
|
|
37
37
|
activeTask: null,
|
|
38
|
+
replayAllMode: false,
|
|
39
|
+
allExecutionAnimation: null,
|
|
40
|
+
insightWidth: null,
|
|
41
|
+
insightHeight: null,
|
|
38
42
|
activeExecution: null,
|
|
39
43
|
activeExecutionAnimation: null,
|
|
40
44
|
// TODO: get from dump
|
|
41
|
-
activeExecutionScreenshotWidth: 0,
|
|
42
|
-
activeExecutionScreenshotHeight: 0,
|
|
43
45
|
hoverTask: null,
|
|
44
46
|
hoverTimestamp: null,
|
|
45
47
|
hoverPreviewConfig: null
|
|
@@ -52,22 +54,75 @@ const useExecutionDump = create((set, get) => {
|
|
|
52
54
|
const { reset } = useInsightDump.getState();
|
|
53
55
|
reset();
|
|
54
56
|
};
|
|
57
|
+
const resetActiveExecution = () => {
|
|
58
|
+
set({
|
|
59
|
+
activeExecution: null,
|
|
60
|
+
activeExecutionAnimation: null,
|
|
61
|
+
_executionDumpLoadId: ++_executionDumpLoadId
|
|
62
|
+
});
|
|
63
|
+
resetInsightDump();
|
|
64
|
+
};
|
|
55
65
|
return __spreadProps(__spreadValues({}, initData), {
|
|
56
66
|
_executionDumpLoadId,
|
|
67
|
+
setReplayAllMode: (replayAllMode) => {
|
|
68
|
+
const state = get();
|
|
69
|
+
if (state.allExecutionAnimation) {
|
|
70
|
+
set({ replayAllMode });
|
|
71
|
+
if (replayAllMode) {
|
|
72
|
+
resetActiveExecution();
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
console.error(
|
|
76
|
+
"allExecutionAnimation not found, failed to set replayAllMode"
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
57
80
|
setGroupedDump: (dump) => {
|
|
58
81
|
console.log("will set ExecutionDump", dump);
|
|
59
82
|
set(__spreadProps(__spreadValues({}, initData), {
|
|
60
83
|
dump
|
|
61
84
|
}));
|
|
62
85
|
resetInsightDump();
|
|
63
|
-
if (dump && dump.executions.length > 0
|
|
64
|
-
|
|
86
|
+
if (dump && dump.executions.length > 0) {
|
|
87
|
+
let width = 0;
|
|
88
|
+
let height = 0;
|
|
89
|
+
dump.executions.forEach((execution) => {
|
|
90
|
+
execution.tasks.forEach((task) => {
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
92
|
+
if (task.type === "Insight") {
|
|
93
|
+
const insightTask = task;
|
|
94
|
+
width = ((_d = (_c = (_b = (_a = insightTask.log) == null ? void 0 : _a.dump) == null ? void 0 : _b.context) == null ? void 0 : _c.size) == null ? void 0 : _d.width) || 1920;
|
|
95
|
+
height = ((_h = (_g = (_f = (_e = insightTask.log) == null ? void 0 : _e.dump) == null ? void 0 : _f.context) == null ? void 0 : _g.size) == null ? void 0 : _h.height) || 1080;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
if (!width || !height) {
|
|
100
|
+
console.warn(
|
|
101
|
+
"width or height not found, failed to generate animation"
|
|
102
|
+
);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const allScripts = [];
|
|
106
|
+
dump.executions.forEach((execution) => {
|
|
107
|
+
const scripts = generateAnimationScripts(execution, width, height);
|
|
108
|
+
if (scripts) {
|
|
109
|
+
allScripts.push(...scripts);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
set({
|
|
113
|
+
allExecutionAnimation: allScripts,
|
|
114
|
+
_executionDumpLoadId: ++_executionDumpLoadId,
|
|
115
|
+
replayAllMode: true,
|
|
116
|
+
insightWidth: width,
|
|
117
|
+
insightHeight: height
|
|
118
|
+
});
|
|
65
119
|
}
|
|
66
120
|
},
|
|
67
121
|
setActiveTask(task) {
|
|
68
122
|
var _a;
|
|
69
123
|
let parentExecution;
|
|
70
|
-
const
|
|
124
|
+
const state = get();
|
|
125
|
+
const dump = state.dump;
|
|
71
126
|
if (dump) {
|
|
72
127
|
parentExecution = dump.executions.find(
|
|
73
128
|
(execution) => execution.tasks.includes(task)
|
|
@@ -76,27 +131,14 @@ const useExecutionDump = create((set, get) => {
|
|
|
76
131
|
if (!parentExecution) {
|
|
77
132
|
throw new Error("parentExecution not found");
|
|
78
133
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
parentExecution.tasks.forEach((t) => {
|
|
82
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
83
|
-
if (t.type === "Insight") {
|
|
84
|
-
const insightTask = t;
|
|
85
|
-
width = ((_d = (_c = (_b = (_a2 = insightTask.log) == null ? void 0 : _a2.dump) == null ? void 0 : _b.context) == null ? void 0 : _c.size) == null ? void 0 : _d.width) || 1920;
|
|
86
|
-
height = ((_h = (_g = (_f = (_e = insightTask.log) == null ? void 0 : _e.dump) == null ? void 0 : _f.context) == null ? void 0 : _g.size) == null ? void 0 : _h.height) || 1080;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
134
|
+
const width = state.insightWidth;
|
|
135
|
+
const height = state.insightHeight;
|
|
89
136
|
set({
|
|
137
|
+
replayAllMode: false,
|
|
90
138
|
activeTask: task,
|
|
91
139
|
activeExecution: parentExecution,
|
|
92
140
|
_executionDumpLoadId: ++_executionDumpLoadId,
|
|
93
|
-
activeExecutionAnimation: generateAnimationScripts(
|
|
94
|
-
parentExecution,
|
|
95
|
-
width,
|
|
96
|
-
height
|
|
97
|
-
),
|
|
98
|
-
activeExecutionScreenshotWidth: width,
|
|
99
|
-
activeExecutionScreenshotHeight: height
|
|
141
|
+
activeExecutionAnimation: width && height ? generateAnimationScripts(parentExecution, width, height) : null
|
|
100
142
|
});
|
|
101
143
|
console.log("will set task", task);
|
|
102
144
|
if (task.type === "Insight") {
|
package/dist/es/index.css
CHANGED
|
@@ -78,6 +78,17 @@ footer.mt-8 {
|
|
|
78
78
|
display: flex;
|
|
79
79
|
flex-direction: row;
|
|
80
80
|
background: #F8F8F8;
|
|
81
|
+
justify-content: space-between;
|
|
82
|
+
}
|
|
83
|
+
.page-nav .page-nav-left {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: row;
|
|
86
|
+
}
|
|
87
|
+
.page-nav .page-nav-toolbar {
|
|
88
|
+
margin-left: 20px;
|
|
89
|
+
}
|
|
90
|
+
.page-nav .page-nav-toolbar .ant-btn {
|
|
91
|
+
background: #E9E9E9;
|
|
81
92
|
}
|
|
82
93
|
.page-nav .logo img {
|
|
83
94
|
height: 20px;
|
|
@@ -103,6 +114,15 @@ footer.mt-8 {
|
|
|
103
114
|
height: 100%;
|
|
104
115
|
box-sizing: border-box;
|
|
105
116
|
}
|
|
117
|
+
.main-right .replay-all-mode-wrapper {
|
|
118
|
+
height: 100%;
|
|
119
|
+
display: flex;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
padding: 22px;
|
|
123
|
+
box-sizing: border-box;
|
|
124
|
+
margin: 0 auto;
|
|
125
|
+
}
|
|
106
126
|
.main-right .main-content {
|
|
107
127
|
display: flex;
|
|
108
128
|
flex-direction: row;
|
package/dist/es/index.js
CHANGED
|
@@ -22,9 +22,12 @@ import "./index.css";
|
|
|
22
22
|
import DetailSide from "./component/detail-side";
|
|
23
23
|
import Sidebar from "./component/sidebar";
|
|
24
24
|
import { useExecutionDump } from "./component/store";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
CaretRightOutlined,
|
|
27
|
+
DownOutlined
|
|
28
|
+
} from "@ant-design/icons";
|
|
26
29
|
import { Helmet } from "@modern-js/runtime/head";
|
|
27
|
-
import { Alert, ConfigProvider, Dropdown,
|
|
30
|
+
import { Alert, Button, ConfigProvider, Dropdown, Upload, message } from "antd";
|
|
28
31
|
import { useEffect, useRef, useState } from "react";
|
|
29
32
|
import ReactDOM from "react-dom/client";
|
|
30
33
|
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
|
@@ -32,12 +35,21 @@ import logo from "./assets/logo-plain.0f78df8a.png";
|
|
|
32
35
|
import DetailPanel from "./component/detail-panel";
|
|
33
36
|
import GlobalHoverPreview from "./component/global-hover-preview";
|
|
34
37
|
import { iconForStatus, timeCostStrElement } from "./component/misc";
|
|
38
|
+
import Player from "./component/player";
|
|
35
39
|
import Timeline from "./component/timeline";
|
|
36
40
|
const { Dragger } = Upload;
|
|
37
41
|
let globalRenderCount = 1;
|
|
38
42
|
function Visualizer(props) {
|
|
39
43
|
const { dumps, hideLogo = false } = props;
|
|
40
44
|
const executionDump = useExecutionDump((store) => store.dump);
|
|
45
|
+
const executionDumpLoadId = useExecutionDump(
|
|
46
|
+
(store) => store._executionDumpLoadId
|
|
47
|
+
);
|
|
48
|
+
const replayAllMode = useExecutionDump((store) => store.replayAllMode);
|
|
49
|
+
const setReplayAllMode = useExecutionDump((store) => store.setReplayAllMode);
|
|
50
|
+
const replayAllScripts = useExecutionDump(
|
|
51
|
+
(store) => store.allExecutionAnimation
|
|
52
|
+
);
|
|
41
53
|
const setGroupedDump = useExecutionDump((store) => store.setGroupedDump);
|
|
42
54
|
const reset = useExecutionDump((store) => store.reset);
|
|
43
55
|
const [mainLayoutChangeFlag, setMainLayoutChangeFlag] = useState(0);
|
|
@@ -117,6 +129,11 @@ function Visualizer(props) {
|
|
|
117
129
|
/* @__PURE__ */ jsx("p", { className: "ant-upload-text", children: "All data will be processed locally by the browser. No data will be sent to the server." })
|
|
118
130
|
] })) });
|
|
119
131
|
} else {
|
|
132
|
+
const content = replayAllMode ? /* @__PURE__ */ jsx("div", { className: "replay-all-mode-wrapper", children: /* @__PURE__ */ jsx(Player, {}, executionDumpLoadId) }) : /* @__PURE__ */ jsxs(PanelGroup, { autoSaveId: "page-detail-layout-v2", direction: "horizontal", children: [
|
|
133
|
+
/* @__PURE__ */ jsx(Panel, { defaultSize: 75, maxSize: 95, children: /* @__PURE__ */ jsx("div", { className: "main-content-container", children: /* @__PURE__ */ jsx(DetailPanel, {}) }) }),
|
|
134
|
+
/* @__PURE__ */ jsx(PanelResizeHandle, {}),
|
|
135
|
+
/* @__PURE__ */ jsx(Panel, { maxSize: 95, children: /* @__PURE__ */ jsx("div", { className: "main-side", children: /* @__PURE__ */ jsx(DetailSide, {}) }) })
|
|
136
|
+
] });
|
|
120
137
|
mainContent = /* @__PURE__ */ jsxs(
|
|
121
138
|
PanelGroup,
|
|
122
139
|
{
|
|
@@ -142,18 +159,7 @@ function Visualizer(props) {
|
|
|
142
159
|
),
|
|
143
160
|
/* @__PURE__ */ jsx(Panel, { defaultSize: 80, maxSize: 95, children: /* @__PURE__ */ jsxs("div", { className: "main-right", children: [
|
|
144
161
|
/* @__PURE__ */ jsx(Timeline, {}, mainLayoutChangeFlag),
|
|
145
|
-
/* @__PURE__ */ jsx("div", { className: "main-content", children:
|
|
146
|
-
PanelGroup,
|
|
147
|
-
{
|
|
148
|
-
autoSaveId: "page-detail-layout-v2",
|
|
149
|
-
direction: "horizontal",
|
|
150
|
-
children: [
|
|
151
|
-
/* @__PURE__ */ jsx(Panel, { defaultSize: 75, maxSize: 95, children: /* @__PURE__ */ jsx("div", { className: "main-content-container", children: /* @__PURE__ */ jsx(DetailPanel, {}) }) }),
|
|
152
|
-
/* @__PURE__ */ jsx(PanelResizeHandle, {}),
|
|
153
|
-
/* @__PURE__ */ jsx(Panel, { maxSize: 95, children: /* @__PURE__ */ jsx("div", { className: "main-side", children: /* @__PURE__ */ jsx(DetailSide, {}) }) })
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
) })
|
|
162
|
+
/* @__PURE__ */ jsx("div", { className: "main-content", children: content })
|
|
157
163
|
] }) })
|
|
158
164
|
]
|
|
159
165
|
}
|
|
@@ -185,25 +191,6 @@ function Visualizer(props) {
|
|
|
185
191
|
globalRenderCount += 1;
|
|
186
192
|
};
|
|
187
193
|
}, []);
|
|
188
|
-
const selectOptions = dumps == null ? void 0 : dumps.map((dump, index) => ({
|
|
189
|
-
value: index,
|
|
190
|
-
label: `${dump.groupName} - ${dump.groupDescription}`,
|
|
191
|
-
groupName: dump.groupName,
|
|
192
|
-
groupDescription: dump.groupDescription
|
|
193
|
-
}));
|
|
194
|
-
const selectWidget = selectOptions && selectOptions.length > 1 ? /* @__PURE__ */ jsx(
|
|
195
|
-
Select,
|
|
196
|
-
{
|
|
197
|
-
options: selectOptions,
|
|
198
|
-
defaultValue: 0,
|
|
199
|
-
onChange: (value) => {
|
|
200
|
-
const dump = dumps[value];
|
|
201
|
-
setGroupedDump(dump);
|
|
202
|
-
},
|
|
203
|
-
defaultOpen: true,
|
|
204
|
-
style: { width: "100%" }
|
|
205
|
-
}
|
|
206
|
-
) : null;
|
|
207
194
|
return /* @__PURE__ */ jsxs(
|
|
208
195
|
ConfigProvider,
|
|
209
196
|
{
|
|
@@ -226,13 +213,40 @@ function Visualizer(props) {
|
|
|
226
213
|
style: { height: containerHeight },
|
|
227
214
|
children: [
|
|
228
215
|
/* @__PURE__ */ jsxs("div", { className: "page-nav", children: [
|
|
229
|
-
/* @__PURE__ */
|
|
230
|
-
"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
216
|
+
/* @__PURE__ */ jsxs("div", { className: "page-nav-left", children: [
|
|
217
|
+
/* @__PURE__ */ jsx("div", { className: "logo", children: /* @__PURE__ */ jsx(
|
|
218
|
+
"img",
|
|
219
|
+
{
|
|
220
|
+
alt: "Midscene_logo",
|
|
221
|
+
src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/vhaeh7vhabf/logo-light-with-text.png"
|
|
222
|
+
}
|
|
223
|
+
) }),
|
|
224
|
+
/* @__PURE__ */ jsx("div", { className: "page-nav-toolbar", children: /* @__PURE__ */ jsx(
|
|
225
|
+
ConfigProvider,
|
|
226
|
+
{
|
|
227
|
+
theme: {
|
|
228
|
+
components: {
|
|
229
|
+
Button: { textHoverBg: "#bfc4da80" }
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
children: /* @__PURE__ */ jsx(
|
|
233
|
+
Button,
|
|
234
|
+
{
|
|
235
|
+
type: "text",
|
|
236
|
+
icon: /* @__PURE__ */ jsx(CaretRightOutlined, {}),
|
|
237
|
+
disabled: !replayAllScripts || replayAllScripts.length === 0,
|
|
238
|
+
style: {
|
|
239
|
+
background: replayAllMode ? "#bfc4da80" : void 0
|
|
240
|
+
},
|
|
241
|
+
onClick: () => {
|
|
242
|
+
setReplayAllMode(true);
|
|
243
|
+
},
|
|
244
|
+
children: "Replay All"
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
) })
|
|
249
|
+
] }),
|
|
236
250
|
/* @__PURE__ */ jsx(
|
|
237
251
|
PlaywrightCaseSelector,
|
|
238
252
|
{
|
package/dist/index.css
CHANGED
|
@@ -79,6 +79,17 @@ footer.mt-8 {
|
|
|
79
79
|
display: flex;
|
|
80
80
|
flex-direction: row;
|
|
81
81
|
background: #F8F8F8;
|
|
82
|
+
justify-content: space-between;
|
|
83
|
+
}
|
|
84
|
+
.page-nav .page-nav-left {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: row;
|
|
87
|
+
}
|
|
88
|
+
.page-nav .page-nav-toolbar {
|
|
89
|
+
margin-left: 20px;
|
|
90
|
+
}
|
|
91
|
+
.page-nav .page-nav-toolbar .ant-btn {
|
|
92
|
+
background: #E9E9E9;
|
|
82
93
|
}
|
|
83
94
|
.page-nav .logo img {
|
|
84
95
|
height: 20px;
|
|
@@ -104,6 +115,15 @@ footer.mt-8 {
|
|
|
104
115
|
height: 100%;
|
|
105
116
|
box-sizing: border-box;
|
|
106
117
|
}
|
|
118
|
+
.main-right .replay-all-mode-wrapper {
|
|
119
|
+
height: 100%;
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
padding: 22px;
|
|
124
|
+
box-sizing: border-box;
|
|
125
|
+
margin: 0 auto;
|
|
126
|
+
}
|
|
107
127
|
.main-right .main-content {
|
|
108
128
|
display: flex;
|
|
109
129
|
flex-direction: row;
|