@electerm/electerm-react 1.51.8 → 1.51.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/client/common/constants.js +16 -1
- package/client/common/default-setting.js +0 -1
- package/client/common/is-color-dark.js +15 -11
- package/client/common/new-terminal.js +2 -5
- package/client/common/reverse-color.js +12 -0
- package/client/common/ws.js +4 -1
- package/client/components/bookmark-form/render-connection-hopping.jsx +25 -2
- package/client/components/bookmark-form/ssh-form.jsx +1 -2
- package/client/components/bookmark-form/tree-delete.jsx +5 -10
- package/client/components/bookmark-form/use-ui.jsx +1 -2
- package/client/components/common/connection-hopping-warning-text.jsx +36 -0
- package/client/components/common/drag-handle.jsx +60 -0
- package/client/components/common/drag-handle.styl +12 -0
- package/client/components/layout/layout.jsx +3 -2
- package/client/components/main/connection-hopping-warnning.jsx +45 -0
- package/client/components/main/error-wrapper.jsx +120 -5
- package/client/components/main/main.jsx +23 -3
- package/client/components/main/upgrade.jsx +4 -9
- package/client/components/main/wrapper.styl +2 -1
- package/client/components/profile/profile-form-ssh.jsx +1 -1
- package/client/components/rdp/resolution-edit.jsx +3 -5
- package/client/components/session/session.jsx +7 -2
- package/client/components/setting-panel/setting-common.jsx +28 -7
- package/client/components/setting-panel/setting-terminal.jsx +7 -4
- package/client/components/sftp/confirm-modal-store.jsx +3 -4
- package/client/components/sftp/sftp-entry.jsx +2 -5
- package/client/components/sftp/transfer-conflict-store.jsx +1 -3
- package/client/components/sftp/transport-action-store.jsx +21 -10
- package/client/components/side-panel-r/side-panel-r.jsx +13 -40
- package/client/components/sidebar/bookmark-select.jsx +0 -3
- package/client/components/sidebar/index.jsx +1 -6
- package/client/components/sidebar/side-panel.jsx +27 -51
- package/client/components/sidebar/sidebar.styl +0 -9
- package/client/components/ssh-config/load-ssh-configs.jsx +106 -0
- package/client/components/ssh-config/ssh-config-item.jsx +26 -0
- package/client/components/ssh-config/ssh-config-load-notify.jsx +60 -0
- package/client/components/tabs/tab.jsx +9 -10
- package/client/components/tabs/tabs.styl +6 -1
- package/client/components/terminal/index.jsx +4 -18
- package/client/components/tree-list/bookmark-toolbar.jsx +203 -0
- package/client/components/tree-list/bookmark-transport.jsx +2 -0
- package/client/components/tree-list/tree-list.jsx +25 -32
- package/client/store/bookmark-group.js +2 -13
- package/client/store/bookmark.js +43 -1
- package/client/store/common.js +2 -8
- package/client/store/index.js +45 -50
- package/client/store/init-state.js +16 -20
- package/client/store/load-data.js +5 -10
- package/client/store/setting.js +8 -15
- package/client/store/sync.js +0 -1
- package/client/store/tab.js +22 -11
- package/client/store/terminal-theme.js +1 -1
- package/client/store/transfer-list.js +0 -8
- package/client/store/ui-theme.js +0 -9
- package/client/store/watch.js +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { useEffect } from 'react'
|
|
2
|
+
import { notification, Button } from 'antd'
|
|
3
|
+
import * as ls from '../../common/safe-local-storage'
|
|
4
|
+
import {
|
|
5
|
+
sshConfigKey,
|
|
6
|
+
sshConfigLoadKey
|
|
7
|
+
} from '../../common/constants'
|
|
8
|
+
|
|
9
|
+
const e = window.translate
|
|
10
|
+
|
|
11
|
+
function handleLoad () {
|
|
12
|
+
window.store.showSshConfigModal = true
|
|
13
|
+
notification.destroy('sshConfigNotify')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function handleIgnore () {
|
|
17
|
+
ls.setItem(sshConfigKey, 'yes')
|
|
18
|
+
notification.destroy('sshConfigNotify')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function showNotification () {
|
|
22
|
+
notification.info({
|
|
23
|
+
message: e('loadSshConfigs'),
|
|
24
|
+
duration: 0,
|
|
25
|
+
placement: 'bottom',
|
|
26
|
+
key: 'sshConfigNotify',
|
|
27
|
+
description: (
|
|
28
|
+
<div>
|
|
29
|
+
<p>{e('sshConfigNotice')}</p>
|
|
30
|
+
<Button type='primary' onClick={handleLoad} className='mg1r mg1b'>
|
|
31
|
+
{e('import')}
|
|
32
|
+
</Button>
|
|
33
|
+
<Button onClick={handleIgnore} className='mg1r mg1b'>
|
|
34
|
+
{e('ignore')}
|
|
35
|
+
</Button>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default function SshConfigLoadNotify (props) {
|
|
42
|
+
const { settingTab, showModal, sshConfigs } = props
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const ignoreSshConfig = ls.getItem(sshConfigKey)
|
|
46
|
+
const sshConfigLoaded = ls.getItem(sshConfigLoadKey)
|
|
47
|
+
const shouldShow =
|
|
48
|
+
sshConfigs.length &&
|
|
49
|
+
ignoreSshConfig !== 'yes' &&
|
|
50
|
+
settingTab === 'bookmarks' &&
|
|
51
|
+
showModal &&
|
|
52
|
+
sshConfigLoaded !== 'yes'
|
|
53
|
+
|
|
54
|
+
if (shouldShow) {
|
|
55
|
+
showNotification()
|
|
56
|
+
}
|
|
57
|
+
}, [settingTab, showModal, sshConfigs.length])
|
|
58
|
+
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
@@ -14,9 +14,7 @@ import { pick } from 'lodash-es'
|
|
|
14
14
|
import Input from '../common/input-auto-focus'
|
|
15
15
|
import createName from '../../common/create-title'
|
|
16
16
|
import { addClass, removeClass } from '../../common/class'
|
|
17
|
-
import
|
|
18
|
-
terminalSshConfigType
|
|
19
|
-
} from '../../common/constants'
|
|
17
|
+
import isDark from '../../common/is-color-dark'
|
|
20
18
|
import { action } from 'manate'
|
|
21
19
|
import { shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
|
|
22
20
|
|
|
@@ -227,11 +225,10 @@ class Tab extends Component {
|
|
|
227
225
|
}
|
|
228
226
|
|
|
229
227
|
renderContext = () => {
|
|
230
|
-
const { tabs,
|
|
228
|
+
const { tabs, tabIndex } = this.props
|
|
231
229
|
const len = tabs.length
|
|
232
230
|
const index = tabIndex
|
|
233
231
|
const noRight = index >= len - 1
|
|
234
|
-
const isSshConfig = tab.type === terminalSshConfigType
|
|
235
232
|
const res = []
|
|
236
233
|
const reloadShortcut = this.getShortcut('app_reloadCurrentTab')
|
|
237
234
|
const closeShortcut = this.getShortcut('app_closeCurrentTab')
|
|
@@ -271,7 +268,6 @@ class Tab extends Component {
|
|
|
271
268
|
subText: cloneToNextShortcut
|
|
272
269
|
})
|
|
273
270
|
res.push({
|
|
274
|
-
disabled: isSshConfig,
|
|
275
271
|
func: 'doRename',
|
|
276
272
|
icon: 'EditOutlined',
|
|
277
273
|
text: e('rename')
|
|
@@ -389,9 +385,12 @@ class Tab extends Component {
|
|
|
389
385
|
if (isEditting) {
|
|
390
386
|
return this.renderEditting(tab, cls)
|
|
391
387
|
}
|
|
392
|
-
const { tabCount, color } = tab
|
|
388
|
+
const { tabCount, color = '#0088cc' } = tab
|
|
393
389
|
const styleTag = color
|
|
394
|
-
? {
|
|
390
|
+
? {
|
|
391
|
+
background: color,
|
|
392
|
+
color: isDark(color) ? '#fff' : '#000'
|
|
393
|
+
}
|
|
395
394
|
: {}
|
|
396
395
|
return (
|
|
397
396
|
<Tooltip
|
|
@@ -418,7 +417,6 @@ class Tab extends Component {
|
|
|
418
417
|
className='tab-title elli pd1x'
|
|
419
418
|
onClick={this.handleClick}
|
|
420
419
|
onDoubleClick={this.handleDup}
|
|
421
|
-
style={styleTag}
|
|
422
420
|
>
|
|
423
421
|
<Loading3QuartersOutlined
|
|
424
422
|
className='pointer tab-reload mg1r'
|
|
@@ -426,7 +424,8 @@ class Tab extends Component {
|
|
|
426
424
|
title={e('reload')}
|
|
427
425
|
/>
|
|
428
426
|
<span className='tab-title'>
|
|
429
|
-
{
|
|
427
|
+
<span className='iblock mg1r tab-count' style={styleTag}>{tabCount}</span>
|
|
428
|
+
<span className='mg1r'>{title}</span>
|
|
430
429
|
</span>
|
|
431
430
|
</div>
|
|
432
431
|
<div className={'tab-status ' + status} />
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
paneMap,
|
|
21
21
|
typeMap,
|
|
22
22
|
isWin,
|
|
23
|
-
terminalSshConfigType,
|
|
24
23
|
transferTypeMap,
|
|
25
24
|
terminalActions,
|
|
26
25
|
commonActions,
|
|
@@ -818,8 +817,7 @@ clear\r`
|
|
|
818
817
|
}
|
|
819
818
|
|
|
820
819
|
isRemote = () => {
|
|
821
|
-
return this.props.tab?.host
|
|
822
|
-
this.props.tab?.type !== terminalSshConfigType
|
|
820
|
+
return this.props.tab?.host
|
|
823
821
|
}
|
|
824
822
|
|
|
825
823
|
onPaste = async () => {
|
|
@@ -1055,15 +1053,9 @@ clear\r`
|
|
|
1055
1053
|
runInitScript = () => {
|
|
1056
1054
|
window.store.triggerResize()
|
|
1057
1055
|
const {
|
|
1058
|
-
type,
|
|
1059
|
-
title,
|
|
1060
1056
|
startDirectory,
|
|
1061
1057
|
runScripts
|
|
1062
1058
|
} = this.props.tab
|
|
1063
|
-
if (type === terminalSshConfigType) {
|
|
1064
|
-
const cmd = `ssh ${title.split(/\s/g)[0]}\r`
|
|
1065
|
-
return this.attachAddon._sendData(cmd)
|
|
1066
|
-
}
|
|
1067
1059
|
const startFolder = startDirectory || window.initFolder
|
|
1068
1060
|
if (startFolder) {
|
|
1069
1061
|
const cmd = `cd "${startFolder}"\r`
|
|
@@ -1141,10 +1133,7 @@ clear\r`
|
|
|
1141
1133
|
id
|
|
1142
1134
|
} = tab
|
|
1143
1135
|
const { savePassword } = this.state
|
|
1144
|
-
const
|
|
1145
|
-
const termType = isSshConfig
|
|
1146
|
-
? typeMap.local
|
|
1147
|
-
: type
|
|
1136
|
+
const termType = type
|
|
1148
1137
|
const extra = this.props.sessionOptions
|
|
1149
1138
|
const opts = clone({
|
|
1150
1139
|
cols,
|
|
@@ -1174,7 +1163,7 @@ clear\r`
|
|
|
1174
1163
|
termType,
|
|
1175
1164
|
readyTimeout: config.sshReadyTimeout,
|
|
1176
1165
|
proxy: getProxy(tab, config),
|
|
1177
|
-
type: tab.host
|
|
1166
|
+
type: tab.host
|
|
1178
1167
|
? typeMap.remote
|
|
1179
1168
|
: typeMap.local
|
|
1180
1169
|
})
|
|
@@ -1326,10 +1315,7 @@ clear\r`
|
|
|
1326
1315
|
isRemote: this.isRemote(),
|
|
1327
1316
|
isActive: this.isActiveTerminal()
|
|
1328
1317
|
}
|
|
1329
|
-
window.store.
|
|
1330
|
-
'terminalInfoProps',
|
|
1331
|
-
infoProps
|
|
1332
|
-
)
|
|
1318
|
+
Object.assign(window.store.terminalInfoProps, infoProps)
|
|
1333
1319
|
}
|
|
1334
1320
|
|
|
1335
1321
|
// getPwd = async () => {
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BookOutlined,
|
|
3
|
+
FolderOutlined,
|
|
4
|
+
UploadOutlined,
|
|
5
|
+
DownloadOutlined,
|
|
6
|
+
CodeOutlined,
|
|
7
|
+
MenuOutlined,
|
|
8
|
+
EditOutlined
|
|
9
|
+
} from '@ant-design/icons'
|
|
10
|
+
import { Button, Space, Dropdown, Upload } from 'antd'
|
|
11
|
+
import copy from 'json-deep-copy'
|
|
12
|
+
import time from '../../common/time'
|
|
13
|
+
import { find, uniq, isEqual } from 'lodash-es'
|
|
14
|
+
import { fixBookmarks } from '../../common/db-fix'
|
|
15
|
+
import download from '../../common/download'
|
|
16
|
+
|
|
17
|
+
const e = window.translate
|
|
18
|
+
|
|
19
|
+
export default function BookmarkToolbar ({
|
|
20
|
+
onNewBookmark,
|
|
21
|
+
onNewBookmarkGroup,
|
|
22
|
+
onImport,
|
|
23
|
+
onExport,
|
|
24
|
+
onSshConfigs,
|
|
25
|
+
bookmarkGroups,
|
|
26
|
+
bookmarks
|
|
27
|
+
}) {
|
|
28
|
+
const beforeUpload = async (file) => {
|
|
29
|
+
const { store } = window
|
|
30
|
+
const txt = await window.fs.readFile(file.path)
|
|
31
|
+
try {
|
|
32
|
+
const content = JSON.parse(txt)
|
|
33
|
+
const {
|
|
34
|
+
bookmarkGroups: bookmarkGroups1,
|
|
35
|
+
bookmarks: bookmarks1
|
|
36
|
+
} = content
|
|
37
|
+
const { props } = this
|
|
38
|
+
const bookmarkGroups = copy(props.bookmarkGroups)
|
|
39
|
+
const bookmarks = copy(props.bookmarks)
|
|
40
|
+
const bmTree = bookmarks.reduce((p, v) => {
|
|
41
|
+
return {
|
|
42
|
+
...p,
|
|
43
|
+
[v.id]: v
|
|
44
|
+
}
|
|
45
|
+
}, {})
|
|
46
|
+
const bmgTree = bookmarkGroups.reduce((p, v) => {
|
|
47
|
+
return {
|
|
48
|
+
...p,
|
|
49
|
+
[v.id]: v
|
|
50
|
+
}
|
|
51
|
+
}, {})
|
|
52
|
+
const add = []
|
|
53
|
+
const dbAdd = []
|
|
54
|
+
const updates = []
|
|
55
|
+
bookmarks1.forEach(bg => {
|
|
56
|
+
if (!bmTree[bg.id]) {
|
|
57
|
+
bookmarks.push(bg)
|
|
58
|
+
add.push(bg)
|
|
59
|
+
dbAdd.push({
|
|
60
|
+
db: 'bookmarks',
|
|
61
|
+
obj: bg
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
bookmarkGroups1.forEach(bg => {
|
|
66
|
+
if (!bmgTree[bg.id]) {
|
|
67
|
+
bookmarkGroups.push(bg)
|
|
68
|
+
dbAdd.push({
|
|
69
|
+
db: 'bookmarkGroups',
|
|
70
|
+
obj: bg
|
|
71
|
+
})
|
|
72
|
+
} else {
|
|
73
|
+
const bg1 = find(
|
|
74
|
+
bookmarkGroups,
|
|
75
|
+
b => b.id === bg.id
|
|
76
|
+
)
|
|
77
|
+
const old = copy(bg1.bookmarkIds)
|
|
78
|
+
bg1.bookmarkIds = uniq(
|
|
79
|
+
[
|
|
80
|
+
...bg1.bookmarkIds,
|
|
81
|
+
...bg.bookmarkIds
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
if (!isEqual(bg1.bookmarkIds, old)) {
|
|
85
|
+
updates.push({
|
|
86
|
+
id: bg1.id,
|
|
87
|
+
db: 'bookmarkGroups',
|
|
88
|
+
update: {
|
|
89
|
+
bookmarkIds: bg1.bookmarkIds
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
store.setBookmarkGroups(bookmarkGroups)
|
|
96
|
+
store.setBookmarks(fixBookmarks(bookmarks))
|
|
97
|
+
store.batchDbAdd(dbAdd)
|
|
98
|
+
store.batchDbUpdate(updates)
|
|
99
|
+
} catch (e) {
|
|
100
|
+
store.onError(e)
|
|
101
|
+
}
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
104
|
+
const handleDownload = () => {
|
|
105
|
+
const { bookmarkGroups, bookmarks } = this.props
|
|
106
|
+
const txt = JSON.stringify({
|
|
107
|
+
bookmarkGroups: copy(bookmarkGroups),
|
|
108
|
+
bookmarks: copy(bookmarks)
|
|
109
|
+
}, null, 2)
|
|
110
|
+
const stamp = time(undefined, 'YYYY-MM-DD-HH-mm-ss')
|
|
111
|
+
download('bookmarks-' + stamp + '.json', txt)
|
|
112
|
+
}
|
|
113
|
+
const handleToggleEdit = () => {
|
|
114
|
+
window.store.bookmarkSelectMode = true
|
|
115
|
+
}
|
|
116
|
+
const titleNew = `${e('new')} ${e('bookmarks')}`
|
|
117
|
+
const titleEdit = `${e('new')} ${e('bookmarkCategory')}`
|
|
118
|
+
const items = [
|
|
119
|
+
{
|
|
120
|
+
label: titleNew,
|
|
121
|
+
onClick: onNewBookmark,
|
|
122
|
+
icon: <BookOutlined />
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
label: titleEdit,
|
|
126
|
+
onClick: onNewBookmarkGroup,
|
|
127
|
+
icon: <FolderOutlined />
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: e('edit'),
|
|
131
|
+
onClick: handleToggleEdit,
|
|
132
|
+
icon: <EditOutlined />
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
label: e('import'),
|
|
136
|
+
onClick: onImport,
|
|
137
|
+
icon: <UploadOutlined />
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
label: e('export'),
|
|
141
|
+
onClick: onExport,
|
|
142
|
+
icon: <DownloadOutlined />
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
label: e('loadSshConfigs'),
|
|
146
|
+
onClick: onSshConfigs,
|
|
147
|
+
icon: <CodeOutlined />
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
const ddProps = {
|
|
152
|
+
menu: {
|
|
153
|
+
items
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
|
|
159
|
+
<div className='pd1b pd1r'>
|
|
160
|
+
<div className='fix'>
|
|
161
|
+
<div className='fleft'>
|
|
162
|
+
<Space.Compact>
|
|
163
|
+
<Button onClick={onNewBookmark}>
|
|
164
|
+
<BookOutlined className='with-plus' />
|
|
165
|
+
</Button>
|
|
166
|
+
<Button onClick={onNewBookmarkGroup}>
|
|
167
|
+
<FolderOutlined className='with-plus' />
|
|
168
|
+
</Button>
|
|
169
|
+
<Button
|
|
170
|
+
icon={<EditOutlined />}
|
|
171
|
+
onClick={handleToggleEdit}
|
|
172
|
+
title={e('edit')}
|
|
173
|
+
/>
|
|
174
|
+
<Button
|
|
175
|
+
icon={<DownloadOutlined />}
|
|
176
|
+
onClick={handleDownload}
|
|
177
|
+
title={e('export')}
|
|
178
|
+
className='download-bookmark-icon'
|
|
179
|
+
/>
|
|
180
|
+
<Upload
|
|
181
|
+
beforeUpload={beforeUpload}
|
|
182
|
+
fileList={[]}
|
|
183
|
+
className='upload-bookmark-icon'
|
|
184
|
+
>
|
|
185
|
+
<Button
|
|
186
|
+
icon={<UploadOutlined />}
|
|
187
|
+
title={e('importFromFile')}
|
|
188
|
+
/>
|
|
189
|
+
</Upload>
|
|
190
|
+
<Button onClick={onSshConfigs}>
|
|
191
|
+
<CodeOutlined />
|
|
192
|
+
</Button>
|
|
193
|
+
</Space.Compact>
|
|
194
|
+
</div>
|
|
195
|
+
<div className='fright'>
|
|
196
|
+
<Dropdown {...ddProps}>
|
|
197
|
+
<MenuOutlined />
|
|
198
|
+
</Dropdown>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
@@ -127,11 +127,13 @@ export default class BookmarkTransport extends PureComponent {
|
|
|
127
127
|
icon={<DownloadOutlined />}
|
|
128
128
|
onClick={this.handleDownload}
|
|
129
129
|
title={e('export')}
|
|
130
|
+
className='download-bookmark-icon'
|
|
130
131
|
key='export'
|
|
131
132
|
/>,
|
|
132
133
|
<Upload
|
|
133
134
|
beforeUpload={this.beforeUpload}
|
|
134
135
|
fileList={[]}
|
|
136
|
+
className='upload-bookmark-icon'
|
|
135
137
|
key='Upload'
|
|
136
138
|
>
|
|
137
139
|
<Button
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { Component } from 'react'
|
|
6
6
|
import {
|
|
7
|
-
BookOutlined,
|
|
8
7
|
CheckOutlined,
|
|
9
8
|
CloseOutlined,
|
|
10
|
-
FolderOutlined,
|
|
11
9
|
LoadingOutlined
|
|
12
10
|
} from '@ant-design/icons'
|
|
13
11
|
import {
|
|
@@ -15,10 +13,6 @@ import {
|
|
|
15
13
|
cut,
|
|
16
14
|
hasBookmarkOrGroupInClipboardText
|
|
17
15
|
} from '../../common/clipboard'
|
|
18
|
-
import {
|
|
19
|
-
Button,
|
|
20
|
-
Space
|
|
21
|
-
} from 'antd'
|
|
22
16
|
import createName from '../../common/create-title'
|
|
23
17
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
24
18
|
import { find, uniq, isEqual, filter, pick } from 'lodash-es'
|
|
@@ -31,8 +25,8 @@ import {
|
|
|
31
25
|
copyBookmarkGroupItemPrefix
|
|
32
26
|
} from '../../common/constants'
|
|
33
27
|
import findParentBySel from '../../common/find-parent'
|
|
34
|
-
import copy from 'json-deep-copy'
|
|
35
|
-
import
|
|
28
|
+
import copy, { deepCopy } from 'json-deep-copy'
|
|
29
|
+
import NewButtonsGroup from './bookmark-toolbar'
|
|
36
30
|
import findBookmarkGroupId from '../../common/find-bookmark-group-id'
|
|
37
31
|
import getInitItem from '../../common/init-setting-item'
|
|
38
32
|
import uid from '../../common/uid'
|
|
@@ -73,7 +67,7 @@ export default class ItemListTree extends Component {
|
|
|
73
67
|
!deepEqual(this.props.expandedKeys, this.state.expandedKeys)
|
|
74
68
|
) {
|
|
75
69
|
this.setState({
|
|
76
|
-
expandedKeys: this.props.expandedKeys
|
|
70
|
+
expandedKeys: deepCopy(this.props.expandedKeys)
|
|
77
71
|
})
|
|
78
72
|
}
|
|
79
73
|
}
|
|
@@ -312,9 +306,7 @@ export default class ItemListTree extends Component {
|
|
|
312
306
|
expandedKeys
|
|
313
307
|
})
|
|
314
308
|
this.closeNewGroupForm()
|
|
315
|
-
window.store.
|
|
316
|
-
'expandedKeys', expandedKeys
|
|
317
|
-
)
|
|
309
|
+
window.store.expandedKeys = deepCopy(expandedKeys)
|
|
318
310
|
}
|
|
319
311
|
|
|
320
312
|
onSelect = (
|
|
@@ -900,28 +892,29 @@ export default class ItemListTree extends Component {
|
|
|
900
892
|
)
|
|
901
893
|
}
|
|
902
894
|
|
|
895
|
+
handleImport = () => {
|
|
896
|
+
document.querySelector('.upload-bookmark-icon input')?.click()
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
handleExport = () => {
|
|
900
|
+
document.querySelector('.download-bookmark-icon')?.click()
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
handleSshConfigs = () => {
|
|
904
|
+
window.store.showSshConfigModal = true
|
|
905
|
+
}
|
|
906
|
+
|
|
903
907
|
renderNewButtons = () => {
|
|
904
908
|
return (
|
|
905
|
-
<
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
onClick={this.handleNewBookmarkGroup}
|
|
915
|
-
title={`${e('new')} ${e('bookmarkCategory')}`}
|
|
916
|
-
>
|
|
917
|
-
<FolderOutlined className='with-plus' />
|
|
918
|
-
</Button>
|
|
919
|
-
<BookmarkTransport
|
|
920
|
-
bookmarkGroups={this.props.bookmarkGroups}
|
|
921
|
-
bookmarks={this.props.bookmarks}
|
|
922
|
-
/>
|
|
923
|
-
</Space.Compact>
|
|
924
|
-
</div>
|
|
909
|
+
<NewButtonsGroup
|
|
910
|
+
onNewBookmark={this.handleNewBookmark}
|
|
911
|
+
onNewBookmarkGroup={this.handleNewBookmarkGroup}
|
|
912
|
+
onImport={this.handleImport}
|
|
913
|
+
onExport={this.handleExport}
|
|
914
|
+
onSshConfigs={this.handleSshConfigs}
|
|
915
|
+
bookmarkGroups={this.props.bookmarkGroups}
|
|
916
|
+
bookmarks={this.props.bookmarks}
|
|
917
|
+
/>
|
|
925
918
|
)
|
|
926
919
|
}
|
|
927
920
|
|
|
@@ -5,23 +5,12 @@
|
|
|
5
5
|
import { find } from 'lodash-es'
|
|
6
6
|
import {
|
|
7
7
|
defaultBookmarkGroupId,
|
|
8
|
-
settingMap
|
|
9
|
-
terminalSshConfigType
|
|
8
|
+
settingMap
|
|
10
9
|
} from '../common/constants'
|
|
11
10
|
|
|
12
11
|
export default Store => {
|
|
13
12
|
Store.prototype.getBookmarkGroupsTotal = function () {
|
|
14
|
-
|
|
15
|
-
return store.sshConfigItems.length && !store.config.hideSshConfig
|
|
16
|
-
? [
|
|
17
|
-
...store.bookmarkGroups,
|
|
18
|
-
{
|
|
19
|
-
title: terminalSshConfigType,
|
|
20
|
-
id: terminalSshConfigType,
|
|
21
|
-
bookmarkIds: store.sshConfigItems.map(d => d.id)
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
: store.bookmarkGroups
|
|
13
|
+
return window.store.bookmarkGroups
|
|
25
14
|
}
|
|
26
15
|
|
|
27
16
|
Store.prototype.setBookmarkGroups = function (items) {
|
package/client/store/bookmark.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* bookmark
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import uid from '../common/uid'
|
|
6
|
+
|
|
5
7
|
export default Store => {
|
|
6
8
|
Store.prototype.handleGetSerials = async function () {
|
|
7
9
|
const { store } = window
|
|
@@ -9,11 +11,51 @@ export default Store => {
|
|
|
9
11
|
const res = await window.pre.runGlobalAsync('listSerialPorts')
|
|
10
12
|
.catch(store.onError)
|
|
11
13
|
if (res) {
|
|
12
|
-
store.
|
|
14
|
+
store.serials = res
|
|
13
15
|
}
|
|
14
16
|
store.loaddingSerials = false
|
|
15
17
|
}
|
|
16
18
|
Store.prototype.setBookmarks = function (items) {
|
|
17
19
|
return window.store.setItems('bookmarks', items)
|
|
18
20
|
}
|
|
21
|
+
|
|
22
|
+
Store.prototype.addSshConfigs = function (items) {
|
|
23
|
+
const { store } = window
|
|
24
|
+
|
|
25
|
+
const bookmarksToAdd = items.map(t => {
|
|
26
|
+
return {
|
|
27
|
+
term: 'xterm-256color',
|
|
28
|
+
id: uid(),
|
|
29
|
+
type: 'local',
|
|
30
|
+
title: 'ssh config: ' + t.title,
|
|
31
|
+
color: '#0088cc',
|
|
32
|
+
runScripts: [
|
|
33
|
+
{
|
|
34
|
+
script: `ssh ${t.title}`,
|
|
35
|
+
delay: 500
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}).filter(d => {
|
|
40
|
+
return !store.bookmarks.find(t => t.title === d.title)
|
|
41
|
+
})
|
|
42
|
+
const ids = bookmarksToAdd.map(d => d.id)
|
|
43
|
+
let sshConfigGroup = store.bookmarkGroups.find(d => d.id === 'sshConfig')
|
|
44
|
+
if (!sshConfigGroup) {
|
|
45
|
+
sshConfigGroup = {
|
|
46
|
+
id: 'sshConfig',
|
|
47
|
+
title: 'ssh configs',
|
|
48
|
+
bookmarkIds: ids
|
|
49
|
+
}
|
|
50
|
+
store.addBookmarkGroup(sshConfigGroup)
|
|
51
|
+
} else {
|
|
52
|
+
store.editItem('sshConfig', {
|
|
53
|
+
bookmarkIds: [
|
|
54
|
+
...ids,
|
|
55
|
+
...(sshConfigGroup.bookmarkIds || [])
|
|
56
|
+
]
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
return store.addItems(bookmarksToAdd, 'bookmarks')
|
|
60
|
+
}
|
|
19
61
|
}
|
package/client/store/common.js
CHANGED
|
@@ -136,17 +136,11 @@ export default Store => {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
Store.prototype.setSettingItem = function (v) {
|
|
139
|
-
window.store.
|
|
139
|
+
window.store.settingItem = v
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
Store.prototype.setTermSearchOption = function (update) {
|
|
143
|
-
|
|
144
|
-
store
|
|
145
|
-
} = window
|
|
146
|
-
store.setState('termSearchOptions', {
|
|
147
|
-
...JSON.parse(window.store._termSearchOptions),
|
|
148
|
-
...update
|
|
149
|
-
})
|
|
143
|
+
Object.assign(window.store._termSearchOptions, update)
|
|
150
144
|
}
|
|
151
145
|
|
|
152
146
|
Store.prototype.setLeftSidePanelWidth = function (v) {
|