@electerm/electerm-react 3.1.26 → 3.2.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/client/common/db.js +4 -2
- package/client/components/ai/ai-history.jsx +4 -4
- package/client/components/bookmark-form/common/bookmark-select.jsx +18 -2
- package/client/components/bookmark-form/common/connection-hopping-form.jsx +153 -0
- package/client/components/bookmark-form/common/connection-hopping.jsx +136 -129
- package/client/components/quick-commands/qm.styl +0 -2
- package/client/components/quick-commands/quick-commands-list-form.jsx +1 -1
- package/client/components/setting-panel/hotkey.jsx +9 -1
- package/client/components/setting-panel/list.jsx +0 -1
- package/client/components/setting-panel/list.styl +4 -0
- package/client/components/setting-panel/setting-modal.jsx +53 -47
- package/client/components/shortcuts/shortcut-editor.jsx +4 -2
- package/client/components/sidebar/history.jsx +1 -0
- package/client/components/terminal/attach-addon-custom.js +86 -0
- package/client/components/terminal/cmd-item.jsx +13 -3
- package/client/components/terminal/drop-file-modal.jsx +57 -0
- package/client/components/terminal/terminal-command-dropdown.jsx +91 -13
- package/client/components/terminal/terminal.jsx +103 -5
- package/client/components/terminal/terminal.styl +9 -0
- package/client/components/tree-list/tree-list-item.jsx +0 -1
- package/client/components/vnc/vnc-session.jsx +2 -0
- package/client/components/widgets/widget-control.jsx +3 -0
- package/client/components/widgets/widget-instance.jsx +26 -7
- package/client/css/includes/box.styl +3 -0
- package/client/store/init-state.js +2 -1
- package/client/store/load-data.js +3 -1
- package/client/store/mcp-handler.js +18 -0
- package/client/store/widgets.js +54 -0
- package/package.json +1 -1
package/client/common/db.js
CHANGED
|
@@ -31,7 +31,8 @@ export const dbNames = [
|
|
|
31
31
|
),
|
|
32
32
|
'history',
|
|
33
33
|
'terminalCommandHistory',
|
|
34
|
-
'aiChatHistory'
|
|
34
|
+
'aiChatHistory',
|
|
35
|
+
'autoRunWidgets'
|
|
35
36
|
]
|
|
36
37
|
export const dbNamesForSync = [
|
|
37
38
|
...without(
|
|
@@ -45,7 +46,8 @@ export const dbNamesForWatch = [
|
|
|
45
46
|
...dbNamesForSync,
|
|
46
47
|
'history',
|
|
47
48
|
'terminalCommandHistory',
|
|
48
|
-
'aiChatHistory'
|
|
49
|
+
'aiChatHistory',
|
|
50
|
+
'autoRunWidgets'
|
|
49
51
|
]
|
|
50
52
|
|
|
51
53
|
/**
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
import { useState, useEffect } from 'react'
|
|
5
5
|
import { Space } from 'antd'
|
|
6
6
|
import { HistoryOutlined } from '@ant-design/icons'
|
|
7
|
-
import {
|
|
7
|
+
import { safeGetItemJSON, safeSetItemJSON } from '../../common/safe-local-storage'
|
|
8
8
|
import AiHistoryItem from './ai-history-item'
|
|
9
9
|
|
|
10
10
|
const MAX_HISTORY = 20
|
|
11
11
|
const e = window.translate
|
|
12
12
|
|
|
13
13
|
export function getHistory (storageKey) {
|
|
14
|
-
return
|
|
14
|
+
return safeGetItemJSON(storageKey, [])
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function addHistoryItem (storageKey, itemData, eventName) {
|
|
@@ -37,7 +37,7 @@ export function addHistoryItem (storageKey, itemData, eventName) {
|
|
|
37
37
|
if (history.length > MAX_HISTORY) {
|
|
38
38
|
history = history.slice(0, MAX_HISTORY)
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
safeSetItemJSON(storageKey, history)
|
|
41
41
|
|
|
42
42
|
// Custom event to trigger update
|
|
43
43
|
if (eventName) {
|
|
@@ -72,7 +72,7 @@ export default function AiHistory (props) {
|
|
|
72
72
|
return hStr !== itemStr
|
|
73
73
|
})
|
|
74
74
|
setHistory(newHistory)
|
|
75
|
-
|
|
75
|
+
safeSetItemJSON(storageKey, newHistory)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
if (!history.length) {
|
|
@@ -4,6 +4,16 @@ import { TreeSelect } from 'antd'
|
|
|
4
4
|
|
|
5
5
|
const e = window.translate
|
|
6
6
|
|
|
7
|
+
const hoppingProps = [
|
|
8
|
+
'host',
|
|
9
|
+
'port',
|
|
10
|
+
'username',
|
|
11
|
+
'password',
|
|
12
|
+
'privateKey',
|
|
13
|
+
'passphrase',
|
|
14
|
+
'certificate'
|
|
15
|
+
]
|
|
16
|
+
|
|
7
17
|
function buildTreeData (bookmarkGroups, tree) {
|
|
8
18
|
const cats = bookmarkGroups
|
|
9
19
|
const btree = cats.reduce((p, k) => ({ ...p, [k.id]: k }), {})
|
|
@@ -53,8 +63,14 @@ export default function BookmarkSelect (props) {
|
|
|
53
63
|
function onSelect (id) {
|
|
54
64
|
const item = tree[id]
|
|
55
65
|
if (item) {
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
const selected = hoppingProps.reduce((p, k) => {
|
|
67
|
+
if (item[k] !== undefined) {
|
|
68
|
+
p[k] = item[k]
|
|
69
|
+
}
|
|
70
|
+
return p
|
|
71
|
+
}, {})
|
|
72
|
+
selected.bookmarkId = item.id
|
|
73
|
+
props.onSelect(selected)
|
|
58
74
|
}
|
|
59
75
|
}
|
|
60
76
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Form,
|
|
3
|
+
InputNumber,
|
|
4
|
+
Input,
|
|
5
|
+
Radio,
|
|
6
|
+
Button
|
|
7
|
+
} from 'antd'
|
|
8
|
+
import {
|
|
9
|
+
formItemLayout,
|
|
10
|
+
tailFormItemLayout
|
|
11
|
+
} from '../../../common/form-layout'
|
|
12
|
+
import {
|
|
13
|
+
PlusOutlined,
|
|
14
|
+
SaveOutlined
|
|
15
|
+
} from '@ant-design/icons'
|
|
16
|
+
import RenderAuth from './render-auth-ssh'
|
|
17
|
+
import {
|
|
18
|
+
authTypeMap
|
|
19
|
+
} from '../../../common/constants'
|
|
20
|
+
import { useState } from 'react'
|
|
21
|
+
import BookmarkSelect from './bookmark-select'
|
|
22
|
+
|
|
23
|
+
const FormItem = Form.Item
|
|
24
|
+
const RadioButton = Radio.Button
|
|
25
|
+
const RadioGroup = Radio.Group
|
|
26
|
+
const e = window.translate
|
|
27
|
+
|
|
28
|
+
export default function ConnectionHoppingForm (props) {
|
|
29
|
+
const {
|
|
30
|
+
store,
|
|
31
|
+
formChild,
|
|
32
|
+
initialValues,
|
|
33
|
+
onFinish,
|
|
34
|
+
authTypes: authTypesProp,
|
|
35
|
+
trim,
|
|
36
|
+
isEdit
|
|
37
|
+
} = props
|
|
38
|
+
const [authType, setAuthType] = useState(initialValues.authType || authTypeMap.password)
|
|
39
|
+
|
|
40
|
+
function onChangeAuthType (e) {
|
|
41
|
+
setAuthType(e.target.value)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function onSubmit () {
|
|
45
|
+
formChild.submit()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const authTypes = authTypesProp || Object.keys(authTypeMap).map(k => k)
|
|
49
|
+
|
|
50
|
+
const treeProps = {
|
|
51
|
+
bookmarks: store.bookmarks.filter(d => {
|
|
52
|
+
return d.host && d.port && d.username
|
|
53
|
+
}),
|
|
54
|
+
bookmarkGroups: store.bookmarkGroups,
|
|
55
|
+
onSelect: onFinish
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<Form
|
|
60
|
+
form={formChild}
|
|
61
|
+
onFinish={onFinish}
|
|
62
|
+
initialValues={initialValues}
|
|
63
|
+
component='div'
|
|
64
|
+
>
|
|
65
|
+
<FormItem
|
|
66
|
+
{...formItemLayout}
|
|
67
|
+
label={e('chooseFromBookmarks')}
|
|
68
|
+
className='mg60b'
|
|
69
|
+
style={{ display: isEdit ? 'none' : '' }}
|
|
70
|
+
>
|
|
71
|
+
<BookmarkSelect {...treeProps} />
|
|
72
|
+
</FormItem>
|
|
73
|
+
<FormItem
|
|
74
|
+
{...formItemLayout}
|
|
75
|
+
label={e('host')}
|
|
76
|
+
hasFeedback
|
|
77
|
+
rules={[{
|
|
78
|
+
max: 520, message: '520 chars max'
|
|
79
|
+
}, {
|
|
80
|
+
required: true, message: 'host required'
|
|
81
|
+
}]}
|
|
82
|
+
normalize={trim}
|
|
83
|
+
name='host'
|
|
84
|
+
>
|
|
85
|
+
<Input />
|
|
86
|
+
</FormItem>
|
|
87
|
+
<FormItem
|
|
88
|
+
{...formItemLayout}
|
|
89
|
+
label={e('port')}
|
|
90
|
+
hasFeedback
|
|
91
|
+
name='port'
|
|
92
|
+
rules={[{
|
|
93
|
+
required: true, message: 'port required'
|
|
94
|
+
}]}
|
|
95
|
+
>
|
|
96
|
+
<InputNumber
|
|
97
|
+
placeholder={e('port')}
|
|
98
|
+
min={1}
|
|
99
|
+
max={65535}
|
|
100
|
+
step={1}
|
|
101
|
+
/>
|
|
102
|
+
</FormItem>
|
|
103
|
+
<FormItem
|
|
104
|
+
{...formItemLayout}
|
|
105
|
+
label={e('username')}
|
|
106
|
+
hasFeedback
|
|
107
|
+
name='username'
|
|
108
|
+
rules={[{
|
|
109
|
+
max: 128, message: '128 chars max'
|
|
110
|
+
}]}
|
|
111
|
+
normalize={trim}
|
|
112
|
+
>
|
|
113
|
+
<Input />
|
|
114
|
+
</FormItem>
|
|
115
|
+
<FormItem
|
|
116
|
+
{...tailFormItemLayout}
|
|
117
|
+
className='mg1b'
|
|
118
|
+
name='authType'
|
|
119
|
+
>
|
|
120
|
+
<RadioGroup
|
|
121
|
+
size='small'
|
|
122
|
+
onChange={onChangeAuthType}
|
|
123
|
+
buttonStyle='solid'
|
|
124
|
+
>
|
|
125
|
+
{
|
|
126
|
+
authTypes.map(t => {
|
|
127
|
+
return (
|
|
128
|
+
<RadioButton value={t} key={t}>
|
|
129
|
+
{e(t)}
|
|
130
|
+
</RadioButton>
|
|
131
|
+
)
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
</RadioGroup>
|
|
135
|
+
</FormItem>
|
|
136
|
+
<RenderAuth
|
|
137
|
+
form={formChild}
|
|
138
|
+
store={store}
|
|
139
|
+
authType={authType}
|
|
140
|
+
/>
|
|
141
|
+
<FormItem {...tailFormItemLayout} className='mg60b'>
|
|
142
|
+
<Button
|
|
143
|
+
type='default'
|
|
144
|
+
htmlType='button'
|
|
145
|
+
icon={isEdit ? <SaveOutlined /> : <PlusOutlined />}
|
|
146
|
+
onClick={onSubmit}
|
|
147
|
+
>
|
|
148
|
+
{isEdit ? e('save') : e('connectionHopping')}
|
|
149
|
+
</Button>
|
|
150
|
+
</FormItem>
|
|
151
|
+
</Form>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
@@ -1,33 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Form,
|
|
3
|
-
InputNumber,
|
|
4
3
|
Input,
|
|
5
|
-
Radio,
|
|
6
|
-
Button,
|
|
7
4
|
Table
|
|
8
5
|
} from 'antd'
|
|
9
6
|
import {
|
|
10
|
-
formItemLayout,
|
|
11
7
|
tailFormItemLayout
|
|
12
8
|
} from '../../../common/form-layout'
|
|
13
9
|
import {
|
|
14
10
|
MinusCircleFilled,
|
|
15
|
-
|
|
11
|
+
EditOutlined,
|
|
12
|
+
HolderOutlined
|
|
16
13
|
} from '@ant-design/icons'
|
|
17
|
-
import RenderAuth from './render-auth-ssh'
|
|
18
14
|
import uid from '../../../common/uid'
|
|
19
15
|
import {
|
|
20
16
|
authTypeMap,
|
|
21
17
|
connectionHoppingWarnKey
|
|
22
18
|
} from '../../../common/constants'
|
|
23
|
-
import { useState } from 'react'
|
|
19
|
+
import { useState, useRef, useCallback } from 'react'
|
|
24
20
|
import ConnectionHoppingWarningText from '../../common/connection-hopping-warning-text'
|
|
25
|
-
import BookmarkSelect from './bookmark-select'
|
|
26
21
|
import * as ls from '../../../common/safe-local-storage'
|
|
22
|
+
import Modal from '../../common/modal'
|
|
23
|
+
import ConnectionHoppingForm from './connection-hopping-form'
|
|
27
24
|
|
|
28
25
|
const FormItem = Form.Item
|
|
29
|
-
const RadioButton = Radio.Button
|
|
30
|
-
const RadioGroup = Radio.Group
|
|
31
26
|
const e = window.translate
|
|
32
27
|
|
|
33
28
|
export default function renderConnectionHopping (props) {
|
|
@@ -37,28 +32,54 @@ export default function renderConnectionHopping (props) {
|
|
|
37
32
|
formData
|
|
38
33
|
} = props
|
|
39
34
|
const [formChild] = Form.useForm()
|
|
40
|
-
const [
|
|
35
|
+
const [editFormChild] = Form.useForm()
|
|
36
|
+
const [initialValues] = useState({
|
|
41
37
|
port: 22,
|
|
42
38
|
authType: authTypeMap.password
|
|
43
39
|
})
|
|
44
40
|
const [showWarn, setShowWarn] = useState(
|
|
45
41
|
window.store.hasOldConnectionHoppingBookmark && ls.getItem(connectionHoppingWarnKey) !== 'yes'
|
|
46
42
|
)
|
|
43
|
+
const [editModalVisible, setEditModalVisible] = useState(false)
|
|
44
|
+
const [editingItem, setEditingItem] = useState(null)
|
|
45
|
+
|
|
47
46
|
function closeWarn () {
|
|
48
47
|
setShowWarn(false)
|
|
49
48
|
}
|
|
50
49
|
const [list, setList] = useState(formData.connectionHoppings || [])
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const dragItem = useRef(null)
|
|
51
|
+
const dragOverItem = useRef(null)
|
|
52
|
+
|
|
53
|
+
const handleDragStart = useCallback((index) => {
|
|
54
|
+
dragItem.current = index
|
|
55
|
+
}, [])
|
|
56
|
+
|
|
57
|
+
const handleDragEnter = useCallback((index) => {
|
|
58
|
+
dragOverItem.current = index
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
const handleDragEnd = useCallback(() => {
|
|
62
|
+
if (dragItem.current === null || dragOverItem.current === null) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
if (dragItem.current === dragOverItem.current) {
|
|
66
|
+
dragItem.current = null
|
|
67
|
+
dragOverItem.current = null
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
setList(old => {
|
|
71
|
+
const newList = [...old]
|
|
72
|
+
const [removed] = newList.splice(dragItem.current, 1)
|
|
73
|
+
newList.splice(dragOverItem.current, 0, removed)
|
|
74
|
+
form.setFieldsValue({
|
|
75
|
+
connectionHoppings: newList
|
|
76
|
+
})
|
|
77
|
+
dragItem.current = null
|
|
78
|
+
dragOverItem.current = null
|
|
79
|
+
return newList
|
|
57
80
|
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
formChild.submit()
|
|
61
|
-
}
|
|
81
|
+
}, [form])
|
|
82
|
+
|
|
62
83
|
function handleFinish (data) {
|
|
63
84
|
const nd = {
|
|
64
85
|
...data,
|
|
@@ -74,14 +95,11 @@ export default function renderConnectionHopping (props) {
|
|
|
74
95
|
setList(old => {
|
|
75
96
|
return [
|
|
76
97
|
...old,
|
|
77
|
-
|
|
98
|
+
nd
|
|
78
99
|
]
|
|
79
100
|
})
|
|
80
101
|
formChild.resetFields()
|
|
81
102
|
}
|
|
82
|
-
const authTypes = props.authTypes || Object.keys(authTypeMap).map(k => {
|
|
83
|
-
return k
|
|
84
|
-
})
|
|
85
103
|
|
|
86
104
|
function remove (id) {
|
|
87
105
|
setList(old => {
|
|
@@ -93,7 +111,51 @@ export default function renderConnectionHopping (props) {
|
|
|
93
111
|
})
|
|
94
112
|
formChild.resetFields()
|
|
95
113
|
}
|
|
114
|
+
|
|
115
|
+
function openEdit (record) {
|
|
116
|
+
setEditingItem(record)
|
|
117
|
+
setEditModalVisible(true)
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
editFormChild.setFieldsValue(record)
|
|
120
|
+
}, 100)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function handleEditFinish (data) {
|
|
124
|
+
const updatedItem = {
|
|
125
|
+
...data,
|
|
126
|
+
id: editingItem.id
|
|
127
|
+
}
|
|
128
|
+
setList(old => {
|
|
129
|
+
return old.map(item => item.id === editingItem.id ? updatedItem : item)
|
|
130
|
+
})
|
|
131
|
+
const v = (form.getFieldValue('connectionHoppings') || []).map(
|
|
132
|
+
item => item.id === editingItem.id ? updatedItem : item
|
|
133
|
+
)
|
|
134
|
+
form.setFieldsValue({
|
|
135
|
+
connectionHoppings: v
|
|
136
|
+
})
|
|
137
|
+
setEditModalVisible(false)
|
|
138
|
+
setEditingItem(null)
|
|
139
|
+
editFormChild.resetFields()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function closeEditModal () {
|
|
143
|
+
setEditModalVisible(false)
|
|
144
|
+
setEditingItem(null)
|
|
145
|
+
editFormChild.resetFields()
|
|
146
|
+
}
|
|
147
|
+
|
|
96
148
|
const cols = [
|
|
149
|
+
{
|
|
150
|
+
title: '',
|
|
151
|
+
key: 'drag',
|
|
152
|
+
width: 30,
|
|
153
|
+
render: () => (
|
|
154
|
+
<HolderOutlined
|
|
155
|
+
className='drag'
|
|
156
|
+
/>
|
|
157
|
+
)
|
|
158
|
+
},
|
|
97
159
|
{
|
|
98
160
|
title: 'NO.',
|
|
99
161
|
dataIndex: 'index',
|
|
@@ -110,15 +172,21 @@ export default function renderConnectionHopping (props) {
|
|
|
110
172
|
return <span>{useProfile}{item.username}{pass}@{item.host}:{item.port}{pk}{ph}</span>
|
|
111
173
|
}
|
|
112
174
|
}, {
|
|
113
|
-
title: e('
|
|
175
|
+
title: e('op'),
|
|
114
176
|
key: 'op',
|
|
115
177
|
dataIndex: 'id',
|
|
116
|
-
render: (id) => {
|
|
178
|
+
render: (id, record) => {
|
|
117
179
|
return (
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
180
|
+
<span>
|
|
181
|
+
<EditOutlined
|
|
182
|
+
className='pointer mg1r'
|
|
183
|
+
onClick={() => openEdit(record)}
|
|
184
|
+
/>
|
|
185
|
+
<MinusCircleFilled
|
|
186
|
+
className='pointer'
|
|
187
|
+
onClick={() => remove(id)}
|
|
188
|
+
/>
|
|
189
|
+
</span>
|
|
122
190
|
)
|
|
123
191
|
}
|
|
124
192
|
}
|
|
@@ -140,6 +208,13 @@ export default function renderConnectionHopping (props) {
|
|
|
140
208
|
className='mg3b'
|
|
141
209
|
pagination={false}
|
|
142
210
|
size='small'
|
|
211
|
+
onRow={(record, index) => ({
|
|
212
|
+
draggable: true,
|
|
213
|
+
onDragStart: () => handleDragStart(index),
|
|
214
|
+
onDragEnter: () => handleDragEnter(index),
|
|
215
|
+
onDragEnd: handleDragEnd,
|
|
216
|
+
onDragOver: (e) => e.preventDefault()
|
|
217
|
+
})}
|
|
143
218
|
dataSource={list.map((d, i) => {
|
|
144
219
|
return {
|
|
145
220
|
...d,
|
|
@@ -161,13 +236,15 @@ export default function renderConnectionHopping (props) {
|
|
|
161
236
|
</FormItem>
|
|
162
237
|
)
|
|
163
238
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
239
|
+
|
|
240
|
+
const editModalProps = {
|
|
241
|
+
open: editModalVisible,
|
|
242
|
+
onCancel: closeEditModal,
|
|
243
|
+
footer: null,
|
|
244
|
+
title: e('edit') + ' ' + e('connectionHopping'),
|
|
245
|
+
width: 600
|
|
170
246
|
}
|
|
247
|
+
|
|
171
248
|
return (
|
|
172
249
|
<>
|
|
173
250
|
<FormItem
|
|
@@ -176,100 +253,30 @@ export default function renderConnectionHopping (props) {
|
|
|
176
253
|
>
|
|
177
254
|
<Input />
|
|
178
255
|
</FormItem>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
256
|
+
{renderList()}
|
|
257
|
+
{renderWarn()}
|
|
258
|
+
<ConnectionHoppingForm
|
|
259
|
+
store={store}
|
|
260
|
+
formChild={formChild}
|
|
182
261
|
initialValues={initialValues}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
rules={[{
|
|
199
|
-
max: 520, message: '520 chars max'
|
|
200
|
-
}, {
|
|
201
|
-
required: true, message: 'host required'
|
|
202
|
-
}]}
|
|
203
|
-
normalize={props.trim}
|
|
204
|
-
name='host'
|
|
205
|
-
>
|
|
206
|
-
<Input />
|
|
207
|
-
</FormItem>
|
|
208
|
-
<FormItem
|
|
209
|
-
{...formItemLayout}
|
|
210
|
-
label={e('port')}
|
|
211
|
-
hasFeedback
|
|
212
|
-
name='port'
|
|
213
|
-
rules={[{
|
|
214
|
-
required: true, message: 'port required'
|
|
215
|
-
}]}
|
|
216
|
-
>
|
|
217
|
-
<InputNumber
|
|
218
|
-
placeholder={e('port')}
|
|
219
|
-
min={1}
|
|
220
|
-
max={65535}
|
|
221
|
-
step={1}
|
|
262
|
+
onFinish={handleFinish}
|
|
263
|
+
authTypes={props.authTypes}
|
|
264
|
+
trim={props.trim}
|
|
265
|
+
/>
|
|
266
|
+
{editModalVisible && (
|
|
267
|
+
<Modal {...editModalProps}>
|
|
268
|
+
<ConnectionHoppingForm
|
|
269
|
+
key={editingItem?.id}
|
|
270
|
+
store={store}
|
|
271
|
+
formChild={editFormChild}
|
|
272
|
+
initialValues={editingItem}
|
|
273
|
+
onFinish={handleEditFinish}
|
|
274
|
+
authTypes={props.authTypes}
|
|
275
|
+
trim={props.trim}
|
|
276
|
+
isEdit
|
|
222
277
|
/>
|
|
223
|
-
</
|
|
224
|
-
|
|
225
|
-
{...formItemLayout}
|
|
226
|
-
label={e('username')}
|
|
227
|
-
hasFeedback
|
|
228
|
-
name='username'
|
|
229
|
-
rules={[{
|
|
230
|
-
max: 128, message: '128 chars max'
|
|
231
|
-
}]}
|
|
232
|
-
normalize={props.trim}
|
|
233
|
-
>
|
|
234
|
-
<Input />
|
|
235
|
-
</FormItem>
|
|
236
|
-
<FormItem
|
|
237
|
-
{...tailFormItemLayout}
|
|
238
|
-
className='mg1b'
|
|
239
|
-
name='authType'
|
|
240
|
-
>
|
|
241
|
-
<RadioGroup
|
|
242
|
-
size='small'
|
|
243
|
-
onChange={onChangeAuthType}
|
|
244
|
-
buttonStyle='solid'
|
|
245
|
-
>
|
|
246
|
-
{
|
|
247
|
-
authTypes.map(t => {
|
|
248
|
-
return (
|
|
249
|
-
<RadioButton value={t} key={t}>
|
|
250
|
-
{e(t)}
|
|
251
|
-
</RadioButton>
|
|
252
|
-
)
|
|
253
|
-
})
|
|
254
|
-
}
|
|
255
|
-
</RadioGroup>
|
|
256
|
-
</FormItem>
|
|
257
|
-
<RenderAuth
|
|
258
|
-
form={formChild}
|
|
259
|
-
store={store}
|
|
260
|
-
authType={initialValues.authType}
|
|
261
|
-
/>
|
|
262
|
-
<FormItem {...tailFormItemLayout} className='mg60b'>
|
|
263
|
-
<Button
|
|
264
|
-
type='default'
|
|
265
|
-
htmlType='button'
|
|
266
|
-
icon={<PlusOutlined />}
|
|
267
|
-
onClick={onSubmit}
|
|
268
|
-
>
|
|
269
|
-
{e('connectionHopping')}
|
|
270
|
-
</Button>
|
|
271
|
-
</FormItem>
|
|
272
|
-
</Form>
|
|
278
|
+
</Modal>
|
|
279
|
+
)}
|
|
273
280
|
</>
|
|
274
281
|
)
|
|
275
282
|
}
|
|
@@ -76,7 +76,7 @@ export default function renderQm (form) {
|
|
|
76
76
|
onDrop={(e) => handleDrop(e, i, form)}
|
|
77
77
|
onDragEnd={handleDragEnd}
|
|
78
78
|
>
|
|
79
|
-
<HolderOutlined className='mg1r
|
|
79
|
+
<HolderOutlined className='mg1r drag' />
|
|
80
80
|
|
|
81
81
|
<Space.Addon>{e('delay')}</Space.Addon>
|
|
82
82
|
<FormItem
|
|
@@ -51,6 +51,12 @@ export default class HotkeySetting extends Component {
|
|
|
51
51
|
})
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
handleClear = () => {
|
|
55
|
+
return this.props.onSaveConfig({
|
|
56
|
+
hotkey: ''
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
convertToElectronAccelerator = (shortcut) => {
|
|
55
61
|
if (!shortcut) return shortcut
|
|
56
62
|
|
|
@@ -117,7 +123,9 @@ export default class HotkeySetting extends Component {
|
|
|
117
123
|
index: 0
|
|
118
124
|
},
|
|
119
125
|
updateConfig: this.onChangeHotkey,
|
|
120
|
-
keysTaken: this.getKeysTaken(hotkey)
|
|
126
|
+
keysTaken: this.getKeysTaken(hotkey),
|
|
127
|
+
handleClear: this.handleClear,
|
|
128
|
+
renderClear: true
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
return (
|
|
@@ -11,7 +11,6 @@ import { noop } from 'lodash-es'
|
|
|
11
11
|
import highlight from '../common/highlight'
|
|
12
12
|
import { settingSyncId, settingCommonId, staticNewItemTabs } from '../../common/constants'
|
|
13
13
|
import getInitItem from '../../common/init-setting-item'
|
|
14
|
-
import './list.styl'
|
|
15
14
|
|
|
16
15
|
const e = window.translate
|
|
17
16
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
.list-item-remove
|
|
9
9
|
.list-item-bookmark
|
|
10
10
|
.list-item-duplicate
|
|
11
|
+
.list-item-autorun
|
|
11
12
|
display none
|
|
12
13
|
width 24px
|
|
13
14
|
line-height 35px
|
|
@@ -15,6 +16,8 @@
|
|
|
15
16
|
position absolute
|
|
16
17
|
right 0
|
|
17
18
|
top 0
|
|
19
|
+
.list-item-autorun
|
|
20
|
+
right 24px
|
|
18
21
|
|
|
19
22
|
.list-item-title
|
|
20
23
|
flex-grow: 1
|
|
@@ -37,6 +40,7 @@
|
|
|
37
40
|
.list-item-remove
|
|
38
41
|
.list-item-bookmark
|
|
39
42
|
.list-item-duplicate
|
|
43
|
+
.list-item-autorun
|
|
40
44
|
display block
|
|
41
45
|
.theme-item:hover
|
|
42
46
|
.list-item-remove
|