@electerm/electerm-react 5.1.25 → 5.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/build-map.js +12 -0
- package/client/common/db.js +7 -5
- package/client/common/import-task.js +174 -0
- package/client/components/bookmark-form/ai-bookmark-form.jsx +18 -15
- package/client/components/bookmark-form/common/bookmark-select.jsx +6 -5
- package/client/components/bookmark-form/common/fields.jsx +1 -1
- package/client/components/bookmark-form/common/profile-item.jsx +12 -2
- package/client/components/bookmark-form/config/rdp.js +1 -1
- package/client/components/bookmark-form/tree-select.jsx +5 -16
- package/client/components/common/import-progress.jsx +90 -0
- package/client/components/main/main.jsx +2 -0
- package/client/components/profile/profile-form-rdp.jsx +1 -1
- package/client/components/quick-commands/quick-command-transport-mod.jsx +24 -18
- package/client/components/rdp/rdp-cred-form.jsx +55 -0
- package/client/components/rdp/rdp-session.jsx +97 -6
- package/client/components/setting-panel/keywords-transport.jsx +1 -4
- package/client/components/setting-panel/setting-modal.jsx +8 -2
- package/client/components/setting-panel/start-session-select.jsx +5 -16
- package/client/components/spice/spice-session.jsx +40 -0
- package/client/components/terminal/terminal-color-query.mjs +32 -27
- package/client/components/terminal/terminal.jsx +13 -9
- package/client/components/tree-list/bookmark-transport.jsx +2 -1
- package/client/components/tree-list/bookmark-upload.js +56 -41
- package/client/components/tree-list/tree-list-row.jsx +11 -4
- package/client/components/tree-list/tree-list-rows.js +6 -3
- package/client/components/tree-list/tree-list.jsx +4 -2
- package/client/store/common.js +19 -1
- package/client/store/load-data.js +6 -1
- package/client/store/store.js +3 -12
- package/client/store/sync.js +31 -2
- package/client/store/watch.js +10 -1
- package/package.json +1 -1
package/client/store/common.js
CHANGED
|
@@ -193,7 +193,13 @@ export default Store => {
|
|
|
193
193
|
type,
|
|
194
194
|
authType
|
|
195
195
|
} = tab
|
|
196
|
-
|
|
196
|
+
// SSH picks auth type explicitly (password/privateKey/profiles radio),
|
|
197
|
+
// other types only have the profile dropdown, so a selected profile
|
|
198
|
+
// always means profile auth for them
|
|
199
|
+
const useProfile = type === connectionMap.ssh
|
|
200
|
+
? authType === 'profiles'
|
|
201
|
+
: true
|
|
202
|
+
if (!profile || !useProfile) {
|
|
197
203
|
return tab
|
|
198
204
|
}
|
|
199
205
|
let p = window.store.profiles.find(x => x.id === profile)
|
|
@@ -224,10 +230,17 @@ export default Store => {
|
|
|
224
230
|
...tab,
|
|
225
231
|
...filtered
|
|
226
232
|
}
|
|
233
|
+
} else if (type === connectionMap.ftp) {
|
|
234
|
+
const filtered = pickBy(p.ftp, (value) => value !== undefined && value !== '')
|
|
235
|
+
return {
|
|
236
|
+
...tab,
|
|
237
|
+
...filtered
|
|
238
|
+
}
|
|
227
239
|
}
|
|
228
240
|
delete p.rdp
|
|
229
241
|
delete p.vnc
|
|
230
242
|
delete p.telnet
|
|
243
|
+
delete p.ftp
|
|
231
244
|
const filtered = pickBy(p, (value) => value !== undefined && value !== '')
|
|
232
245
|
return {
|
|
233
246
|
...tab,
|
|
@@ -455,6 +468,11 @@ export default Store => {
|
|
|
455
468
|
let i = len - 1
|
|
456
469
|
for (;i >= 0; i--) {
|
|
457
470
|
const f = profiles[i]
|
|
471
|
+
// migrate old rdp profile key userName -> username
|
|
472
|
+
if (f.rdp?.userName !== undefined) {
|
|
473
|
+
f.rdp.username = f.rdp.userName
|
|
474
|
+
delete f.rdp.userName
|
|
475
|
+
}
|
|
458
476
|
if (f.name) {
|
|
459
477
|
continue
|
|
460
478
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { dbNames, getData, fetchInitData } from '../common/db'
|
|
6
|
+
import deepCopy from 'json-deep-copy'
|
|
6
7
|
import parseInt10 from '../common/parse-int10'
|
|
7
8
|
import { infoTabs, statusMap, defaultEnvLang } from '../common/constants'
|
|
8
9
|
import generate from '../common/id-with-stamp'
|
|
@@ -237,7 +238,11 @@ export default (Store) => {
|
|
|
237
238
|
.then(arr => {
|
|
238
239
|
for (const { name, data } of arr) {
|
|
239
240
|
const dt = JSON.parse(data || '[]')
|
|
240
|
-
|
|
241
|
+
// seed the watcher snapshot with a *copy* - manate wraps the exact
|
|
242
|
+
// array assigned into the store, so seeding with `dt` itself would
|
|
243
|
+
// alias snapshot and store to one backing array; the watcher's
|
|
244
|
+
// no-change early-return would then skip DB writes forever
|
|
245
|
+
refsStatic.add('oldState-' + name, deepCopy(dt))
|
|
241
246
|
if (name === 'bookmarks') {
|
|
242
247
|
ext.bookmarksMap = new Map(
|
|
243
248
|
dt.map(d => [d.id, d])
|
package/client/store/store.js
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
} from '../common/constants'
|
|
43
43
|
import getInitItem from '../common/init-setting-item'
|
|
44
44
|
import createTitle from '../common/create-title'
|
|
45
|
+
import buildMap from '../common/build-map'
|
|
45
46
|
import {
|
|
46
47
|
theme
|
|
47
48
|
} from 'antd'
|
|
@@ -278,12 +279,7 @@ class Store {
|
|
|
278
279
|
const {
|
|
279
280
|
bookmarks
|
|
280
281
|
} = window.store
|
|
281
|
-
return bookmarks
|
|
282
|
-
return {
|
|
283
|
-
...p,
|
|
284
|
-
[v.id]: v
|
|
285
|
-
}
|
|
286
|
-
}, {})
|
|
282
|
+
return buildMap(bookmarks)
|
|
287
283
|
}
|
|
288
284
|
|
|
289
285
|
hasSshConfig () {
|
|
@@ -296,12 +292,7 @@ class Store {
|
|
|
296
292
|
const {
|
|
297
293
|
bookmarkGroups
|
|
298
294
|
} = window.store
|
|
299
|
-
return bookmarkGroups
|
|
300
|
-
return {
|
|
301
|
-
...p,
|
|
302
|
-
[v.id]: v
|
|
303
|
-
}
|
|
304
|
-
}, {})
|
|
295
|
+
return buildMap(bookmarkGroups)
|
|
305
296
|
}
|
|
306
297
|
|
|
307
298
|
get hasOldConnectionHoppingBookmark () {
|
package/client/store/sync.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { get, pick, debounce } from 'lodash-es'
|
|
6
6
|
import copy from 'json-deep-copy'
|
|
7
|
+
import { action } from 'manate'
|
|
7
8
|
import {
|
|
8
9
|
settingMap, packInfo, syncTypes, syncDataMaps
|
|
9
10
|
} from '../common/constants'
|
|
@@ -13,6 +14,9 @@ import download from '../common/download'
|
|
|
13
14
|
import { fixBookmarks } from '../common/db-fix'
|
|
14
15
|
import dayjs from 'dayjs'
|
|
15
16
|
import parseJsonSafe from '../common/parse-json-safe'
|
|
17
|
+
import { runImportTask } from '../common/import-task'
|
|
18
|
+
|
|
19
|
+
const e = window.translate
|
|
16
20
|
|
|
17
21
|
const {
|
|
18
22
|
version: packVer
|
|
@@ -694,15 +698,40 @@ export default (Store) => {
|
|
|
694
698
|
const { store } = window
|
|
695
699
|
const objs = JSON.parse(txt)
|
|
696
700
|
const { names } = store.getDataSyncNames(true)
|
|
701
|
+
const fixed = {}
|
|
697
702
|
for (const n of names) {
|
|
698
|
-
let arr = objs[n]
|
|
703
|
+
let arr = objs[n] || []
|
|
699
704
|
if (n === settingMap.terminalThemes) {
|
|
700
705
|
arr = store.fixThemes(arr)
|
|
701
706
|
} else if (n === settingMap.bookmarks) {
|
|
702
707
|
arr = fixBookmarks(arr)
|
|
703
708
|
}
|
|
704
|
-
|
|
709
|
+
fixed[n] = arr
|
|
705
710
|
}
|
|
711
|
+
// clear all targets first - importAll replaces data sets, not appends.
|
|
712
|
+
// watchers are stopped inside runImportTask, so this is silent until restart
|
|
713
|
+
action(() => {
|
|
714
|
+
for (const n of names) {
|
|
715
|
+
store.setItems(n, [])
|
|
716
|
+
}
|
|
717
|
+
})()
|
|
718
|
+
await runImportTask({
|
|
719
|
+
title: e('import'),
|
|
720
|
+
batch: 200,
|
|
721
|
+
stopWatchers: names,
|
|
722
|
+
// one chunked step per data set (bookmarks, groups, themes, ...),
|
|
723
|
+
// so the progress bar advances per batch instead of per data set
|
|
724
|
+
steps: names.map((n) => {
|
|
725
|
+
const arr = fixed[n]
|
|
726
|
+
return {
|
|
727
|
+
label: n,
|
|
728
|
+
items: arr,
|
|
729
|
+
process: (chunk) => {
|
|
730
|
+
store[n].push(...chunk)
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
})
|
|
734
|
+
})
|
|
706
735
|
store.updateConfig(stripServerManagedKeys(objs.config))
|
|
707
736
|
if (objs.config?.theme) {
|
|
708
737
|
store.setTheme(objs.config.theme)
|
package/client/store/watch.js
CHANGED
|
@@ -31,6 +31,16 @@ export default store => {
|
|
|
31
31
|
old,
|
|
32
32
|
n
|
|
33
33
|
)
|
|
34
|
+
const newOrder = (n || []).map(d => d.id)
|
|
35
|
+
// with large collections (thousands of bookmarks) this autoRun fires
|
|
36
|
+
// often; when neither content nor order changed, skip the deep-copy
|
|
37
|
+
// snapshot and the DB writes entirely
|
|
38
|
+
const orderChanged = !old ||
|
|
39
|
+
old.length !== (n || []).length ||
|
|
40
|
+
old.some((d, i) => d.id !== newOrder[i])
|
|
41
|
+
if (!updated.length && !added.length && !removed.length && !orderChanged) {
|
|
42
|
+
return store[name]
|
|
43
|
+
}
|
|
34
44
|
// Update snapshot immediately before async DB writes to prevent
|
|
35
45
|
// race conditions: a second autoRun firing before the first
|
|
36
46
|
// completes would see stale oldState and re-insert the same items,
|
|
@@ -41,7 +51,6 @@ export default store => {
|
|
|
41
51
|
...updated.map(item => update(item.id, item, name, false)),
|
|
42
52
|
added.length ? insert(name, added) : Promise.resolve()
|
|
43
53
|
])
|
|
44
|
-
const newOrder = (n || []).map(d => d.id)
|
|
45
54
|
await update(
|
|
46
55
|
`${name}:order`,
|
|
47
56
|
newOrder
|