@electerm/electerm-react 2.5.6 → 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/auth/login.jsx +1 -1
- package/client/components/bookmark-form/bookmark-form.styl +2 -0
- package/client/components/bookmark-form/common/fields.jsx +1 -1
- package/client/components/bookmark-form/common/hex-input.jsx +6 -1
- package/client/components/bookmark-form/common/run-scripts.jsx +23 -19
- package/client/components/bookmark-form/common/ssh-host-selector.jsx +1 -1
- package/client/components/bookmark-form/common/ssh-tunnels.jsx +0 -1
- package/client/components/bookmark-form/{tree-delete.jsx → tree-select.jsx} +27 -13
- package/client/components/common/input-confirm-common.jsx +18 -11
- package/client/components/common/input-confirm.jsx +1 -3
- package/client/components/common/input-number-confirm.jsx +1 -3
- 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/common/password.jsx +0 -4
- package/client/components/quick-commands/quick-commands-box.jsx +9 -9
- package/client/components/quick-commands/quick-commands-list-form.jsx +15 -13
- package/client/components/setting-panel/bookmark-tree-list.jsx +2 -2
- package/client/components/setting-panel/keywords-form.jsx +10 -15
- package/client/components/setting-panel/setting-common.jsx +19 -40
- package/client/components/setting-panel/setting-terminal.jsx +9 -6
- package/client/components/setting-panel/setting-wrap.styl +8 -2
- package/client/components/setting-panel/terminal-bg-config.jsx +1 -1
- package/client/components/sftp/address-bar.jsx +3 -2
- package/client/components/sftp/address-bookmark.jsx +1 -1
- package/client/components/sftp/file-item.jsx +2 -2
- package/client/components/sftp/keyword-filter.jsx +2 -2
- package/client/components/shortcuts/shortcut-editor.jsx +1 -1
- package/client/components/sidebar/sidebar-panel.jsx +15 -2
- package/client/components/sidebar/sidebar.styl +9 -3
- package/client/components/sys-menu/zoom.jsx +6 -4
- 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/terminal/term-search.jsx +1 -2
- package/client/components/terminal/terminal.jsx +10 -1
- package/client/components/text-editor/simple-editor.jsx +1 -1
- package/client/components/tree-list/tree-list.jsx +14 -12
- package/client/components/tree-list/tree-list.styl +15 -0
- package/client/components/web/address-bar.jsx +2 -2
- 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'
|
|
@@ -90,7 +90,7 @@ export function renderFormItem (item, formItemLayout, form, ctxProps, index) {
|
|
|
90
90
|
)
|
|
91
91
|
break
|
|
92
92
|
case 'colorTitle':
|
|
93
|
-
control = <InputAutoFocus
|
|
93
|
+
control = <InputAutoFocus prefix={<ColorPickerItem />} {...item.props} />
|
|
94
94
|
break
|
|
95
95
|
case 'password':
|
|
96
96
|
control = <Password {...item.props} />
|
|
@@ -17,6 +17,11 @@ export const HexInput = (props) => {
|
|
|
17
17
|
return <CheckOutlined className='pointer' onClick={submit} />
|
|
18
18
|
}
|
|
19
19
|
return (
|
|
20
|
-
<Input
|
|
20
|
+
<Input
|
|
21
|
+
prefix='#' {...props}
|
|
22
|
+
value={v}
|
|
23
|
+
onChange={handleChange}
|
|
24
|
+
suffix={renderAfter()}
|
|
25
|
+
/>
|
|
21
26
|
)
|
|
22
27
|
}
|
|
@@ -17,40 +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
30
|
<InputNumber
|
|
29
31
|
min={1}
|
|
30
32
|
step={1}
|
|
33
|
+
prefix={e('loginScriptDelay')}
|
|
34
|
+
suffix='ms'
|
|
31
35
|
max={65535}
|
|
32
|
-
|
|
36
|
+
className='number-input'
|
|
33
37
|
rules={[{ required: true, message: e('loginScriptDelay') + ' required' }]}
|
|
34
|
-
className='compact-input'
|
|
35
38
|
/>
|
|
36
39
|
</FormItem>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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'
|
|
47
56
|
/>
|
|
48
|
-
</
|
|
49
|
-
<Button
|
|
50
|
-
icon={<MinusCircleOutlined />}
|
|
51
|
-
onClick={() => remove(field.name)}
|
|
52
|
-
className='mg24b'
|
|
53
|
-
/>
|
|
57
|
+
</Space.Compact>
|
|
54
58
|
</Space>
|
|
55
59
|
</>
|
|
56
60
|
)
|
|
@@ -53,7 +53,7 @@ export default function SshHostSelector ({ ips = [], useIp, form, onBlur, onPast
|
|
|
53
53
|
name='host'
|
|
54
54
|
onBlur={props.onBlur}
|
|
55
55
|
onPaste={e => onPaste(e, form)}
|
|
56
|
-
|
|
56
|
+
prefix={<ColorPickerItem />}
|
|
57
57
|
/>
|
|
58
58
|
</FormItem>
|
|
59
59
|
</FormItem>
|
|
@@ -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}
|
|
@@ -7,8 +7,8 @@ export default function InputConfirmCommon ({
|
|
|
7
7
|
value,
|
|
8
8
|
onChange,
|
|
9
9
|
inputComponent: InputComponent,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
addonBefore,
|
|
11
|
+
addonAfter,
|
|
12
12
|
...rest
|
|
13
13
|
}) {
|
|
14
14
|
const [localValue, setLocalValue] = useState(value)
|
|
@@ -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
|
<>
|
|
@@ -50,10 +56,11 @@ export default function InputConfirmCommon ({
|
|
|
50
56
|
: null
|
|
51
57
|
const { className, ...restProps } = rest
|
|
52
58
|
const cls = className ? `${className} input-confirm` : 'input-confirm'
|
|
53
|
-
const
|
|
59
|
+
const beforeAddon = addonBefore || null
|
|
60
|
+
const afterAddon = addonAfter || icons
|
|
54
61
|
? (
|
|
55
62
|
<Space.Addon>
|
|
56
|
-
{
|
|
63
|
+
{addonAfter}
|
|
57
64
|
{icons}
|
|
58
65
|
</Space.Addon>
|
|
59
66
|
)
|
|
@@ -62,17 +69,17 @@ export default function InputConfirmCommon ({
|
|
|
62
69
|
const childProps = {
|
|
63
70
|
...restProps,
|
|
64
71
|
value: localValue,
|
|
65
|
-
onChange: handleChange
|
|
72
|
+
onChange: handleChange,
|
|
73
|
+
onBlur: handleBlur
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
const inputElement = <InputComponent {...childProps} />
|
|
69
77
|
|
|
70
78
|
return (
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
</div>
|
|
79
|
+
<Space.Compact className={cls}>
|
|
80
|
+
{beforeAddon}
|
|
81
|
+
{inputElement}
|
|
82
|
+
{afterAddon}
|
|
83
|
+
</Space.Compact>
|
|
77
84
|
)
|
|
78
85
|
}
|
|
@@ -2,12 +2,10 @@ import { Input } from 'antd'
|
|
|
2
2
|
import InputConfirmCommon from './input-confirm-common'
|
|
3
3
|
|
|
4
4
|
export default function InputConfirm (props) {
|
|
5
|
-
const { extraAddonAfter, ...rest } = props
|
|
6
5
|
return (
|
|
7
6
|
<InputConfirmCommon
|
|
8
|
-
{...
|
|
7
|
+
{...props}
|
|
9
8
|
inputComponent={Input}
|
|
10
|
-
extraAddonAfter={extraAddonAfter}
|
|
11
9
|
/>
|
|
12
10
|
)
|
|
13
11
|
}
|
|
@@ -2,12 +2,10 @@ import { InputNumber } from 'antd'
|
|
|
2
2
|
import InputConfirmCommon from './input-confirm-common'
|
|
3
3
|
|
|
4
4
|
export default function InputNumberConfirm (props) {
|
|
5
|
-
const { addonAfter, ...rest } = props
|
|
6
5
|
return (
|
|
7
6
|
<InputConfirmCommon
|
|
8
|
-
{...
|
|
7
|
+
{...props}
|
|
9
8
|
inputComponent={InputNumber}
|
|
10
|
-
extraAddonAfter={addonAfter}
|
|
11
9
|
/>
|
|
12
10
|
)
|
|
13
11
|
}
|
|
@@ -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
|
|
@@ -49,9 +49,6 @@ export default forwardRef(function Password (props, ref) {
|
|
|
49
49
|
}
|
|
50
50
|
}, [props.onBlur])
|
|
51
51
|
|
|
52
|
-
// Keep addonBefore as-is from props; must be null when caps lock is off
|
|
53
|
-
const addonBefore = props.addonBefore ?? null
|
|
54
|
-
|
|
55
52
|
// Show caps lock indicator inside prefix to avoid remounting the input wrapper
|
|
56
53
|
let capsPrefix = null
|
|
57
54
|
if (isCapsLockOn) {
|
|
@@ -75,7 +72,6 @@ export default forwardRef(function Password (props, ref) {
|
|
|
75
72
|
<Input.Password
|
|
76
73
|
{...props}
|
|
77
74
|
ref={ref}
|
|
78
|
-
addonBefore={addonBefore}
|
|
79
75
|
prefix={prefix}
|
|
80
76
|
onKeyDown={handleKeyEvent}
|
|
81
77
|
onKeyUp={handleKeyEvent}
|
|
@@ -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,22 +18,26 @@ 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
34
|
<InputNumber
|
|
33
35
|
min={1}
|
|
34
36
|
step={1}
|
|
35
37
|
max={65535}
|
|
36
|
-
addonBefore={e('delay')}
|
|
37
38
|
placeholder={100}
|
|
38
39
|
className='compact-input'
|
|
40
|
+
suffix='ms'
|
|
39
41
|
/>
|
|
40
42
|
</FormItem>
|
|
41
43
|
<FormItem
|
|
@@ -43,6 +45,7 @@ export default function renderQm () {
|
|
|
43
45
|
name={[field.name, 'command']}
|
|
44
46
|
required
|
|
45
47
|
className='mg2x'
|
|
48
|
+
noStyle
|
|
46
49
|
>
|
|
47
50
|
<Input.TextArea
|
|
48
51
|
autoSize={{ minRows: 1 }}
|
|
@@ -56,9 +59,8 @@ export default function renderQm () {
|
|
|
56
59
|
<Button
|
|
57
60
|
icon={<MinusCircleOutlined />}
|
|
58
61
|
onClick={() => remove(field.name)}
|
|
59
|
-
className='mg24b'
|
|
60
62
|
/>
|
|
61
|
-
</Space>
|
|
63
|
+
</Space.Compact>
|
|
62
64
|
)
|
|
63
65
|
}
|
|
64
66
|
const commonCmds = [
|
|
@@ -86,28 +88,29 @@ export default function renderQm () {
|
|
|
86
88
|
|
|
87
89
|
const cmds = commonCmds.map(c => {
|
|
88
90
|
return (
|
|
89
|
-
<
|
|
91
|
+
<Button
|
|
90
92
|
title={c.desc}
|
|
91
|
-
|
|
93
|
+
type='text'
|
|
92
94
|
key={c.cmd}
|
|
95
|
+
size='small'
|
|
93
96
|
onClick={() => {
|
|
94
97
|
copy(c.cmd)
|
|
95
98
|
}}
|
|
96
99
|
>
|
|
97
100
|
<b className='pointer'>{c.cmd}</b>
|
|
98
|
-
</
|
|
101
|
+
</Button>
|
|
99
102
|
)
|
|
100
103
|
})
|
|
101
104
|
const label = (
|
|
102
105
|
<div>
|
|
103
|
-
{e('
|
|
106
|
+
{e('quickCommands')}
|
|
104
107
|
<HelpIcon
|
|
105
108
|
title={cmds}
|
|
106
109
|
/>
|
|
107
110
|
</div>
|
|
108
111
|
)
|
|
109
112
|
return (
|
|
110
|
-
<FormItem
|
|
113
|
+
<FormItem label={label}>
|
|
111
114
|
<FormList
|
|
112
115
|
name='commands'
|
|
113
116
|
>
|
|
@@ -124,7 +127,6 @@ export default function renderQm () {
|
|
|
124
127
|
<Button
|
|
125
128
|
type='dashed'
|
|
126
129
|
onClick={() => add()}
|
|
127
|
-
block
|
|
128
130
|
icon={<PlusOutlined />}
|
|
129
131
|
>
|
|
130
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,31 +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
|
-
<InputConfirm
|
|
59
|
-
addonBefore={renderBefore(field.name)}
|
|
60
|
-
/>
|
|
61
|
-
</FormItem>
|
|
55
|
+
<InputConfirm
|
|
56
|
+
addonBefore={renderBefore(field.name)}
|
|
57
|
+
/>
|
|
62
58
|
</FormItem>
|
|
63
59
|
<Button
|
|
64
60
|
icon={<MinusCircleOutlined />}
|
|
65
61
|
onClick={() => remove(field.name)}
|
|
66
|
-
className='mg24b'
|
|
67
62
|
/>
|
|
68
|
-
</Space>
|
|
63
|
+
</Space.Compact>
|
|
69
64
|
)
|
|
70
65
|
}
|
|
71
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}
|
|
@@ -442,7 +422,7 @@ export default class SettingCommon extends Component {
|
|
|
442
422
|
onFocus: this.handleLoginPassFocus,
|
|
443
423
|
onBlur: this.handleLoginPassBlur,
|
|
444
424
|
onChange: this.handleChangeLoginPass,
|
|
445
|
-
|
|
425
|
+
suffix: this.renderLoginPassAfter(),
|
|
446
426
|
placeholder: placeholderLogin
|
|
447
427
|
}
|
|
448
428
|
return (
|
|
@@ -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')
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
Button,
|
|
12
12
|
AutoComplete,
|
|
13
13
|
Tooltip,
|
|
14
|
-
Flex
|
|
14
|
+
Flex,
|
|
15
|
+
Space
|
|
15
16
|
} from 'antd'
|
|
16
17
|
import deepCopy from 'json-deep-copy'
|
|
17
18
|
import {
|
|
@@ -176,23 +177,25 @@ export default class SettingTerminal extends Component {
|
|
|
176
177
|
<Button
|
|
177
178
|
onClick={this.handleChooseFolder}
|
|
178
179
|
className='mg1r'
|
|
180
|
+
type='text'
|
|
179
181
|
size='small'
|
|
180
182
|
>
|
|
181
183
|
{e('chooseFolder')}
|
|
182
184
|
</Button>
|
|
183
185
|
<Button
|
|
184
186
|
size='small'
|
|
187
|
+
type='text'
|
|
185
188
|
onClick={() => this.handleLogChange('')}
|
|
186
189
|
>
|
|
187
190
|
{e('reset')}
|
|
188
191
|
</Button>
|
|
189
192
|
</>
|
|
190
193
|
),
|
|
194
|
+
prefix: e('terminalLogPath'),
|
|
191
195
|
addonBefore: (
|
|
192
|
-
|
|
193
|
-
<span className='mg1r'>{e('terminalLogPath')}</span>
|
|
196
|
+
<Space.Addon>
|
|
194
197
|
<ShowItem to={path} />
|
|
195
|
-
|
|
198
|
+
</Space.Addon>
|
|
196
199
|
)
|
|
197
200
|
}
|
|
198
201
|
return (
|
|
@@ -340,7 +343,7 @@ export default class SettingTerminal extends Component {
|
|
|
340
343
|
options={dataSource.map(this.renderBgOption)}
|
|
341
344
|
>
|
|
342
345
|
<InputConfirm
|
|
343
|
-
|
|
346
|
+
addonAfter={after}
|
|
344
347
|
/>
|
|
345
348
|
</AutoComplete>
|
|
346
349
|
</Tooltip>
|
|
@@ -537,7 +540,7 @@ export default class SettingTerminal extends Component {
|
|
|
537
540
|
<Flex flex='auto'>{this.renderFontFamily()}</Flex>
|
|
538
541
|
</Flex>
|
|
539
542
|
</div>
|
|
540
|
-
<div
|
|
543
|
+
<div>
|
|
541
544
|
<div className='pd1b'>
|
|
542
545
|
<span className='inline-title mg1r'>{e('keywordsHighlight')}</span>
|
|
543
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
|
|
@@ -66,6 +66,7 @@ function renderAddonBefore (props, realPath) {
|
|
|
66
66
|
realPath={realPath}
|
|
67
67
|
host={host}
|
|
68
68
|
type={type}
|
|
69
|
+
className='mg1r'
|
|
69
70
|
onClickHistory={props.onClickHistory}
|
|
70
71
|
/>
|
|
71
72
|
</>
|
|
@@ -134,11 +135,11 @@ export default function AddressBar (props) {
|
|
|
134
135
|
value={path}
|
|
135
136
|
onChange={e => props.onChange(e, n)}
|
|
136
137
|
onPressEnter={e => props.onGoto(type, e)}
|
|
137
|
-
|
|
138
|
+
prefix={renderAddonBefore(props, realPath)}
|
|
138
139
|
onFocus={() => props.onInputFocus(type)}
|
|
139
140
|
onBlur={() => props.onInputBlur(type)}
|
|
140
141
|
disabled={loadingSftp}
|
|
141
|
-
|
|
142
|
+
suffix={
|
|
142
143
|
renderAddonAfter(isLoadingRemote, onGoto, GoIcon, type)
|
|
143
144
|
}
|
|
144
145
|
/>
|
|
@@ -74,6 +74,7 @@ export default class FileSection extends React.Component {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
componentWillUnmount () {
|
|
77
|
+
filesRef.remove(this.id)
|
|
77
78
|
clearTimeout(this.timer)
|
|
78
79
|
this.timer = null
|
|
79
80
|
this.domRef = null
|
|
@@ -82,7 +83,6 @@ export default class FileSection extends React.Component {
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
clearRef = () => {
|
|
85
|
-
filesRef.remove(this.id)
|
|
86
86
|
refs.remove(this.id)
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -1112,7 +1112,7 @@ export default class FileSection extends React.Component {
|
|
|
1112
1112
|
<div className='sftp-item'>
|
|
1113
1113
|
<Input
|
|
1114
1114
|
value={nameTemp}
|
|
1115
|
-
|
|
1115
|
+
prefix={pre}
|
|
1116
1116
|
onChange={this.handleChange}
|
|
1117
1117
|
onBlur={this.handleBlur}
|
|
1118
1118
|
onPressEnter={this.handleBlur}
|
|
@@ -37,11 +37,11 @@ export default function KeywordFilter ({ keyword, type, updateKeyword }) {
|
|
|
37
37
|
const inputProps = {
|
|
38
38
|
value: text,
|
|
39
39
|
onChange: handleInputChange,
|
|
40
|
-
|
|
40
|
+
prefix: <FilterOutlined />,
|
|
41
41
|
onKeyPress: handleKeyPress,
|
|
42
42
|
placeholder: e('keyword'),
|
|
43
43
|
className: 'keyword-filter-input',
|
|
44
|
-
|
|
44
|
+
suffix: <CheckOutlined onClick={applyFilter} />
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const tooltipContent = (
|
|
@@ -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
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import InputNumberConfirm from '../common/input-number-confirm'
|
|
2
|
-
|
|
2
|
+
import {
|
|
3
|
+
Space
|
|
4
|
+
} from 'antd'
|
|
3
5
|
import {
|
|
4
6
|
MinusCircleOutlined,
|
|
5
7
|
PlusCircleOutlined
|
|
@@ -18,9 +20,9 @@ export default function ZoomMenu (props) {
|
|
|
18
20
|
step={1}
|
|
19
21
|
min={25}
|
|
20
22
|
max={500}
|
|
21
|
-
|
|
23
|
+
suffix='%'
|
|
22
24
|
addonBefore={
|
|
23
|
-
|
|
25
|
+
<Space.Addon>
|
|
24
26
|
<PlusCircleOutlined
|
|
25
27
|
onClick={() => store.zoom(0.25, true)}
|
|
26
28
|
className='mg1r pointer font16'
|
|
@@ -29,7 +31,7 @@ export default function ZoomMenu (props) {
|
|
|
29
31
|
onClick={() => store.zoom(-0.25, true)}
|
|
30
32
|
className='pointer font16'
|
|
31
33
|
/>
|
|
32
|
-
|
|
34
|
+
</Space.Addon>
|
|
33
35
|
}
|
|
34
36
|
/>
|
|
35
37
|
)
|
|
@@ -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
|
},
|
|
@@ -206,9 +206,8 @@ export default class TermSearch extends PureComponent {
|
|
|
206
206
|
value: termSearch,
|
|
207
207
|
className: 'iblock',
|
|
208
208
|
onChange: this.handleChange,
|
|
209
|
-
suffix: this.renderSuffix()
|
|
209
|
+
suffix: <>{this.renderSuffix()} {this.renderAfter()}</>,
|
|
210
210
|
onPressEnter: this.next,
|
|
211
|
-
addonAfter: this.renderAfter(),
|
|
212
211
|
selectall: true
|
|
213
212
|
}
|
|
214
213
|
return (
|
|
@@ -239,12 +239,21 @@ class Term extends Component {
|
|
|
239
239
|
type: 'shell_integration',
|
|
240
240
|
execute: async () => {
|
|
241
241
|
await this.injectShellIntegration()
|
|
242
|
+
if (currSftpFollow) {
|
|
243
|
+
this.attachAddon._sendData('\r')
|
|
244
|
+
}
|
|
242
245
|
}
|
|
243
246
|
})
|
|
244
247
|
} else {
|
|
245
248
|
// No active queue, inject directly
|
|
246
|
-
this.injectShellIntegration()
|
|
249
|
+
this.injectShellIntegration().then(() => {
|
|
250
|
+
if (currSftpFollow) {
|
|
251
|
+
this.attachAddon._sendData('\r')
|
|
252
|
+
}
|
|
253
|
+
})
|
|
247
254
|
}
|
|
255
|
+
} else if (this.shellInjected && currSftpFollow) {
|
|
256
|
+
this.getCwd()
|
|
248
257
|
}
|
|
249
258
|
}
|
|
250
259
|
if (
|
|
@@ -570,8 +570,8 @@ export default class ItemListTree extends Component {
|
|
|
570
570
|
value={categoryTitle}
|
|
571
571
|
onChange={this.handleChangeEdit}
|
|
572
572
|
onPressEnter={this.handleSubmitEdit}
|
|
573
|
-
|
|
574
|
-
|
|
573
|
+
prefix={colorPicker}
|
|
574
|
+
suffix={confirm}
|
|
575
575
|
/>
|
|
576
576
|
)
|
|
577
577
|
}
|
|
@@ -757,8 +757,8 @@ export default class ItemListTree extends Component {
|
|
|
757
757
|
value={bookmarkGroupTitle}
|
|
758
758
|
onPressEnter={this.handleSubmit}
|
|
759
759
|
onChange={this.handleChangeBookmarkGroupTitle}
|
|
760
|
-
|
|
761
|
-
|
|
760
|
+
prefix={colorPicker}
|
|
761
|
+
suffix={confirm}
|
|
762
762
|
onBlur={this.handleBlurBookmarkGroupTitle}
|
|
763
763
|
/>
|
|
764
764
|
</div>
|
|
@@ -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)}
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
.tree-control-btn
|
|
29
29
|
display inline-block
|
|
30
30
|
vertical-align middle
|
|
31
|
+
line-height 26px
|
|
31
32
|
&.item-dragover-top
|
|
32
33
|
border-top 1px solid #18d551
|
|
33
34
|
.tree-item-title
|
|
@@ -84,3 +85,17 @@
|
|
|
84
85
|
max-height 300px
|
|
85
86
|
overflow-y auto
|
|
86
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
|
|
@@ -33,12 +33,12 @@ export default function AddressBar (props) {
|
|
|
33
33
|
<Input
|
|
34
34
|
value={url}
|
|
35
35
|
onClick={handleClick}
|
|
36
|
-
|
|
36
|
+
prefix={
|
|
37
37
|
<ReloadOutlined
|
|
38
38
|
onClick={onReload}
|
|
39
39
|
/>
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
suffix={
|
|
42
42
|
<GlobalOutlined
|
|
43
43
|
onClick={onOpen}
|
|
44
44
|
/>
|
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
|
|