Skip to content

Commit d0ab581

Browse files
committed
feat(playground): add history modal overlay and improve layout in HistorySelector component
1 parent 8f33cb1 commit d0ab581

File tree

6 files changed

+90
-123
lines changed

6 files changed

+90
-123
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.history-modal-overlay {
2+
position: fixed;
3+
}

apps/chrome-extension/src/components/playground/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { useEnvConfig } from '@midscene/visualizer';
77
import { useCallback, useEffect, useMemo, useRef } from 'react';
88
import { getExtensionVersion } from '../../utils/chrome';
9+
import './index.less';
910

1011
declare const __SDK_VERSION__: string;
1112

@@ -56,7 +57,6 @@ export function BrowserExtensionPlayground({
5657
});
5758
currentAgent.current = agent;
5859

59-
6060
console.log(
6161
'[DEBUG] Chrome extension PlaygroundSDK created, ID:',
6262
sdkRef.current.id,
@@ -85,15 +85,16 @@ export function BrowserExtensionPlayground({
8585
// Use effect to ensure progress callbacks are properly forwarded
8686
useEffect(() => {
8787
if (playgroundSDK && !(playgroundSDK as any)._progressCallbackSetup) {
88-
const originalOnProgressUpdate = playgroundSDK.onProgressUpdate?.bind(playgroundSDK);
89-
88+
const originalOnProgressUpdate =
89+
playgroundSDK.onProgressUpdate?.bind(playgroundSDK);
90+
9091
playgroundSDK.onProgressUpdate = (callback: (tip: string) => void) => {
9192
// Forward to original method if it exists
9293
if (originalOnProgressUpdate) {
9394
originalOnProgressUpdate(callback);
9495
}
9596
};
96-
97+
9798
(playgroundSDK as any)._progressCallbackSetup = true;
9899
}
99100
}, [playgroundSDK]);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"private": true,
44
"version": "0.28.6",
55
"scripts": {
6-
"dev": "nx run-many --target=build:watch --exclude=android-playground,chrome-extension,@midscene/report,doc --verbose --parallel=9",
6+
"dev": "nx run-many --target=build:watch --exclude=android-playground,chrome-extension,@midscene/report,doc --verbose --parallel=6",
77
"build": "nx run-many --target=build --exclude=doc --verbose",
88
"build:skip-cache": "nx run-many --target=build --exclude=doc --verbose --skip-nx-cache",
99
"test": "nx run-many --target=test --projects=@midscene/core,@midscene/shared,@midscene/visualizer,@midscene/web,@midscene/cli,@midscene/android,@midscene/mcp,@midscene/playground --verbose",

packages/visualizer/src/component/history-selector/index.less

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
@import '../common.less';
22

3+
.history-modal-overlay {
4+
position: absolute;
5+
top: 0;
6+
left: 0;
7+
right: 0;
8+
bottom: 0;
9+
background: rgba(0, 0, 0, 0.45);
10+
display: flex;
11+
align-items: flex-end;
12+
justify-content: stretch;
13+
z-index: 1000;
14+
}
15+
316
.history-modal-container {
4-
height: 70vh;
17+
width: 100%;
18+
height: 400px;
19+
background: white;
520
display: flex;
621
flex-direction: column;
722
border-radius: 12px 12px 0 0;
823
overflow: hidden;
24+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
25+
z-index: 1001;
926

1027
/* top title bar */
1128
.history-modal-header {
@@ -120,18 +137,3 @@
120137
}
121138
}
122139

123-
.ant-modal-wrap .ant-modal-content {
124-
animation: slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards !important;
125-
}
126-
127-
@keyframes slideUpFromBottom {
128-
0% {
129-
transform: translateY(100%);
130-
opacity: 0;
131-
}
132-
133-
100% {
134-
transform: translateY(0);
135-
opacity: 1;
136-
}
137-
}
Lines changed: 62 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, Input, Modal, Typography } from 'antd';
1+
import { Button, Input, Typography } from 'antd';
22
import type React from 'react';
33
import { useMemo, useState } from 'react';
44
import CloseOutlined from '../../icons/close.svg';
@@ -84,113 +84,73 @@ export const HistorySelector: React.FC<HistorySelectorProps> = ({
8484
<HistoryOutlined width={24} height={24} />
8585
</div>
8686

87-
<Modal
88-
open={isModalOpen}
89-
onCancel={() => setIsModalOpen(false)}
90-
footer={null}
91-
width="100%"
92-
closable={false}
93-
centered={false}
94-
transitionName=""
95-
maskTransitionName=""
96-
style={{
97-
margin: 0,
98-
padding: 0,
99-
maxWidth: 'none',
100-
top: 'auto',
101-
bottom: 0,
102-
}}
103-
styles={{
104-
wrapper: {
105-
alignItems: 'flex-end',
106-
justifyContent: 'center',
107-
paddingBottom: 0,
108-
display: 'flex',
109-
},
110-
body: {
111-
height: '70vh',
112-
padding: 0,
113-
margin: 0,
114-
},
115-
content: {
116-
height: '70vh',
117-
borderRadius: '12px 12px 0 0',
118-
margin: 0,
119-
padding: 0,
120-
marginBottom: 0,
121-
position: 'fixed',
122-
bottom: 0,
123-
left: 0,
124-
right: 0,
125-
},
126-
}}
127-
maskClosable={true}
128-
destroyOnClose
129-
>
130-
<div className="history-modal-container">
131-
{/* top title bar */}
132-
<div className="history-modal-header">
133-
<Text strong style={{ fontSize: '16px' }}>
134-
History ({history.length})
135-
</Text>
136-
<Button
137-
size="small"
138-
type="text"
139-
icon={<CloseOutlined width={16} height={16} />}
140-
onClick={() => setIsModalOpen(false)}
141-
className="close-button"
142-
/>
143-
</div>
144-
145-
{/* search bar */}
146-
<div className="history-search-section">
147-
<div className="search-input-wrapper">
148-
<Input
149-
placeholder="Search"
150-
value={searchText}
151-
onChange={(e) => setSearchText(e.target.value)}
152-
prefix={<MagnifyingGlass width={18} height={18} />}
153-
className="search-input"
154-
allowClear
155-
/>
87+
{isModalOpen && (
88+
<div className="history-modal-overlay" onClick={() => setIsModalOpen(false)}>
89+
<div className="history-modal-container" onClick={(e) => e.stopPropagation()}>
90+
{/* top title bar */}
91+
<div className="history-modal-header">
92+
<Text strong style={{ fontSize: '16px' }}>
93+
History ({history.length})
94+
</Text>
15695
<Button
157-
type="link"
158-
onClick={handleClearHistory}
159-
className="clear-button"
160-
disabled={history.length === 0}
161-
>
162-
Clear
163-
</Button>
96+
size="small"
97+
type="text"
98+
icon={<CloseOutlined width={16} height={16} />}
99+
onClick={() => setIsModalOpen(false)}
100+
className="close-button"
101+
/>
164102
</div>
165-
</div>
166103

167-
{/* history content */}
168-
<div className="history-content">
169-
{history.length === 0 ? (
170-
/* no history record */
171-
<div className="no-results">
172-
<Text type="secondary">No history record</Text>
104+
{/* search bar */}
105+
<div className="history-search-section">
106+
<div className="search-input-wrapper">
107+
<Input
108+
placeholder="Search"
109+
value={searchText}
110+
onChange={(e) => setSearchText(e.target.value)}
111+
prefix={<MagnifyingGlass width={18} height={18} />}
112+
className="search-input"
113+
allowClear
114+
/>
115+
<Button
116+
type="link"
117+
onClick={handleClearHistory}
118+
className="clear-button"
119+
disabled={history.length === 0}
120+
>
121+
Clear
122+
</Button>
173123
</div>
174-
) : (
175-
<>
176-
{renderHistoryGroup('Last 7 days', groupedHistory.recent7Days)}
177-
{renderHistoryGroup('Last 1 year', groupedHistory.recent1Year)}
178-
{renderHistoryGroup('Earlier', groupedHistory.older)}
179-
180-
{/* no search result */}
181-
{searchText &&
182-
groupedHistory.recent7Days.length === 0 &&
183-
groupedHistory.recent1Year.length === 0 &&
184-
groupedHistory.older.length === 0 && (
185-
<div className="no-results">
186-
<Text type="secondary">No matching history record</Text>
187-
</div>
188-
)}
189-
</>
190-
)}
124+
</div>
125+
126+
{/* history content */}
127+
<div className="history-content">
128+
{history.length === 0 ? (
129+
/* no history record */
130+
<div className="no-results">
131+
<Text type="secondary">No history record</Text>
132+
</div>
133+
) : (
134+
<>
135+
{renderHistoryGroup('Last 7 days', groupedHistory.recent7Days)}
136+
{renderHistoryGroup('Last 1 year', groupedHistory.recent1Year)}
137+
{renderHistoryGroup('Earlier', groupedHistory.older)}
138+
139+
{/* no search result */}
140+
{searchText &&
141+
groupedHistory.recent7Days.length === 0 &&
142+
groupedHistory.recent1Year.length === 0 &&
143+
groupedHistory.older.length === 0 && (
144+
<div className="no-results">
145+
<Text type="secondary">No matching history record</Text>
146+
</div>
147+
)}
148+
</>
149+
)}
150+
</div>
191151
</div>
192152
</div>
193-
</Modal>
153+
)}
194154
</>
195155
);
196156
};

packages/visualizer/src/component/universal-playground/index.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
height: 100vh;
88
width: 100%;
99
background: #fff;
10+
position: relative;
1011

1112
.command-form {
1213
display: flex;

0 commit comments

Comments
 (0)