@electerm/electerm-react 1.80.18 → 1.90.8
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 +3 -1
- package/client/common/default-setting.js +2 -1
- package/client/common/fetch-from-server.js +1 -1
- package/client/common/sftp.js +13 -9
- package/client/common/transfer.js +4 -4
- package/client/common/ws.js +1 -2
- package/client/components/batch-op/batch-op.jsx +3 -4
- package/client/components/bookmark-form/ftp-form-ui.jsx +168 -0
- package/client/components/bookmark-form/ftp-form.jsx +16 -0
- package/client/components/bookmark-form/index.jsx +8 -3
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +2 -0
- package/client/components/bookmark-form/x11.jsx +6 -15
- package/client/components/file-transfer/transfer.jsx +26 -24
- package/client/components/footer/tab-select.jsx +1 -1
- package/client/components/rdp/rdp-session.jsx +2 -3
- package/client/components/session/session.jsx +21 -22
- package/client/components/setting-panel/setting-terminal.jsx +5 -0
- package/client/components/sftp/address-bar.jsx +6 -1
- package/client/components/sftp/file-info-modal.jsx +0 -2
- package/client/components/sftp/file-item.jsx +60 -24
- package/client/components/sftp/owner-list.js +4 -4
- package/client/components/sftp/sftp-entry.jsx +62 -21
- package/client/components/sftp/transfer-common.js +1 -2
- package/client/components/sidebar/transfer-list-control.jsx +5 -5
- package/client/components/terminal/terminal-apis.js +4 -8
- package/client/components/terminal/terminal.jsx +6 -10
- package/client/components/terminal-info/base.jsx +4 -8
- package/client/components/terminal-info/run-cmd.jsx +2 -3
- package/client/components/terminal-info/terminal-info.jsx +2 -3
- package/client/components/theme/theme-list-item.jsx +22 -42
- package/client/components/theme/theme-list.jsx +23 -1
- package/client/components/tree-list/bookmark-toolbar.jsx +58 -46
- package/client/components/vnc/vnc-session.jsx +2 -3
- package/client/entry/worker.js +1 -2
- package/client/store/item.js +1 -1
- package/client/store/tab.js +7 -5
- package/client/store/ui-theme.js +6 -6
- package/client/store/watch.js +3 -2
- package/package.json +1 -1
|
@@ -50,12 +50,10 @@ export default class TerminalInfoBase extends Component {
|
|
|
50
50
|
handleToggleTimestamp = () => {
|
|
51
51
|
const { saveTerminalLogToFile, addTimeStampToTermLog } = this.state
|
|
52
52
|
const {
|
|
53
|
-
pid
|
|
54
|
-
sessionId
|
|
53
|
+
pid
|
|
55
54
|
} = this.props
|
|
56
55
|
toggleTerminalLogTimestamp(
|
|
57
|
-
pid
|
|
58
|
-
sessionId
|
|
56
|
+
pid
|
|
59
57
|
)
|
|
60
58
|
const nv = !addTimeStampToTermLog
|
|
61
59
|
this.setState({
|
|
@@ -80,12 +78,10 @@ export default class TerminalInfoBase extends Component {
|
|
|
80
78
|
handleToggle = () => {
|
|
81
79
|
const { saveTerminalLogToFile, addTimeStampToTermLog } = this.state
|
|
82
80
|
const {
|
|
83
|
-
pid
|
|
84
|
-
sessionId
|
|
81
|
+
pid
|
|
85
82
|
} = this.props
|
|
86
83
|
toggleTerminalLog(
|
|
87
|
-
pid
|
|
88
|
-
sessionId
|
|
84
|
+
pid
|
|
89
85
|
)
|
|
90
86
|
const nv = !saveTerminalLogToFile
|
|
91
87
|
this.setState({
|
|
@@ -148,12 +148,11 @@ function formatNetwork (traffic, ips) {
|
|
|
148
148
|
|
|
149
149
|
export async function runCmds (props, cmds) {
|
|
150
150
|
const {
|
|
151
|
-
pid
|
|
152
|
-
sessionId
|
|
151
|
+
pid
|
|
153
152
|
} = props
|
|
154
153
|
const ress = []
|
|
155
154
|
for (const cmd of cmds) {
|
|
156
|
-
const res = await runCmd(pid,
|
|
155
|
+
const res = await runCmd(pid, cmd)
|
|
157
156
|
ress.push(res || '')
|
|
158
157
|
}
|
|
159
158
|
return ress
|
|
@@ -30,11 +30,10 @@ export default class TerminalInfoContent extends PureComponent {
|
|
|
30
30
|
|
|
31
31
|
killProcess = async (id) => {
|
|
32
32
|
const {
|
|
33
|
-
pid
|
|
34
|
-
sessionId
|
|
33
|
+
pid
|
|
35
34
|
} = this.props
|
|
36
35
|
const cmd = `kill ${id}`
|
|
37
|
-
runCmd(pid,
|
|
36
|
+
runCmd(pid, cmd)
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
render () {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SunOutlined,
|
|
9
9
|
MoonOutlined
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
|
-
import {
|
|
11
|
+
import { Tag } from 'antd'
|
|
12
12
|
import classnames from 'classnames'
|
|
13
13
|
import { defaultTheme } from '../../common/constants'
|
|
14
14
|
import highlight from '../common/highlight'
|
|
@@ -26,41 +26,24 @@ export default function ThemeListItem (props) {
|
|
|
26
26
|
const { store } = window
|
|
27
27
|
|
|
28
28
|
function handleClickApply () {
|
|
29
|
+
delete window.originalTheme
|
|
29
30
|
store.setTheme(item.id)
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
className='theme-preview pd2'
|
|
47
|
-
style={{ background: main, color: text }}
|
|
48
|
-
>
|
|
49
|
-
{
|
|
50
|
-
arr.map(k => {
|
|
51
|
-
return (
|
|
52
|
-
<Tag
|
|
53
|
-
color={item.uiThemeConfig[k]}
|
|
54
|
-
key={k}
|
|
55
|
-
className='mg1l mg1b'
|
|
56
|
-
>
|
|
57
|
-
{e(k)}
|
|
58
|
-
</Tag>
|
|
59
|
-
)
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
</div>
|
|
63
|
-
)
|
|
33
|
+
function handleMouseEnter () {
|
|
34
|
+
// Store current theme ID before changing
|
|
35
|
+
const currentTheme = window.store.config.theme
|
|
36
|
+
window.originalTheme = currentTheme
|
|
37
|
+
// Apply the hovered theme
|
|
38
|
+
store.setTheme(item.id)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function handleMouseLeave () {
|
|
42
|
+
if (!window.originalTheme) return
|
|
43
|
+
// Restore the original theme
|
|
44
|
+
store.setTheme(window.originalTheme)
|
|
45
|
+
// Clean up
|
|
46
|
+
delete window.originalTheme
|
|
64
47
|
}
|
|
65
48
|
|
|
66
49
|
function renderApplyBtn () {
|
|
@@ -68,15 +51,12 @@ export default function ThemeListItem (props) {
|
|
|
68
51
|
return null
|
|
69
52
|
}
|
|
70
53
|
return (
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
onClick={handleClickApply}
|
|
78
|
-
/>
|
|
79
|
-
</Tooltip>
|
|
54
|
+
<CheckCircleOutlined
|
|
55
|
+
className='pointer list-item-apply'
|
|
56
|
+
onClick={handleClickApply}
|
|
57
|
+
onMouseEnter={handleMouseEnter}
|
|
58
|
+
onMouseLeave={handleMouseLeave}
|
|
59
|
+
/>
|
|
80
60
|
)
|
|
81
61
|
}
|
|
82
62
|
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import List from '../setting-panel/list'
|
|
6
|
-
import { LoadingOutlined } from '@ant-design/icons'
|
|
6
|
+
import { LoadingOutlined, CheckCircleOutlined } from '@ant-design/icons'
|
|
7
7
|
import { pick } from 'lodash-es'
|
|
8
8
|
import { Pagination } from 'antd'
|
|
9
9
|
import ThemeListItem from './theme-list-item'
|
|
10
|
+
import { defaultTheme } from '../../common/constants'
|
|
10
11
|
import './terminal-theme-list.styl'
|
|
11
12
|
|
|
13
|
+
const e = window.translate
|
|
14
|
+
|
|
12
15
|
export default class ThemeList extends List {
|
|
13
16
|
handlePager = page => {
|
|
14
17
|
this.setState({ page })
|
|
@@ -37,6 +40,24 @@ export default class ThemeList extends List {
|
|
|
37
40
|
)
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
renderCurrentTheme () {
|
|
44
|
+
const { theme, list } = this.props
|
|
45
|
+
const item = list.find(d => d.id === theme)
|
|
46
|
+
if (!item) {
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
const { name, id } = item
|
|
50
|
+
const title = id === defaultTheme.id
|
|
51
|
+
? e(id)
|
|
52
|
+
: name
|
|
53
|
+
return (
|
|
54
|
+
<div className='pd2'>
|
|
55
|
+
<CheckCircleOutlined className='mg1r' />
|
|
56
|
+
{title}
|
|
57
|
+
</div>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
40
61
|
filter = list => {
|
|
41
62
|
const { keyword, ready } = this.state
|
|
42
63
|
return keyword
|
|
@@ -69,6 +90,7 @@ export default class ThemeList extends List {
|
|
|
69
90
|
{this.renderTransport ? this.renderTransport() : null}
|
|
70
91
|
{this.renderLabels ? this.renderLabels() : null}
|
|
71
92
|
{this.renderSearch()}
|
|
93
|
+
{this.renderCurrentTheme()}
|
|
72
94
|
<div className='item-list-wrap' style={listStyle}>
|
|
73
95
|
{
|
|
74
96
|
list.map(this.renderItem)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BookOutlined,
|
|
3
3
|
FolderOutlined,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ImportOutlined,
|
|
5
|
+
ExportOutlined,
|
|
6
6
|
CodeOutlined,
|
|
7
7
|
MenuOutlined,
|
|
8
8
|
EditOutlined
|
|
@@ -13,6 +13,7 @@ import time from '../../common/time'
|
|
|
13
13
|
import { uniq } from 'lodash-es'
|
|
14
14
|
import { fixBookmarks } from '../../common/db-fix'
|
|
15
15
|
import download from '../../common/download'
|
|
16
|
+
import delay from '../../common/wait'
|
|
16
17
|
import { action } from 'manate'
|
|
17
18
|
|
|
18
19
|
const e = window.translate
|
|
@@ -27,54 +28,65 @@ export default function BookmarkToolbar (props) {
|
|
|
27
28
|
bookmarkGroups,
|
|
28
29
|
bookmarks
|
|
29
30
|
} = props
|
|
30
|
-
const
|
|
31
|
+
const upload = action(async (file) => {
|
|
31
32
|
const { store } = window
|
|
32
33
|
const txt = await window.fs.readFile(file.path)
|
|
33
|
-
try {
|
|
34
|
-
const content = JSON.parse(txt)
|
|
35
|
-
const {
|
|
36
|
-
bookmarkGroups: bookmarkGroups1,
|
|
37
|
-
bookmarks: bookmarks1
|
|
38
|
-
} = content
|
|
39
|
-
const bookmarkGroups0 = copy(bookmarkGroups)
|
|
40
|
-
const bookmarks0 = copy(bookmarks)
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
const content = JSON.parse(txt)
|
|
36
|
+
const {
|
|
37
|
+
bookmarkGroups: bookmarkGroups1,
|
|
38
|
+
bookmarks: bookmarks1
|
|
39
|
+
} = content
|
|
40
|
+
const bookmarkGroups0 = copy(bookmarkGroups)
|
|
41
|
+
const bookmarks0 = copy(bookmarks)
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
// Using Map instead of reduce
|
|
44
|
+
const bmTree = new Map(
|
|
45
|
+
bookmarks0.map(bookmark => [bookmark.id, bookmark])
|
|
46
|
+
)
|
|
47
|
+
const bmgTree = new Map(
|
|
48
|
+
bookmarkGroups0.map(group => [group.id, group])
|
|
49
|
+
)
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
if (!bmTree.has(bg.id)) {
|
|
54
|
-
store.bookmarks.push(bg)
|
|
55
|
-
}
|
|
56
|
-
})
|
|
51
|
+
const fixed = fixBookmarks(bookmarks1)
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
fixed.forEach(bg => {
|
|
54
|
+
if (!bmTree.has(bg.id)) {
|
|
55
|
+
store.bookmarks.push(bg)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
bookmarkGroups1.forEach(bg => {
|
|
60
|
+
if (!bmgTree.has(bg.id)) {
|
|
61
|
+
store.bookmarkGroups.push(bg)
|
|
62
|
+
} else {
|
|
63
|
+
const bg1 = store.bookmarkGroups.find(
|
|
64
|
+
b => b.id === bg.id
|
|
65
|
+
)
|
|
66
|
+
bg1.bookmarkIds = uniq(
|
|
67
|
+
[
|
|
68
|
+
...bg1.bookmarkIds,
|
|
69
|
+
...bg.bookmarkIds
|
|
70
|
+
]
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
76
74
|
return false
|
|
77
75
|
})
|
|
76
|
+
const beforeUpload = async (file) => {
|
|
77
|
+
const names = [
|
|
78
|
+
'bookmarks',
|
|
79
|
+
'bookmarkGroups'
|
|
80
|
+
]
|
|
81
|
+
for (const name of names) {
|
|
82
|
+
window[`watch${name}`].stop()
|
|
83
|
+
}
|
|
84
|
+
upload(file)
|
|
85
|
+
await delay(1000)
|
|
86
|
+
for (const name of names) {
|
|
87
|
+
window[`watch${name}`].start()
|
|
88
|
+
}
|
|
89
|
+
}
|
|
78
90
|
|
|
79
91
|
const handleDownload = () => {
|
|
80
92
|
const txt = JSON.stringify({
|
|
@@ -108,12 +120,12 @@ export default function BookmarkToolbar (props) {
|
|
|
108
120
|
{
|
|
109
121
|
label: e('import'),
|
|
110
122
|
onClick: onImport,
|
|
111
|
-
icon: <
|
|
123
|
+
icon: <ImportOutlined />
|
|
112
124
|
},
|
|
113
125
|
{
|
|
114
126
|
label: e('export'),
|
|
115
127
|
onClick: onExport,
|
|
116
|
-
icon: <
|
|
128
|
+
icon: <ExportOutlined />
|
|
117
129
|
},
|
|
118
130
|
{
|
|
119
131
|
label: e('loadSshConfigs'),
|
|
@@ -146,7 +158,7 @@ export default function BookmarkToolbar (props) {
|
|
|
146
158
|
title={e('edit')}
|
|
147
159
|
/>
|
|
148
160
|
<Button
|
|
149
|
-
icon={<
|
|
161
|
+
icon={<ExportOutlined />}
|
|
150
162
|
onClick={handleDownload}
|
|
151
163
|
title={e('export')}
|
|
152
164
|
className='download-bookmark-icon'
|
|
@@ -157,7 +169,7 @@ export default function BookmarkToolbar (props) {
|
|
|
157
169
|
className='upload-bookmark-icon'
|
|
158
170
|
>
|
|
159
171
|
<Button
|
|
160
|
-
icon={<
|
|
172
|
+
icon={<ImportOutlined />}
|
|
161
173
|
title={e('importFromFile')}
|
|
162
174
|
/>
|
|
163
175
|
</Upload>
|
|
@@ -73,7 +73,7 @@ export default class VncSession extends RdpSession {
|
|
|
73
73
|
tokenElecterm,
|
|
74
74
|
server = ''
|
|
75
75
|
} = config
|
|
76
|
-
const {
|
|
76
|
+
const { id } = this.props
|
|
77
77
|
const tab = window.store.applyProfile(deepCopy(this.props.tab || {}))
|
|
78
78
|
const {
|
|
79
79
|
type,
|
|
@@ -85,7 +85,6 @@ export default class VncSession extends RdpSession {
|
|
|
85
85
|
} = tab
|
|
86
86
|
const opts = clone({
|
|
87
87
|
term: terminalType || config.terminalType,
|
|
88
|
-
sessionId,
|
|
89
88
|
tabId: id,
|
|
90
89
|
srcTabId: tab.id,
|
|
91
90
|
termType: type,
|
|
@@ -111,7 +110,7 @@ export default class VncSession extends RdpSession {
|
|
|
111
110
|
: `${host}:${port}`
|
|
112
111
|
const pre = server.startsWith('https') ? 'wss' : 'ws'
|
|
113
112
|
const { width, height } = this.state
|
|
114
|
-
const wsUrl = `${pre}://${hs}/vnc/${pid}?
|
|
113
|
+
const wsUrl = `${pre}://${hs}/vnc/${pid}?token=${tokenElecterm}&width=${width}&height=${height}`
|
|
115
114
|
const vncOpts = {
|
|
116
115
|
scaleViewport,
|
|
117
116
|
viewOnly,
|
package/client/entry/worker.js
CHANGED
|
@@ -7,13 +7,12 @@ self.insts = {}
|
|
|
7
7
|
function createWs (
|
|
8
8
|
type,
|
|
9
9
|
id,
|
|
10
|
-
sessionId = '',
|
|
11
10
|
sftpId = '',
|
|
12
11
|
config
|
|
13
12
|
) {
|
|
14
13
|
// init gloabl ws
|
|
15
14
|
const { host, port, tokenElecterm } = config
|
|
16
|
-
const wsUrl = `ws://${host}:${port}/${type}/${id}
|
|
15
|
+
const wsUrl = `ws://${host}:${port}/${type}/${id}?&sftpId=${sftpId}&token=${tokenElecterm}`
|
|
17
16
|
const ws = new WebSocket(wsUrl)
|
|
18
17
|
ws.s = msg => {
|
|
19
18
|
try {
|
package/client/store/item.js
CHANGED
package/client/store/tab.js
CHANGED
|
@@ -511,7 +511,9 @@ export default Store => {
|
|
|
511
511
|
|
|
512
512
|
Store.prototype.updateBatchInputSelectedTabIds = function () {
|
|
513
513
|
const { store } = window
|
|
514
|
-
store._batchInputSelectedTabIds
|
|
514
|
+
if (!store._batchInputSelectedTabIds.has(store.activeTabId)) {
|
|
515
|
+
store._batchInputSelectedTabIds = new Set([store.activeTabId])
|
|
516
|
+
}
|
|
515
517
|
}
|
|
516
518
|
|
|
517
519
|
Store.prototype.onSelectBatchInputSelectedTabId = action(function (id) {
|
|
@@ -565,15 +567,15 @@ export default Store => {
|
|
|
565
567
|
}
|
|
566
568
|
}
|
|
567
569
|
|
|
568
|
-
Store.prototype.remoteList = function (
|
|
569
|
-
const sftp = refs.get('sftp-' +
|
|
570
|
+
Store.prototype.remoteList = function (tabId) {
|
|
571
|
+
const sftp = refs.get('sftp-' + tabId)
|
|
570
572
|
if (sftp) {
|
|
571
573
|
sftp.remoteListDebounce()
|
|
572
574
|
}
|
|
573
575
|
}
|
|
574
576
|
|
|
575
|
-
Store.prototype.localList = function (
|
|
576
|
-
const sftp = refs.get('sftp-' +
|
|
577
|
+
Store.prototype.localList = function (tabId) {
|
|
578
|
+
const sftp = refs.get('sftp-' + tabId)
|
|
577
579
|
if (sftp) {
|
|
578
580
|
sftp.localListDebounce()
|
|
579
581
|
}
|
package/client/store/ui-theme.js
CHANGED
|
@@ -37,12 +37,12 @@ export default Store => {
|
|
|
37
37
|
return window.pre.runGlobalAsync('toCss', stylus)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
Store.prototype.sortTheme = function (a, b) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
40
|
+
// Store.prototype.sortTheme = function (a, b) {
|
|
41
|
+
// const theme = window.originalTheme || window.store.config.theme
|
|
42
|
+
// const ax = a.id === theme ? -1 : 1
|
|
43
|
+
// const bx = b.id === theme ? -1 : 1
|
|
44
|
+
// return ax > bx ? 1 : -1
|
|
45
|
+
// }
|
|
46
46
|
|
|
47
47
|
Store.prototype.getUiThemeConfig = function () {
|
|
48
48
|
const { store } = window
|
package/client/store/watch.js
CHANGED
|
@@ -39,7 +39,7 @@ export default store => {
|
|
|
39
39
|
// })
|
|
40
40
|
|
|
41
41
|
for (const name of dbNamesForWatch) {
|
|
42
|
-
autoRun(async () => {
|
|
42
|
+
window[`watch${name}`] = autoRun(async () => {
|
|
43
43
|
const old = refsStatic.get('oldState-' + name)
|
|
44
44
|
const n = store.getItems(name)
|
|
45
45
|
const { updated, added, removed } = dataCompare(
|
|
@@ -70,7 +70,8 @@ export default store => {
|
|
|
70
70
|
await store.uploadSettingAll()
|
|
71
71
|
}
|
|
72
72
|
return store[name]
|
|
73
|
-
})
|
|
73
|
+
})
|
|
74
|
+
window[`watch${name}`].start()
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
autoRun(async () => {
|