@electerm/electerm-react 2.5.9 → 2.5.16
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/constants.js +1 -1
- package/client/components/bookmark-form/bookmark-form.styl +2 -0
- package/client/components/bookmark-form/common/run-scripts.jsx +29 -27
- package/client/components/bookmark-form/{tree-delete.jsx → tree-select.jsx} +27 -13
- package/client/components/common/input-confirm-common.jsx +13 -8
- package/client/components/common/modal.styl +1 -0
- package/client/components/common/multi-select-modal.jsx +35 -0
- package/client/components/common/notification.styl +1 -1
- package/client/components/quick-commands/quick-commands-box.jsx +9 -9
- package/client/components/quick-commands/quick-commands-list-form.jsx +34 -35
- package/client/components/setting-panel/bookmark-tree-list.jsx +2 -2
- package/client/components/setting-panel/keywords-form.jsx +14 -20
- package/client/components/setting-panel/setting-common.jsx +18 -39
- package/client/components/setting-panel/setting-terminal.jsx +1 -1
- package/client/components/setting-panel/setting-wrap.styl +8 -2
- package/client/components/sidebar/sidebar-panel.jsx +15 -2
- package/client/components/sidebar/sidebar.styl +9 -3
- package/client/components/tabs/add-btn-menu.jsx +13 -9
- package/client/components/tabs/add-btn.styl +11 -1
- package/client/components/tabs/tab.jsx +7 -1
- package/client/components/tabs/tabs.styl +4 -1
- package/client/components/tree-list/tree-list.jsx +10 -8
- package/client/components/tree-list/tree-list.styl +14 -0
- package/client/store/bookmark.js +7 -0
- package/package.json +1 -1
|
@@ -233,7 +233,7 @@ export const downloadUpgradeTimeout = 20000
|
|
|
233
233
|
export const expandedKeysLsKey = 'expanded-keys'
|
|
234
234
|
export const resolutionsLsKey = 'custom-resolution-key'
|
|
235
235
|
export const checkedKeysLsKey = 'checked-keys'
|
|
236
|
-
export const quickCommandLabelsLsKey = 'quick-command-
|
|
236
|
+
export const quickCommandLabelsLsKey = 'quick-command-label'
|
|
237
237
|
export const localAddrBookmarkLsKey = 'local-addr-bookmark-keys'
|
|
238
238
|
export const dismissDelKeyTipLsKey = 'dismiss-del-key-tip'
|
|
239
239
|
export const sshTunnelHelpLink = 'https://github.com/electerm/electerm/wiki/How-to-use-ssh-tunnel'
|
|
@@ -17,42 +17,44 @@ export default function renderRunScripts () {
|
|
|
17
17
|
return (
|
|
18
18
|
<>
|
|
19
19
|
<Space
|
|
20
|
-
align='
|
|
20
|
+
align='baseline'
|
|
21
|
+
block
|
|
21
22
|
key={field.key}
|
|
22
23
|
>
|
|
23
24
|
<FormItem
|
|
24
25
|
label=''
|
|
25
26
|
name={[field.name, 'delay']}
|
|
26
27
|
required
|
|
28
|
+
noStyle
|
|
27
29
|
>
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/>
|
|
37
|
-
</Space.Compact>
|
|
38
|
-
</FormItem>
|
|
39
|
-
<FormItem
|
|
40
|
-
label=''
|
|
41
|
-
name={[field.name, 'script']}
|
|
42
|
-
required
|
|
43
|
-
className='mg2x'
|
|
44
|
-
>
|
|
45
|
-
<Input.TextArea
|
|
46
|
-
autoSize={{ minRows: 1 }}
|
|
47
|
-
placeholder={e('loginScript')}
|
|
48
|
-
className='compact-input'
|
|
30
|
+
<InputNumber
|
|
31
|
+
min={1}
|
|
32
|
+
step={1}
|
|
33
|
+
prefix={e('loginScriptDelay')}
|
|
34
|
+
suffix='ms'
|
|
35
|
+
max={65535}
|
|
36
|
+
className='number-input'
|
|
37
|
+
rules={[{ required: true, message: e('loginScriptDelay') + ' required' }]}
|
|
49
38
|
/>
|
|
50
39
|
</FormItem>
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
40
|
+
<Space.Compact>
|
|
41
|
+
<FormItem
|
|
42
|
+
label=''
|
|
43
|
+
name={[field.name, 'script']}
|
|
44
|
+
required
|
|
45
|
+
noStyle
|
|
46
|
+
>
|
|
47
|
+
<Input.TextArea
|
|
48
|
+
autoSize={{ minRows: 1 }}
|
|
49
|
+
placeholder={e('loginScript')}
|
|
50
|
+
/>
|
|
51
|
+
</FormItem>
|
|
52
|
+
<Button
|
|
53
|
+
icon={<MinusCircleOutlined />}
|
|
54
|
+
onClick={() => remove(field.name)}
|
|
55
|
+
className='mg24b'
|
|
56
|
+
/>
|
|
57
|
+
</Space.Compact>
|
|
56
58
|
</Space>
|
|
57
59
|
</>
|
|
58
60
|
)
|
|
@@ -71,28 +71,42 @@ function buildData (bookmarks, bookmarkGroups) {
|
|
|
71
71
|
return level1
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export default function
|
|
75
|
-
const { expandedKeys, checkedKeys, bookmarks, bookmarkGroups } = props
|
|
74
|
+
export default function BookmarkTreeSelect (props) {
|
|
75
|
+
const { expandedKeys: propExpandedKeys, checkedKeys: propCheckedKeys, bookmarks, bookmarkGroups, type = 'delete', onCheck: propOnCheck, onExpand: propOnExpand } = props
|
|
76
76
|
|
|
77
|
-
const
|
|
77
|
+
const expandedKeys = propExpandedKeys !== undefined ? propExpandedKeys : window.store.expandedKeys
|
|
78
|
+
const checkedKeys = propCheckedKeys !== undefined ? propCheckedKeys : window.store.checkedKeys
|
|
79
|
+
|
|
80
|
+
const onExpand = propOnExpand || ((expandedKeys) => {
|
|
78
81
|
window.store.expandedKeys = deepCopy(expandedKeys)
|
|
79
|
-
}
|
|
82
|
+
})
|
|
80
83
|
|
|
81
|
-
const onCheck = (checkedKeys) => {
|
|
84
|
+
const onCheck = propOnCheck || ((checkedKeys) => {
|
|
82
85
|
window.store.checkedKeys = deepCopy(checkedKeys)
|
|
83
|
-
}
|
|
86
|
+
})
|
|
84
87
|
|
|
85
|
-
const
|
|
88
|
+
const handleOperation = () => {
|
|
86
89
|
const { store } = window
|
|
87
90
|
const arr = checkedKeys.filter(d => d !== defaultBookmarkGroupId)
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
if (type === 'delete') {
|
|
92
|
+
store.delItems(arr, settingMap.bookmarks)
|
|
93
|
+
store.delItems(arr, settingMap.bookmarkGroups)
|
|
94
|
+
} else {
|
|
95
|
+
store.openBookmarks(arr)
|
|
96
|
+
if (props.onClose) {
|
|
97
|
+
props.onClose()
|
|
98
|
+
}
|
|
99
|
+
}
|
|
90
100
|
store.checkedKeys = []
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
const handleCancel = () => {
|
|
94
104
|
const { store } = window
|
|
95
|
-
|
|
105
|
+
if (props.onClose) {
|
|
106
|
+
props.onClose()
|
|
107
|
+
} else {
|
|
108
|
+
store.bookmarkSelectMode = false
|
|
109
|
+
}
|
|
96
110
|
store.checkedKeys = []
|
|
97
111
|
}
|
|
98
112
|
|
|
@@ -109,13 +123,13 @@ export default function BookmarkTreeDelete (props) {
|
|
|
109
123
|
return (
|
|
110
124
|
<div>
|
|
111
125
|
<div className='pd2'>
|
|
112
|
-
<Space.Compact>
|
|
126
|
+
<Space.Compact className='mg2b'>
|
|
113
127
|
<Button
|
|
114
128
|
type='primary'
|
|
115
129
|
disabled={!len}
|
|
116
|
-
onClick={
|
|
130
|
+
onClick={handleOperation}
|
|
117
131
|
>
|
|
118
|
-
{e('delSelected')} ({len})
|
|
132
|
+
{type === 'delete' ? e('delSelected') : e('open')} ({len})
|
|
119
133
|
</Button>
|
|
120
134
|
<Button
|
|
121
135
|
onClick={handleCancel}
|
|
@@ -34,6 +34,12 @@ export default function InputConfirmCommon ({
|
|
|
34
34
|
setIsEditing(false)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function handleBlur () {
|
|
38
|
+
if (isEditing) {
|
|
39
|
+
handleConfirm()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
37
43
|
const icons = isEditing
|
|
38
44
|
? (
|
|
39
45
|
<>
|
|
@@ -63,18 +69,17 @@ export default function InputConfirmCommon ({
|
|
|
63
69
|
const childProps = {
|
|
64
70
|
...restProps,
|
|
65
71
|
value: localValue,
|
|
66
|
-
onChange: handleChange
|
|
72
|
+
onChange: handleChange,
|
|
73
|
+
onBlur: handleBlur
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
const inputElement = <InputComponent {...childProps} />
|
|
70
77
|
|
|
71
78
|
return (
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
</Space.Compact>
|
|
78
|
-
</div>
|
|
79
|
+
<Space.Compact className={cls}>
|
|
80
|
+
{beforeAddon}
|
|
81
|
+
{inputElement}
|
|
82
|
+
{afterAddon}
|
|
83
|
+
</Space.Compact>
|
|
79
84
|
)
|
|
80
85
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import Modal from './modal'
|
|
3
|
+
import BookmarkTreeSelect from '../bookmark-form/tree-select'
|
|
4
|
+
|
|
5
|
+
const e = window.translate
|
|
6
|
+
|
|
7
|
+
const MultiSelectModal = ({ onClose, open }) => {
|
|
8
|
+
const [checkedKeys, setCheckedKeys] = useState([])
|
|
9
|
+
const [expandedKeys, setExpandedKeys] = useState([])
|
|
10
|
+
if (!open) {
|
|
11
|
+
return null
|
|
12
|
+
}
|
|
13
|
+
const { store } = window
|
|
14
|
+
return (
|
|
15
|
+
<Modal
|
|
16
|
+
title={e('open') + ' ' + e('bookmarks')}
|
|
17
|
+
open={open}
|
|
18
|
+
onCancel={onClose}
|
|
19
|
+
footer={null}
|
|
20
|
+
>
|
|
21
|
+
<BookmarkTreeSelect
|
|
22
|
+
type='open'
|
|
23
|
+
onClose={onClose}
|
|
24
|
+
bookmarks={store.bookmarks}
|
|
25
|
+
bookmarkGroups={store.bookmarkGroups}
|
|
26
|
+
expandedKeys={expandedKeys}
|
|
27
|
+
checkedKeys={checkedKeys}
|
|
28
|
+
onExpand={setExpandedKeys}
|
|
29
|
+
onCheck={setCheckedKeys}
|
|
30
|
+
/>
|
|
31
|
+
</Modal>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default MultiSelectModal
|
|
@@ -23,7 +23,7 @@ const { Option } = Select
|
|
|
23
23
|
|
|
24
24
|
export default function QuickCommandsFooterBox (props) {
|
|
25
25
|
const [keyword, setKeyword] = useState('')
|
|
26
|
-
const [
|
|
26
|
+
const [label, setLabel] = useState(ls.getItem(quickCommandLabelsLsKey, ''))
|
|
27
27
|
const timer = useRef(null)
|
|
28
28
|
|
|
29
29
|
function handleMouseLeave () {
|
|
@@ -68,8 +68,8 @@ export default function QuickCommandsFooterBox (props) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function handleChangeLabels (v) {
|
|
71
|
-
ls.
|
|
72
|
-
|
|
71
|
+
ls.setItem(quickCommandLabelsLsKey, v || '')
|
|
72
|
+
setLabel(v)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// function filterFunc (v, opt) {
|
|
@@ -132,10 +132,10 @@ export default function QuickCommandsFooterBox (props) {
|
|
|
132
132
|
)
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function filterArray (array, keyword,
|
|
135
|
+
function filterArray (array, keyword, label) {
|
|
136
136
|
return array.filter(obj => {
|
|
137
137
|
const nameMatches = !keyword || obj.name.toLowerCase().includes(keyword)
|
|
138
|
-
const labelMatches = !
|
|
138
|
+
const labelMatches = !label || (obj.labels || []).includes(label)
|
|
139
139
|
return nameMatches && labelMatches
|
|
140
140
|
})
|
|
141
141
|
}
|
|
@@ -156,16 +156,16 @@ export default function QuickCommandsFooterBox (props) {
|
|
|
156
156
|
return renderNoCmd()
|
|
157
157
|
}
|
|
158
158
|
const keyword0 = keyword.toLowerCase()
|
|
159
|
-
const filtered = filterArray(all, keyword0,
|
|
159
|
+
const filtered = filterArray(all, keyword0, label)
|
|
160
160
|
const sorted = qmSortByFrequency
|
|
161
161
|
? sortBy(filtered, (obj) => -(obj.clickCount || 0))
|
|
162
162
|
: filtered
|
|
163
163
|
const sprops = {
|
|
164
|
-
value:
|
|
165
|
-
mode: 'multiple',
|
|
164
|
+
value: label,
|
|
166
165
|
onChange: handleChangeLabels,
|
|
167
166
|
placeholder: e('labels'),
|
|
168
|
-
className: 'qm-label-select'
|
|
167
|
+
className: 'qm-label-select',
|
|
168
|
+
allowClear: true
|
|
169
169
|
}
|
|
170
170
|
const tp = pinnedQuickCommandBar
|
|
171
171
|
? 'primary'
|
|
@@ -3,11 +3,9 @@ import {
|
|
|
3
3
|
InputNumber,
|
|
4
4
|
Space,
|
|
5
5
|
Button,
|
|
6
|
-
Input
|
|
7
|
-
Tag
|
|
6
|
+
Input
|
|
8
7
|
} from 'antd'
|
|
9
8
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
|
|
10
|
-
import { formItemLayout } from '../../common/form-layout'
|
|
11
9
|
import HelpIcon from '../common/help-icon'
|
|
12
10
|
import { copy } from '../../common/clipboard'
|
|
13
11
|
import { useRef } from 'react'
|
|
@@ -20,48 +18,49 @@ export default function renderQm () {
|
|
|
20
18
|
const focused = useRef(0)
|
|
21
19
|
function renderItem (field, i, add, remove) {
|
|
22
20
|
return (
|
|
23
|
-
<Space
|
|
21
|
+
<Space.Compact
|
|
24
22
|
align='center'
|
|
23
|
+
block
|
|
25
24
|
key={field.key}
|
|
25
|
+
className='mg2b'
|
|
26
26
|
>
|
|
27
|
+
<Space.Addon>{e('delay')}</Space.Addon>
|
|
27
28
|
<FormItem
|
|
28
29
|
label=''
|
|
29
30
|
name={[field.name, 'delay']}
|
|
30
31
|
required
|
|
32
|
+
noStyle
|
|
31
33
|
>
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/>
|
|
41
|
-
</Space.Compact>
|
|
34
|
+
<InputNumber
|
|
35
|
+
min={1}
|
|
36
|
+
step={1}
|
|
37
|
+
max={65535}
|
|
38
|
+
placeholder={100}
|
|
39
|
+
className='compact-input'
|
|
40
|
+
suffix='ms'
|
|
41
|
+
/>
|
|
42
42
|
</FormItem>
|
|
43
43
|
<FormItem
|
|
44
44
|
label=''
|
|
45
45
|
name={[field.name, 'command']}
|
|
46
46
|
required
|
|
47
47
|
className='mg2x'
|
|
48
|
+
noStyle
|
|
48
49
|
>
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/>
|
|
58
|
-
<Button
|
|
59
|
-
icon={<MinusCircleOutlined />}
|
|
60
|
-
onClick={() => remove(field.name)}
|
|
61
|
-
/>
|
|
62
|
-
</Space.Compact>
|
|
50
|
+
<Input.TextArea
|
|
51
|
+
autoSize={{ minRows: 1 }}
|
|
52
|
+
placeholder={e('quickCommand')}
|
|
53
|
+
className='compact-input qm-input'
|
|
54
|
+
onFocus={() => {
|
|
55
|
+
focused.current = i
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
63
58
|
</FormItem>
|
|
64
|
-
|
|
59
|
+
<Button
|
|
60
|
+
icon={<MinusCircleOutlined />}
|
|
61
|
+
onClick={() => remove(field.name)}
|
|
62
|
+
/>
|
|
63
|
+
</Space.Compact>
|
|
65
64
|
)
|
|
66
65
|
}
|
|
67
66
|
const commonCmds = [
|
|
@@ -89,28 +88,29 @@ export default function renderQm () {
|
|
|
89
88
|
|
|
90
89
|
const cmds = commonCmds.map(c => {
|
|
91
90
|
return (
|
|
92
|
-
<
|
|
91
|
+
<Button
|
|
93
92
|
title={c.desc}
|
|
94
|
-
|
|
93
|
+
type='text'
|
|
95
94
|
key={c.cmd}
|
|
95
|
+
size='small'
|
|
96
96
|
onClick={() => {
|
|
97
97
|
copy(c.cmd)
|
|
98
98
|
}}
|
|
99
99
|
>
|
|
100
100
|
<b className='pointer'>{c.cmd}</b>
|
|
101
|
-
</
|
|
101
|
+
</Button>
|
|
102
102
|
)
|
|
103
103
|
})
|
|
104
104
|
const label = (
|
|
105
105
|
<div>
|
|
106
|
-
{e('
|
|
106
|
+
{e('quickCommands')}
|
|
107
107
|
<HelpIcon
|
|
108
108
|
title={cmds}
|
|
109
109
|
/>
|
|
110
110
|
</div>
|
|
111
111
|
)
|
|
112
112
|
return (
|
|
113
|
-
<FormItem
|
|
113
|
+
<FormItem label={label}>
|
|
114
114
|
<FormList
|
|
115
115
|
name='commands'
|
|
116
116
|
>
|
|
@@ -127,7 +127,6 @@ export default function renderQm () {
|
|
|
127
127
|
<Button
|
|
128
128
|
type='dashed'
|
|
129
129
|
onClick={() => add()}
|
|
130
|
-
block
|
|
131
130
|
icon={<PlusOutlined />}
|
|
132
131
|
>
|
|
133
132
|
{e('quickCommand')}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import TreeList from '../tree-list/tree-list'
|
|
2
|
-
import
|
|
2
|
+
import BookmarkTreeSelect from '../bookmark-form/tree-select'
|
|
3
3
|
|
|
4
4
|
export default function BookmarkTreeList (props) {
|
|
5
5
|
return props.bookmarkSelectMode
|
|
6
6
|
? (
|
|
7
|
-
<
|
|
7
|
+
<BookmarkTreeSelect
|
|
8
8
|
{...props}
|
|
9
9
|
/>
|
|
10
10
|
)
|
|
@@ -41,32 +41,26 @@ export default function KeywordForm (props) {
|
|
|
41
41
|
|
|
42
42
|
function renderItem (field, i, add, remove) {
|
|
43
43
|
return (
|
|
44
|
-
<Space
|
|
44
|
+
<Space.Compact
|
|
45
45
|
align='center'
|
|
46
46
|
key={field.key}
|
|
47
|
-
className='mg3r'
|
|
47
|
+
className='mg3r mg2b'
|
|
48
48
|
>
|
|
49
49
|
<FormItem
|
|
50
|
-
|
|
50
|
+
noStyle
|
|
51
|
+
required
|
|
52
|
+
name={[field.name, 'keyword']}
|
|
53
|
+
rules={[{ validator: checker }]}
|
|
51
54
|
>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
name={[field.name, 'keyword']}
|
|
56
|
-
rules={[{ validator: checker }]}
|
|
57
|
-
>
|
|
58
|
-
<Space.Compact>
|
|
59
|
-
<InputConfirm
|
|
60
|
-
addonBefore={renderBefore(field.name)}
|
|
61
|
-
/>
|
|
62
|
-
<Button
|
|
63
|
-
icon={<MinusCircleOutlined />}
|
|
64
|
-
onClick={() => remove(field.name)}
|
|
65
|
-
/>
|
|
66
|
-
</Space.Compact>
|
|
67
|
-
</FormItem>
|
|
55
|
+
<InputConfirm
|
|
56
|
+
addonBefore={renderBefore(field.name)}
|
|
57
|
+
/>
|
|
68
58
|
</FormItem>
|
|
69
|
-
|
|
59
|
+
<Button
|
|
60
|
+
icon={<MinusCircleOutlined />}
|
|
61
|
+
onClick={() => remove(field.name)}
|
|
62
|
+
/>
|
|
63
|
+
</Space.Compact>
|
|
70
64
|
)
|
|
71
65
|
}
|
|
72
66
|
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
MoonOutlined
|
|
7
7
|
} from '@ant-design/icons'
|
|
8
8
|
import message from '../common/message'
|
|
9
|
+
import { notification } from '../common/notification'
|
|
9
10
|
import {
|
|
10
11
|
Select,
|
|
11
12
|
Switch,
|
|
12
|
-
Alert,
|
|
13
13
|
Button,
|
|
14
14
|
Table,
|
|
15
15
|
Space,
|
|
@@ -42,8 +42,6 @@ const e = window.translate
|
|
|
42
42
|
export default class SettingCommon extends Component {
|
|
43
43
|
state = {
|
|
44
44
|
ready: false,
|
|
45
|
-
languageChanged: false,
|
|
46
|
-
passwordChanged: false,
|
|
47
45
|
submittingPass: false,
|
|
48
46
|
passInputFocused: false,
|
|
49
47
|
placeholderLogin: window.pre.requireAuth ? '********' : e('notSet'),
|
|
@@ -82,7 +80,6 @@ export default class SettingCommon extends Component {
|
|
|
82
80
|
this.setState({
|
|
83
81
|
loginPass: pass ? '********' : '',
|
|
84
82
|
submittingPass: false,
|
|
85
|
-
passwordChanged: true,
|
|
86
83
|
placeholderLogin: pass ? '********' : e('notSet')
|
|
87
84
|
}, () => {
|
|
88
85
|
this.submitting = false
|
|
@@ -121,10 +118,6 @@ export default class SettingCommon extends Component {
|
|
|
121
118
|
})
|
|
122
119
|
}
|
|
123
120
|
|
|
124
|
-
handleRestart = () => {
|
|
125
|
-
window.location.reload()
|
|
126
|
-
}
|
|
127
|
-
|
|
128
121
|
handleResetAll = () => {
|
|
129
122
|
this.saveConfig(
|
|
130
123
|
deepCopy(defaultSettings)
|
|
@@ -137,13 +130,24 @@ export default class SettingCommon extends Component {
|
|
|
137
130
|
})
|
|
138
131
|
}
|
|
139
132
|
|
|
140
|
-
handleChangeLang = language => {
|
|
141
|
-
this.
|
|
142
|
-
languageChanged: true
|
|
143
|
-
})
|
|
144
|
-
return this.saveConfig({
|
|
133
|
+
handleChangeLang = async language => {
|
|
134
|
+
await this.saveConfig({
|
|
145
135
|
language
|
|
146
136
|
})
|
|
137
|
+
notification.info({
|
|
138
|
+
message: (
|
|
139
|
+
<div>
|
|
140
|
+
{e('saveLang')}
|
|
141
|
+
<Button
|
|
142
|
+
onClick={() => window.location.reload()}
|
|
143
|
+
className='mg1l'
|
|
144
|
+
size='small'
|
|
145
|
+
>
|
|
146
|
+
{e('restartNow')}
|
|
147
|
+
</Button>
|
|
148
|
+
</div>
|
|
149
|
+
)
|
|
150
|
+
})
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
handleChangeTerminalTheme = id => {
|
|
@@ -199,30 +203,6 @@ export default class SettingCommon extends Component {
|
|
|
199
203
|
)
|
|
200
204
|
}
|
|
201
205
|
|
|
202
|
-
renderRestart = (name) => {
|
|
203
|
-
if (!this.state[name]) {
|
|
204
|
-
return null
|
|
205
|
-
}
|
|
206
|
-
return (
|
|
207
|
-
<div className='pd1t'>
|
|
208
|
-
<Alert
|
|
209
|
-
message={
|
|
210
|
-
<div>
|
|
211
|
-
{e('saveLang')}
|
|
212
|
-
<Button
|
|
213
|
-
onClick={this.handleRestart}
|
|
214
|
-
className='mg1l'
|
|
215
|
-
>
|
|
216
|
-
{e('restartNow')}
|
|
217
|
-
</Button>
|
|
218
|
-
</div>
|
|
219
|
-
}
|
|
220
|
-
type='success'
|
|
221
|
-
/>
|
|
222
|
-
</div>
|
|
223
|
-
)
|
|
224
|
-
}
|
|
225
|
-
|
|
226
206
|
renderNumber = (name, options, title = '') => {
|
|
227
207
|
let value = this.props.config[name]
|
|
228
208
|
if (options.valueParser) {
|
|
@@ -296,7 +276,7 @@ export default class SettingCommon extends Component {
|
|
|
296
276
|
}
|
|
297
277
|
return (
|
|
298
278
|
<div className='pd2b'>
|
|
299
|
-
<Space.Compact
|
|
279
|
+
<Space.Compact className='width-100'>
|
|
300
280
|
<InputConfirm
|
|
301
281
|
value={value}
|
|
302
282
|
onChange={onChange}
|
|
@@ -592,7 +572,6 @@ export default class SettingCommon extends Component {
|
|
|
592
572
|
</Select>
|
|
593
573
|
<Link className='mg1l' to={createEditLangLink(language)}>{e('edit')}</Link>
|
|
594
574
|
</div>
|
|
595
|
-
{this.renderRestart('languageChanged')}
|
|
596
575
|
<div className='pd1b'>{e('default')} {e('execWindows')}</div>
|
|
597
576
|
{
|
|
598
577
|
this.renderTextExec('execWindows')
|
|
@@ -540,7 +540,7 @@ export default class SettingTerminal extends Component {
|
|
|
540
540
|
<Flex flex='auto'>{this.renderFontFamily()}</Flex>
|
|
541
541
|
</Flex>
|
|
542
542
|
</div>
|
|
543
|
-
<div
|
|
543
|
+
<div>
|
|
544
544
|
<div className='pd1b'>
|
|
545
545
|
<span className='inline-title mg1r'>{e('keywordsHighlight')}</span>
|
|
546
546
|
<HelpIcon
|
|
@@ -24,8 +24,14 @@
|
|
|
24
24
|
width 340px
|
|
25
25
|
bottom 0
|
|
26
26
|
padding 20px 0 20px 20px
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
display flex
|
|
28
|
+
flex-direction column
|
|
29
|
+
.model-bookmark-tree-wrap
|
|
30
|
+
flex 1
|
|
31
|
+
display flex
|
|
32
|
+
flex-direction column
|
|
33
|
+
overflow hidden
|
|
34
|
+
min-height 0
|
|
29
35
|
.setting-row-right
|
|
30
36
|
left 340px
|
|
31
37
|
right 0
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
* bookmark select
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { memo } from 'react'
|
|
5
|
+
import { memo, useState } from 'react'
|
|
6
6
|
import BookmarkWrap from './bookmark'
|
|
7
7
|
import History from './history'
|
|
8
8
|
import { Tabs, Tooltip } from 'antd'
|
|
9
|
+
import MultiSelectModal from '../common/multi-select-modal'
|
|
9
10
|
import {
|
|
10
11
|
ArrowsAltOutlined,
|
|
11
12
|
EditOutlined,
|
|
12
13
|
PlusCircleOutlined,
|
|
13
14
|
ShrinkOutlined,
|
|
14
15
|
PushpinOutlined,
|
|
15
|
-
UnorderedListOutlined
|
|
16
|
+
UnorderedListOutlined,
|
|
17
|
+
SelectOutlined
|
|
16
18
|
} from '@ant-design/icons'
|
|
17
19
|
|
|
18
20
|
const e = window.translate
|
|
@@ -20,6 +22,7 @@ const e = window.translate
|
|
|
20
22
|
export default memo(function SidebarPanel (props) {
|
|
21
23
|
const { sidebarPanelTab, pinned } = props
|
|
22
24
|
const { store } = window
|
|
25
|
+
const [openSelectModal, setOpenSelectModal] = useState(false)
|
|
23
26
|
const prps = {
|
|
24
27
|
className: 'font16 mg1x mg2l pointer iblock control-icon'
|
|
25
28
|
}
|
|
@@ -81,6 +84,12 @@ export default memo(function SidebarPanel (props) {
|
|
|
81
84
|
<ShrinkOutlined
|
|
82
85
|
{...pop3}
|
|
83
86
|
/>
|
|
87
|
+
</Tooltip>,
|
|
88
|
+
<Tooltip title={e('open') + ' ' + e('bookmarks')} key='multi'>
|
|
89
|
+
<SelectOutlined
|
|
90
|
+
{...prps}
|
|
91
|
+
onClick={() => setOpenSelectModal(true)}
|
|
92
|
+
/>
|
|
84
93
|
</Tooltip>
|
|
85
94
|
]
|
|
86
95
|
}
|
|
@@ -119,6 +128,10 @@ export default memo(function SidebarPanel (props) {
|
|
|
119
128
|
? <BookmarkWrap {...props} />
|
|
120
129
|
: <History store={store} />
|
|
121
130
|
}
|
|
131
|
+
<MultiSelectModal
|
|
132
|
+
open={openSelectModal}
|
|
133
|
+
onClose={() => setOpenSelectModal(false)}
|
|
134
|
+
/>
|
|
122
135
|
</div>
|
|
123
136
|
)
|
|
124
137
|
})
|
|
@@ -39,9 +39,15 @@
|
|
|
39
39
|
right 0
|
|
40
40
|
top 112px
|
|
41
41
|
bottom 0
|
|
42
|
-
overflow
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
overflow hidden
|
|
43
|
+
display flex
|
|
44
|
+
flex-direction column
|
|
45
|
+
.sidebar-inner
|
|
46
|
+
flex 1
|
|
47
|
+
display flex
|
|
48
|
+
flex-direction column
|
|
49
|
+
overflow hidden
|
|
50
|
+
min-height 0
|
|
45
51
|
.not-system-ui.is-mac
|
|
46
52
|
.sidebar-bar
|
|
47
53
|
margin-top 20px
|
|
@@ -72,16 +72,20 @@ export default function AddBtnMenu ({
|
|
|
72
72
|
<DragHandle
|
|
73
73
|
{...dragProps}
|
|
74
74
|
/>
|
|
75
|
-
<div
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
<div className='add-menu-header'>
|
|
76
|
+
<div
|
|
77
|
+
className={cls}
|
|
78
|
+
onClick={onNewSsh}
|
|
79
|
+
>
|
|
80
|
+
<CodeFilled /> {e('newBookmark')}
|
|
81
|
+
</div>
|
|
82
|
+
{addTabBtn}
|
|
83
|
+
</div>
|
|
84
|
+
<div className='add-menu-list'>
|
|
85
|
+
<BookmarksList
|
|
86
|
+
store={window.store}
|
|
87
|
+
/>
|
|
80
88
|
</div>
|
|
81
|
-
{addTabBtn}
|
|
82
|
-
<BookmarksList
|
|
83
|
-
store={window.store}
|
|
84
|
-
/>
|
|
85
89
|
</div>
|
|
86
90
|
)
|
|
87
91
|
}
|
|
@@ -8,10 +8,20 @@
|
|
|
8
8
|
box-shadow 0 4px 12px rgba(0, 0, 0, 0.3), 0 0 0 1px var(--main-darker)
|
|
9
9
|
min-width 300px
|
|
10
10
|
max-width 600px
|
|
11
|
-
overflow
|
|
11
|
+
overflow hidden
|
|
12
12
|
margin-top 4px
|
|
13
13
|
padding 4px 15px
|
|
14
|
+
display flex
|
|
15
|
+
flex-direction column
|
|
14
16
|
.drag-handle
|
|
15
17
|
right 3px
|
|
16
18
|
display block
|
|
19
|
+
.add-menu-header
|
|
20
|
+
flex-shrink 0
|
|
21
|
+
.add-menu-list
|
|
22
|
+
flex 1
|
|
23
|
+
overflow hidden
|
|
24
|
+
display flex
|
|
25
|
+
flex-direction column
|
|
26
|
+
min-height 0
|
|
17
27
|
|
|
@@ -399,7 +399,11 @@ class Tab extends Component {
|
|
|
399
399
|
}
|
|
400
400
|
|
|
401
401
|
render () {
|
|
402
|
-
const {
|
|
402
|
+
const {
|
|
403
|
+
isLast,
|
|
404
|
+
tab,
|
|
405
|
+
currentBatchTabId
|
|
406
|
+
} = this.props
|
|
403
407
|
const {
|
|
404
408
|
id,
|
|
405
409
|
isEditting,
|
|
@@ -411,10 +415,12 @@ class Tab extends Component {
|
|
|
411
415
|
terminalOnData
|
|
412
416
|
} = this.state
|
|
413
417
|
const active = id === currentBatchTabId
|
|
418
|
+
const activeAll = id === window.store.activeTabId
|
|
414
419
|
const cls = classnames(
|
|
415
420
|
`tab-${id}`,
|
|
416
421
|
'tab',
|
|
417
422
|
{ active },
|
|
423
|
+
{ 'active-all': activeAll },
|
|
418
424
|
{
|
|
419
425
|
'tab-last': isLast
|
|
420
426
|
},
|
|
@@ -849,14 +849,16 @@ export default class ItemListTree extends Component {
|
|
|
849
849
|
: []
|
|
850
850
|
return (
|
|
851
851
|
<div className={`tree-list item-type-${type}`}>
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
852
|
+
<div className='tree-list-header'>
|
|
853
|
+
{
|
|
854
|
+
staticList
|
|
855
|
+
? null
|
|
856
|
+
: this.renderNewButtons()
|
|
857
|
+
}
|
|
858
|
+
{
|
|
859
|
+
this.renderSearch()
|
|
860
|
+
}
|
|
861
|
+
</div>
|
|
860
862
|
<div className='item-list-wrap' style={listStyle}>
|
|
861
863
|
{this.renderNewCat({ id: '' })}
|
|
862
864
|
{level1Bookgroups.map(this.renderGroup)}
|
|
@@ -85,3 +85,17 @@
|
|
|
85
85
|
max-height 300px
|
|
86
86
|
overflow-y auto
|
|
87
87
|
padding 8px
|
|
88
|
+
|
|
89
|
+
.tree-list
|
|
90
|
+
display flex
|
|
91
|
+
flex-direction column
|
|
92
|
+
height 100%
|
|
93
|
+
overflow hidden
|
|
94
|
+
|
|
95
|
+
.tree-list-header
|
|
96
|
+
flex-shrink 0
|
|
97
|
+
|
|
98
|
+
.item-list-wrap
|
|
99
|
+
flex 1
|
|
100
|
+
overflow-y auto
|
|
101
|
+
min-height 0
|
package/client/store/bookmark.js
CHANGED
|
@@ -19,6 +19,13 @@ export default Store => {
|
|
|
19
19
|
return window.store.setItems('bookmarks', items)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
Store.prototype.openBookmarks = function (ids) {
|
|
23
|
+
const { store } = window
|
|
24
|
+
ids.forEach(id => {
|
|
25
|
+
store.onSelectBookmark(id)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
Store.prototype.addSshConfigs = function (items) {
|
|
23
30
|
const { store } = window
|
|
24
31
|
|