whistle.mock-plugins 1.2.2-beta.13 → 1.2.2-beta.18
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/COLUMN_RESIZE_IMPLEMENTATION.md +162 -0
- package/TEST_GUIDE.md +156 -0
- package/VERSION.md +34 -0
- package/app/public/js/index.js +1 -1
- package/app/public/js/index.js.LICENSE.txt +0 -2
- package/lib/models.js +9 -0
- package/lib/routes/interfaces.js +4 -2
- package/lib/ruleManager.js +30 -47
- package/package.json +2 -1
- package/ui/src/components/interface-management/DataManagementDrawer.js +115 -0
- package/ui/src/components/interface-management/ResponseContentEditor.js +118 -132
- package/ui/src/components/interface-management/index.js +1 -0
- package/ui/src/pages/InterfaceManagementV2.js +500 -142
- package/ui/src/pages/Settings.js +75 -6
- package/ui/src/styles/interface-management.css +37 -1
- package/ui/src/styles/settings.css +29 -0
package/ui/src/pages/Settings.js
CHANGED
|
@@ -1,11 +1,45 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import AppLayout from '../components/AppLayout';
|
|
3
|
-
import { Card, Typography,
|
|
3
|
+
import { Card, Typography, Switch, Space, Divider } from 'antd';
|
|
4
4
|
import '../styles/settings.css';
|
|
5
5
|
|
|
6
6
|
const { Title, Text, Paragraph } = Typography;
|
|
7
7
|
|
|
8
8
|
const Settings = () => {
|
|
9
|
+
const [displayMode, setDisplayMode] = useState('modal');
|
|
10
|
+
const [interfaceFormDisplayMode, setInterfaceFormDisplayMode] = useState('modal');
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
// 从 localStorage 读取配置
|
|
14
|
+
const savedMode = localStorage.getItem('dataManagementDisplayMode');
|
|
15
|
+
if (savedMode) {
|
|
16
|
+
setDisplayMode(savedMode);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const savedInterfaceFormMode = localStorage.getItem('interfaceFormDisplayMode');
|
|
20
|
+
if (savedInterfaceFormMode) {
|
|
21
|
+
setInterfaceFormDisplayMode(savedInterfaceFormMode);
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
const handleDisplayModeChange = (checked) => {
|
|
26
|
+
const newMode = checked ? 'drawer' : 'modal';
|
|
27
|
+
setDisplayMode(newMode);
|
|
28
|
+
localStorage.setItem('dataManagementDisplayMode', newMode);
|
|
29
|
+
|
|
30
|
+
// 触发 storage 事件,通知其他页面
|
|
31
|
+
window.dispatchEvent(new Event('storage'));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleInterfaceFormDisplayModeChange = (checked) => {
|
|
35
|
+
const newMode = checked ? 'drawer' : 'modal';
|
|
36
|
+
setInterfaceFormDisplayMode(newMode);
|
|
37
|
+
localStorage.setItem('interfaceFormDisplayMode', newMode);
|
|
38
|
+
|
|
39
|
+
// 触发 storage 事件,通知其他页面
|
|
40
|
+
window.dispatchEvent(new Event('storage'));
|
|
41
|
+
};
|
|
42
|
+
|
|
9
43
|
return (
|
|
10
44
|
<AppLayout>
|
|
11
45
|
<div className="page-container">
|
|
@@ -19,10 +53,45 @@ const Settings = () => {
|
|
|
19
53
|
</div>
|
|
20
54
|
|
|
21
55
|
<Card title="界面设置" className="settings-card">
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
56
|
+
<div className="settings-item">
|
|
57
|
+
<div className="settings-item-header">
|
|
58
|
+
<div>
|
|
59
|
+
<div className="settings-item-title">数据管理交互</div>
|
|
60
|
+
<div className="settings-item-description">
|
|
61
|
+
选择数据管理的显示方式
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<Space>
|
|
65
|
+
<Text type="secondary">
|
|
66
|
+
{displayMode === 'drawer' ? '抽屉模式' : '弹窗模式'}
|
|
67
|
+
</Text>
|
|
68
|
+
<Switch
|
|
69
|
+
checked={displayMode === 'drawer'}
|
|
70
|
+
onChange={handleDisplayModeChange}
|
|
71
|
+
/>
|
|
72
|
+
</Space>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div className="settings-item">
|
|
77
|
+
<div className="settings-item-header">
|
|
78
|
+
<div>
|
|
79
|
+
<div className="settings-item-title">接口表单交互</div>
|
|
80
|
+
<div className="settings-item-description">
|
|
81
|
+
选择添加/编辑接口的显示方式
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
<Space>
|
|
85
|
+
<Text type="secondary">
|
|
86
|
+
{interfaceFormDisplayMode === 'drawer' ? '抽屉模式' : '弹窗模式'}
|
|
87
|
+
</Text>
|
|
88
|
+
<Switch
|
|
89
|
+
checked={interfaceFormDisplayMode === 'drawer'}
|
|
90
|
+
onChange={handleInterfaceFormDisplayModeChange}
|
|
91
|
+
/>
|
|
92
|
+
</Space>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
26
95
|
</Card>
|
|
27
96
|
</div>
|
|
28
97
|
</AppLayout>
|
|
@@ -295,7 +295,11 @@
|
|
|
295
295
|
padding: 12px 16px !important;
|
|
296
296
|
white-space: nowrap;
|
|
297
297
|
overflow: hidden;
|
|
298
|
-
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* 当前响应列需要 overflow: visible 以显示完整的下拉菜单 */
|
|
301
|
+
.interface-table td.current-response-cell {
|
|
302
|
+
overflow: visible !important;
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
/* 卡片视图样式 */
|
|
@@ -1283,3 +1287,35 @@
|
|
|
1283
1287
|
.interface-table .ant-pagination-options {
|
|
1284
1288
|
margin-right: 16px;
|
|
1285
1289
|
}
|
|
1290
|
+
|
|
1291
|
+
/* 可调整列宽样式 */
|
|
1292
|
+
.column-resize-handle {
|
|
1293
|
+
position: absolute;
|
|
1294
|
+
right: -5px;
|
|
1295
|
+
top: 0;
|
|
1296
|
+
bottom: 0;
|
|
1297
|
+
width: 10px;
|
|
1298
|
+
cursor: col-resize;
|
|
1299
|
+
z-index: 1;
|
|
1300
|
+
user-select: none;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
.column-resize-handle:hover {
|
|
1304
|
+
background-color: rgba(24, 144, 255, 0.2);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.column-resize-handle::after {
|
|
1308
|
+
content: '';
|
|
1309
|
+
position: absolute;
|
|
1310
|
+
right: 4px;
|
|
1311
|
+
top: 50%;
|
|
1312
|
+
transform: translateY(-50%);
|
|
1313
|
+
width: 2px;
|
|
1314
|
+
height: 20px;
|
|
1315
|
+
background-color: #d9d9d9;
|
|
1316
|
+
transition: background-color 0.3s;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
.column-resize-handle:hover::after {
|
|
1320
|
+
background-color: #1890ff;
|
|
1321
|
+
}
|
|
@@ -33,6 +33,35 @@
|
|
|
33
33
|
font-weight: 500;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/* 设置项样式 */
|
|
37
|
+
.settings-item {
|
|
38
|
+
padding: 16px 0;
|
|
39
|
+
border-bottom: 1px solid #f0f0f0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.settings-item:last-child {
|
|
43
|
+
border-bottom: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.settings-item-header {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.settings-item-title {
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
font-weight: 500;
|
|
55
|
+
color: #262626;
|
|
56
|
+
margin-bottom: 4px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.settings-item-description {
|
|
60
|
+
font-size: 12px;
|
|
61
|
+
color: #8c8c8c;
|
|
62
|
+
line-height: 1.5;
|
|
63
|
+
}
|
|
64
|
+
|
|
36
65
|
.settings-section {
|
|
37
66
|
margin-bottom: 32px;
|
|
38
67
|
}
|