@electerm/electerm-react 1.80.6 → 1.90.6
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 +3 -2
- 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/conflict-resolve.jsx +11 -1
- package/client/components/file-transfer/transfer.jsx +26 -24
- package/client/components/footer/tab-select.jsx +1 -1
- package/client/components/main/upgrade.jsx +3 -0
- 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-icon.jsx +1 -1
- package/client/components/sftp/file-info-modal.jsx +0 -2
- package/client/components/sftp/file-item.jsx +62 -26
- package/client/components/sftp/file-table-header.jsx +1 -1
- 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/bookmark.jsx +27 -7
- package/client/components/sidebar/info-modal.jsx +1 -1
- package/client/components/sidebar/sidebar.styl +2 -0
- package/client/components/sidebar/transfer-list-control.jsx +5 -5
- package/client/components/terminal/term-search.jsx +5 -2
- package/client/components/terminal/terminal-apis.js +4 -8
- package/client/components/terminal/terminal.jsx +12 -14
- 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/tree-list/bookmark-toolbar.jsx +58 -46
- package/client/components/vnc/vnc-session.jsx +2 -3
- package/client/entry/electerm.jsx +1 -1
- package/client/entry/worker.js +1 -2
- package/client/store/tab.js +7 -5
- package/client/store/ui-theme.js +1 -1
- package/client/store/watch.js +3 -2
- package/package.json +1 -1
|
@@ -68,7 +68,8 @@ export const connectionMap = buildConst([
|
|
|
68
68
|
'local',
|
|
69
69
|
'web',
|
|
70
70
|
'rdp',
|
|
71
|
-
'vnc'
|
|
71
|
+
'vnc',
|
|
72
|
+
'ftp'
|
|
72
73
|
])
|
|
73
74
|
|
|
74
75
|
export const authTypeMap = buildConst([
|
|
@@ -135,6 +136,7 @@ export const terminalVncType = 'vnc'
|
|
|
135
136
|
export const terminalSerialType = 'serial'
|
|
136
137
|
export const terminalTelnetType = 'telnet'
|
|
137
138
|
export const terminalLocalType = 'local'
|
|
139
|
+
export const terminalFtpType = 'ftp'
|
|
138
140
|
export const openedSidebarKey = 'opened-sidebar'
|
|
139
141
|
export const sidebarPinnedKey = 'sidebar-pinned'
|
|
140
142
|
export const leftSidebarWidthKey = 'left-sidebar-width'
|
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
scrollback: 3000,
|
|
9
9
|
onStartSessions: [],
|
|
10
10
|
fontSize: 16,
|
|
11
|
-
fontFamily: '
|
|
11
|
+
fontFamily: 'Maple Mono, mono, courier-new, courier, monospace',
|
|
12
12
|
execWindows: 'System32/WindowsPowerShell/v1.0/powershell.exe',
|
|
13
13
|
execMac: 'zsh',
|
|
14
14
|
execLinux: 'bash',
|
|
@@ -65,5 +65,6 @@ export default {
|
|
|
65
65
|
apiPathAI: '/chat/completions',
|
|
66
66
|
sessionLogPath: '',
|
|
67
67
|
sshSftpSplitView: false,
|
|
68
|
-
showCmdSuggestions: false
|
|
68
|
+
showCmdSuggestions: false,
|
|
69
|
+
startDirectoryLocal: ''
|
|
69
70
|
}
|
package/client/common/sftp.js
CHANGED
|
@@ -10,16 +10,17 @@ import initWs from './ws'
|
|
|
10
10
|
const transferKeys = Object.keys(transferTypeMap)
|
|
11
11
|
|
|
12
12
|
class Sftp {
|
|
13
|
-
async init (
|
|
13
|
+
async init (terminalId) {
|
|
14
14
|
const id = generate()
|
|
15
|
-
const ws = await initWs('sftp', id,
|
|
15
|
+
const ws = await initWs('sftp', id, terminalId)
|
|
16
16
|
this.ws = ws
|
|
17
17
|
this.id = id
|
|
18
|
-
this.
|
|
18
|
+
this.terminalId = terminalId
|
|
19
19
|
ws.s({
|
|
20
20
|
action: 'sftp-new',
|
|
21
21
|
id,
|
|
22
|
-
|
|
22
|
+
type: this.type,
|
|
23
|
+
terminalId
|
|
23
24
|
})
|
|
24
25
|
const th = this
|
|
25
26
|
this.ws = ws
|
|
@@ -28,8 +29,9 @@ class Sftp {
|
|
|
28
29
|
if (transferKeys.includes(func)) {
|
|
29
30
|
return Transfer({
|
|
30
31
|
sftpId: id,
|
|
32
|
+
isFtp: this.type === 'ftp',
|
|
31
33
|
...args[0],
|
|
32
|
-
|
|
34
|
+
terminalId,
|
|
33
35
|
type: func
|
|
34
36
|
})
|
|
35
37
|
}
|
|
@@ -43,7 +45,8 @@ class Sftp {
|
|
|
43
45
|
uid,
|
|
44
46
|
func,
|
|
45
47
|
args,
|
|
46
|
-
|
|
48
|
+
terminalId,
|
|
49
|
+
type: this.type
|
|
47
50
|
})
|
|
48
51
|
ws.once((arg) => {
|
|
49
52
|
if (arg.error) {
|
|
@@ -62,14 +65,15 @@ class Sftp {
|
|
|
62
65
|
ws.s({
|
|
63
66
|
action: 'sftp-destroy',
|
|
64
67
|
id: this.id,
|
|
65
|
-
|
|
68
|
+
terminalId: this.terminalId
|
|
66
69
|
})
|
|
67
70
|
ws.close()
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
export default async (
|
|
74
|
+
export default async (terminalId, type = 'sftp') => {
|
|
72
75
|
const sftp = new Sftp()
|
|
73
|
-
|
|
76
|
+
sftp.type = type
|
|
77
|
+
await sftp.init(terminalId)
|
|
74
78
|
return sftp
|
|
75
79
|
}
|
|
@@ -18,10 +18,10 @@ class Transfer {
|
|
|
18
18
|
this.id = id
|
|
19
19
|
const th = this
|
|
20
20
|
const {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
sftpId,
|
|
22
|
+
isFtp
|
|
23
23
|
} = rest
|
|
24
|
-
const ws = await initWs('transfer', id,
|
|
24
|
+
const ws = await initWs('transfer', id, sftpId)
|
|
25
25
|
ws.s({
|
|
26
26
|
action: 'transfer-new',
|
|
27
27
|
...rest,
|
|
@@ -32,8 +32,8 @@ class Transfer {
|
|
|
32
32
|
ws.s({
|
|
33
33
|
action: 'transfer-func',
|
|
34
34
|
id: th.id,
|
|
35
|
+
isFtp,
|
|
35
36
|
func,
|
|
36
|
-
sessionId,
|
|
37
37
|
sftpId,
|
|
38
38
|
args
|
|
39
39
|
})
|
package/client/common/ws.js
CHANGED
|
@@ -140,7 +140,7 @@ function onEvent (e) {
|
|
|
140
140
|
|
|
141
141
|
window.worker.addEventListener('message', onEvent)
|
|
142
142
|
|
|
143
|
-
export default (type, id,
|
|
143
|
+
export default (type, id, sftpId = '', persist) => {
|
|
144
144
|
return new Promise((resolve) => {
|
|
145
145
|
send({
|
|
146
146
|
id,
|
|
@@ -150,7 +150,6 @@ export default (type, id, sessionId = '', sftpId = '', persist) => {
|
|
|
150
150
|
args: [
|
|
151
151
|
type,
|
|
152
152
|
id,
|
|
153
|
-
sessionId,
|
|
154
153
|
sftpId,
|
|
155
154
|
pick(window.store.config, [
|
|
156
155
|
'host',
|
|
@@ -168,7 +168,7 @@ export default class BatchOp extends PureComponent {
|
|
|
168
168
|
this.updateState('tab created', index)
|
|
169
169
|
if (conf.cmd) {
|
|
170
170
|
this.updateState('running cmd', index)
|
|
171
|
-
await runCmd(tab.id,
|
|
171
|
+
await runCmd(tab.id, conf.cmd)
|
|
172
172
|
this.updateState('running cmd done', index)
|
|
173
173
|
}
|
|
174
174
|
if (conf.remotePath) {
|
|
@@ -193,7 +193,7 @@ export default class BatchOp extends PureComponent {
|
|
|
193
193
|
this.updateState('run cmd2', index)
|
|
194
194
|
document.querySelector('.session-current .type-tab.ssh').click()
|
|
195
195
|
await wait(200)
|
|
196
|
-
await runCmd(tab.id,
|
|
196
|
+
await runCmd(tab.id, conf.cmdAfterTransfer)
|
|
197
197
|
this.updateState('run cmd2 done', index)
|
|
198
198
|
}
|
|
199
199
|
this.updateState(e('finished'), index)
|
|
@@ -211,7 +211,6 @@ export default class BatchOp extends PureComponent {
|
|
|
211
211
|
fromPath: fp,
|
|
212
212
|
id: uid(),
|
|
213
213
|
operation: '',
|
|
214
|
-
sessionId: tab.sessionId,
|
|
215
214
|
tabId: tab.id,
|
|
216
215
|
title: 'batch operation',
|
|
217
216
|
toPath: resolveFilePath(isDown ? conf.localPath : conf.remotePath, name),
|
|
@@ -230,7 +229,7 @@ export default class BatchOp extends PureComponent {
|
|
|
230
229
|
const first = transferHistory.find(t => {
|
|
231
230
|
return t.id === obj.id || t.originalId === obj.id
|
|
232
231
|
})
|
|
233
|
-
if (first && first.
|
|
232
|
+
if (first && first.id === tab.id) {
|
|
234
233
|
this.ref1 && this.ref1.stop()
|
|
235
234
|
delete this.ref1
|
|
236
235
|
clearTimeout(this.tm)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web form
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { useEffect } from 'react'
|
|
6
|
+
import {
|
|
7
|
+
Input,
|
|
8
|
+
Form,
|
|
9
|
+
InputNumber,
|
|
10
|
+
TreeSelect,
|
|
11
|
+
Switch
|
|
12
|
+
} from 'antd'
|
|
13
|
+
import { formItemLayout } from '../../common/form-layout'
|
|
14
|
+
import {
|
|
15
|
+
newBookmarkIdPrefix,
|
|
16
|
+
terminalFtpType
|
|
17
|
+
} from '../../common/constants'
|
|
18
|
+
import useSubmit from './use-submit'
|
|
19
|
+
import copy from 'json-deep-copy'
|
|
20
|
+
import { defaults, isEmpty } from 'lodash-es'
|
|
21
|
+
import { ColorPickerItem } from './color-picker-item.jsx'
|
|
22
|
+
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
23
|
+
import formatBookmarkGroups from './bookmark-group-tree-format'
|
|
24
|
+
import findBookmarkGroupId from '../../common/find-bookmark-group-id'
|
|
25
|
+
import ProfileItem from './profile-form-item'
|
|
26
|
+
|
|
27
|
+
const FormItem = Form.Item
|
|
28
|
+
const e = window.translate
|
|
29
|
+
|
|
30
|
+
export default function FtpFormUi (props) {
|
|
31
|
+
const [
|
|
32
|
+
form,
|
|
33
|
+
handleFinish,
|
|
34
|
+
submitUi
|
|
35
|
+
] = useSubmit(props)
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (props.formData.id.startsWith(newBookmarkIdPrefix)) {
|
|
38
|
+
form.setFieldsValue({
|
|
39
|
+
category: props.currentBookmarkGroupId
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}, [props.currentBookmarkGroupId])
|
|
43
|
+
const {
|
|
44
|
+
id = ''
|
|
45
|
+
} = props.formData
|
|
46
|
+
const {
|
|
47
|
+
bookmarkGroups = [],
|
|
48
|
+
currentBookmarkGroupId
|
|
49
|
+
} = props
|
|
50
|
+
let initialValues = copy(props.formData)
|
|
51
|
+
const initBookmarkGroupId = !id.startsWith(newBookmarkIdPrefix)
|
|
52
|
+
? findBookmarkGroupId(bookmarkGroups, id)
|
|
53
|
+
: currentBookmarkGroupId
|
|
54
|
+
const defaultValues = {
|
|
55
|
+
type: terminalFtpType,
|
|
56
|
+
port: 21,
|
|
57
|
+
category: initBookmarkGroupId,
|
|
58
|
+
color: getRandomDefaultColor(),
|
|
59
|
+
user: '',
|
|
60
|
+
password: '',
|
|
61
|
+
secure: false
|
|
62
|
+
}
|
|
63
|
+
initialValues = defaults(initialValues, defaultValues)
|
|
64
|
+
|
|
65
|
+
function renderCommon () {
|
|
66
|
+
const {
|
|
67
|
+
bookmarkGroups = []
|
|
68
|
+
} = props
|
|
69
|
+
const tree = formatBookmarkGroups(bookmarkGroups)
|
|
70
|
+
return (
|
|
71
|
+
<div className='pd1x'>
|
|
72
|
+
<FormItem
|
|
73
|
+
{...formItemLayout}
|
|
74
|
+
label={e('title')}
|
|
75
|
+
hasFeedback
|
|
76
|
+
>
|
|
77
|
+
<FormItem noStyle name='title'>
|
|
78
|
+
<Input addonBefore={<ColorPickerItem />} />
|
|
79
|
+
</FormItem>
|
|
80
|
+
</FormItem>
|
|
81
|
+
<FormItem
|
|
82
|
+
{...formItemLayout}
|
|
83
|
+
label={e('host')}
|
|
84
|
+
hasFeedback
|
|
85
|
+
name='host'
|
|
86
|
+
required
|
|
87
|
+
>
|
|
88
|
+
<Input />
|
|
89
|
+
</FormItem>
|
|
90
|
+
<FormItem
|
|
91
|
+
{...formItemLayout}
|
|
92
|
+
label={e('port')}
|
|
93
|
+
hasFeedback
|
|
94
|
+
name='port'
|
|
95
|
+
rules={[{
|
|
96
|
+
required: true, message: 'port required'
|
|
97
|
+
}]}
|
|
98
|
+
>
|
|
99
|
+
<InputNumber
|
|
100
|
+
placeholder={e('port')}
|
|
101
|
+
min={1}
|
|
102
|
+
max={65535}
|
|
103
|
+
step={1}
|
|
104
|
+
/>
|
|
105
|
+
</FormItem>
|
|
106
|
+
<ProfileItem
|
|
107
|
+
store={props.store}
|
|
108
|
+
profileFilter={d => !isEmpty(d.vnc)}
|
|
109
|
+
/>
|
|
110
|
+
<FormItem
|
|
111
|
+
{...formItemLayout}
|
|
112
|
+
label={e('username')}
|
|
113
|
+
hasFeedback
|
|
114
|
+
name='user'
|
|
115
|
+
>
|
|
116
|
+
<Input />
|
|
117
|
+
</FormItem>
|
|
118
|
+
<FormItem
|
|
119
|
+
{...formItemLayout}
|
|
120
|
+
label={e('password')}
|
|
121
|
+
hasFeedback
|
|
122
|
+
name='password'
|
|
123
|
+
>
|
|
124
|
+
<Input.Password />
|
|
125
|
+
</FormItem>
|
|
126
|
+
<FormItem
|
|
127
|
+
{...formItemLayout}
|
|
128
|
+
label={e('secure')}
|
|
129
|
+
name='secure'
|
|
130
|
+
valuePropName='secure'
|
|
131
|
+
>
|
|
132
|
+
<Switch />
|
|
133
|
+
</FormItem>
|
|
134
|
+
<FormItem
|
|
135
|
+
{...formItemLayout}
|
|
136
|
+
label={e('bookmarkCategory')}
|
|
137
|
+
name='category'
|
|
138
|
+
>
|
|
139
|
+
<TreeSelect
|
|
140
|
+
treeData={tree}
|
|
141
|
+
treeDefaultExpandAll
|
|
142
|
+
showSearch
|
|
143
|
+
/>
|
|
144
|
+
</FormItem>
|
|
145
|
+
<FormItem
|
|
146
|
+
{...formItemLayout}
|
|
147
|
+
label='type'
|
|
148
|
+
name='type'
|
|
149
|
+
className='hide'
|
|
150
|
+
>
|
|
151
|
+
<Input />
|
|
152
|
+
</FormItem>
|
|
153
|
+
</div>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Form
|
|
159
|
+
form={form}
|
|
160
|
+
onFinish={handleFinish}
|
|
161
|
+
initialValues={initialValues}
|
|
162
|
+
name='vnc-form'
|
|
163
|
+
>
|
|
164
|
+
{renderCommon()}
|
|
165
|
+
{submitUi}
|
|
166
|
+
</Form>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bookmark form
|
|
3
|
+
*/
|
|
4
|
+
import BookmarkForm from './ssh-form'
|
|
5
|
+
import FtpFormUi from './ftp-form-ui'
|
|
6
|
+
|
|
7
|
+
export default class FtpForm extends BookmarkForm {
|
|
8
|
+
render () {
|
|
9
|
+
return (
|
|
10
|
+
<FtpFormUi
|
|
11
|
+
{...this.props}
|
|
12
|
+
{...this.getProps()}
|
|
13
|
+
/>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
terminalVncType,
|
|
15
15
|
terminalLocalType,
|
|
16
16
|
terminalTelnetType,
|
|
17
|
+
terminalFtpType,
|
|
17
18
|
newBookmarkIdPrefix
|
|
18
19
|
} from '../../common/constants'
|
|
19
20
|
import SshForm from './ssh-form'
|
|
@@ -23,6 +24,7 @@ import TelnetForm from './telnet-form'
|
|
|
23
24
|
import WebForm from './web-form'
|
|
24
25
|
import RdpForm from './rdp-form'
|
|
25
26
|
import VncForm from './vnc-form'
|
|
27
|
+
import FtpForm from './ftp-form'
|
|
26
28
|
import { createTitleWithTag } from '../../common/create-title'
|
|
27
29
|
import {
|
|
28
30
|
LoadingOutlined,
|
|
@@ -42,7 +44,8 @@ export default class BookmarkIndex extends PureComponent {
|
|
|
42
44
|
terminalLocalType,
|
|
43
45
|
terminalSerialType,
|
|
44
46
|
terminalRdpType,
|
|
45
|
-
terminalVncType
|
|
47
|
+
terminalVncType,
|
|
48
|
+
terminalFtpType
|
|
46
49
|
].includes(initType)
|
|
47
50
|
) {
|
|
48
51
|
initType = connectionMap.ssh
|
|
@@ -72,7 +75,8 @@ export default class BookmarkIndex extends PureComponent {
|
|
|
72
75
|
[connectionMap.local]: LocalForm,
|
|
73
76
|
[connectionMap.web]: WebForm,
|
|
74
77
|
[connectionMap.rdp]: RdpForm,
|
|
75
|
-
[connectionMap.vnc]: VncForm
|
|
78
|
+
[connectionMap.vnc]: VncForm,
|
|
79
|
+
[connectionMap.ftp]: FtpForm
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
handleChange = (e) => {
|
|
@@ -97,8 +101,9 @@ export default class BookmarkIndex extends PureComponent {
|
|
|
97
101
|
{
|
|
98
102
|
keys.map(k => {
|
|
99
103
|
const v = connectionMap[k]
|
|
104
|
+
const txt = v === 'ssh' ? 'Ssh/Sftp' : e(v)
|
|
100
105
|
return (
|
|
101
|
-
<Radio.Button key={v} value={v}>{
|
|
106
|
+
<Radio.Button key={v} value={v}>{txt}</Radio.Button>
|
|
102
107
|
)
|
|
103
108
|
})
|
|
104
109
|
}
|
|
@@ -27,6 +27,7 @@ export default function renderSshTunnels (props) {
|
|
|
27
27
|
} = props
|
|
28
28
|
const [formChild] = Form.useForm()
|
|
29
29
|
const [initialValues] = useState({
|
|
30
|
+
sshTunnel: 'forwardRemoteToLocal',
|
|
30
31
|
sshTunnelLocalPort: 12200,
|
|
31
32
|
sshTunnelLocalHost: '127.0.0.1',
|
|
32
33
|
sshTunnelRemotePort: 12300,
|
|
@@ -214,6 +215,7 @@ export default function renderSshTunnels (props) {
|
|
|
214
215
|
label={e('sshTunnel')}
|
|
215
216
|
name='sshTunnel'
|
|
216
217
|
{...formItemLayout}
|
|
218
|
+
defaultValue='forwardRemoteToLocal'
|
|
217
219
|
required
|
|
218
220
|
>
|
|
219
221
|
<RadioGroup onChange={onChange}>
|
|
@@ -79,13 +79,6 @@ const defaultServerHostKeyOptions = [
|
|
|
79
79
|
|
|
80
80
|
export default function renderX11 (form) {
|
|
81
81
|
function setDefaults () {
|
|
82
|
-
// form.setFieldsValue({
|
|
83
|
-
// cipher: defaultCipherOptions
|
|
84
|
-
// })
|
|
85
|
-
|
|
86
|
-
// form.setFieldsValue({
|
|
87
|
-
// serverHostKey: defaultServerHostKeyOptions
|
|
88
|
-
// })
|
|
89
82
|
form.setFieldValue('cipher', defaultCipherOptions)
|
|
90
83
|
form.setFieldValue('serverHostKey', defaultServerHostKeyOptions)
|
|
91
84
|
}
|
|
@@ -97,12 +90,11 @@ export default function renderX11 (form) {
|
|
|
97
90
|
name='cipher'
|
|
98
91
|
>
|
|
99
92
|
<Select
|
|
100
|
-
mode='
|
|
93
|
+
mode='tags'
|
|
94
|
+
style={{ width: '100%' }}
|
|
101
95
|
>
|
|
102
96
|
{cipherOptions.map(cipher => (
|
|
103
|
-
<Option key={cipher} value={cipher}>
|
|
104
|
-
{cipher}
|
|
105
|
-
</Option>
|
|
97
|
+
<Option key={cipher} value={cipher}>{cipher}</Option>
|
|
106
98
|
))}
|
|
107
99
|
</Select>
|
|
108
100
|
</FormItem>
|
|
@@ -116,12 +108,11 @@ export default function renderX11 (form) {
|
|
|
116
108
|
name='serverHostKey'
|
|
117
109
|
>
|
|
118
110
|
<Select
|
|
119
|
-
mode='
|
|
111
|
+
mode='tags'
|
|
112
|
+
style={{ width: '100%' }}
|
|
120
113
|
>
|
|
121
114
|
{serverHostKeyOptions.map(key => (
|
|
122
|
-
<Option key={key} value={key}>
|
|
123
|
-
{key}
|
|
124
|
-
</Option>
|
|
115
|
+
<Option key={key} value={key}>{key}</Option>
|
|
125
116
|
))}
|
|
126
117
|
</Select>
|
|
127
118
|
</FormItem>
|
|
@@ -153,7 +153,7 @@ export default class ConfirmModalStore extends Component {
|
|
|
153
153
|
<Button
|
|
154
154
|
type='dashed'
|
|
155
155
|
className='mg1l'
|
|
156
|
-
onClick={() => this.act(fileActions.
|
|
156
|
+
onClick={() => this.act(fileActions.skipAll)}
|
|
157
157
|
>
|
|
158
158
|
{e('cancel')}
|
|
159
159
|
</Button>
|
|
@@ -208,6 +208,16 @@ export default class ConfirmModalStore extends Component {
|
|
|
208
208
|
>
|
|
209
209
|
{e('renameAll')}
|
|
210
210
|
</Button>
|
|
211
|
+
<Button
|
|
212
|
+
type='primary'
|
|
213
|
+
className='mg1l'
|
|
214
|
+
title={e('skipAll')}
|
|
215
|
+
onClick={
|
|
216
|
+
() => this.act(fileActions.skipAll)
|
|
217
|
+
}
|
|
218
|
+
>
|
|
219
|
+
{e('skipAll')}
|
|
220
|
+
</Button>
|
|
211
221
|
</div>
|
|
212
222
|
</div>
|
|
213
223
|
)
|
|
@@ -19,16 +19,18 @@ const { assign } = Object
|
|
|
19
19
|
export default class TransportAction extends Component {
|
|
20
20
|
constructor (props) {
|
|
21
21
|
super(props)
|
|
22
|
-
this.sessionId = props.transfer.sessionId
|
|
23
22
|
const {
|
|
24
23
|
id,
|
|
25
|
-
transferBatch = ''
|
|
24
|
+
transferBatch = '',
|
|
25
|
+
tabId
|
|
26
26
|
} = props.transfer
|
|
27
27
|
this.id = `tr-${transferBatch}-${id}`
|
|
28
|
+
this.tabId = tabId
|
|
28
29
|
refsTransfers.add(this.id, this)
|
|
29
30
|
this.total = 0
|
|
30
31
|
this.transferred = 0
|
|
31
32
|
this.currentProgress = 1
|
|
33
|
+
this.isFtp = refs.get('sftp-' + tabId)?.type === 'ftp'
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
componentDidMount () {
|
|
@@ -66,9 +68,9 @@ export default class TransportAction extends Component {
|
|
|
66
68
|
return getLocalFileInfo(path).catch(console.log)
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
remoteCheckExist = (path,
|
|
71
|
+
remoteCheckExist = (path, tabId) => {
|
|
70
72
|
// return true
|
|
71
|
-
const sftp = refs.get('sftp-' +
|
|
73
|
+
const sftp = refs.get('sftp-' + tabId)?.sftp
|
|
72
74
|
if (!sftp) {
|
|
73
75
|
console.log('remoteCheckExist error', 'sftp not exist')
|
|
74
76
|
return false
|
|
@@ -81,8 +83,8 @@ export default class TransportAction extends Component {
|
|
|
81
83
|
})
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
checkExist = (type, path,
|
|
85
|
-
return this[type + 'CheckExist'](path,
|
|
86
|
+
checkExist = (type, path, tabId) => {
|
|
87
|
+
return this[type + 'CheckExist'](path, tabId)
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
update = (up) => {
|
|
@@ -123,11 +125,11 @@ export default class TransportAction extends Component {
|
|
|
123
125
|
// }
|
|
124
126
|
|
|
125
127
|
remoteList = () => {
|
|
126
|
-
window.store.remoteList(this.
|
|
128
|
+
window.store.remoteList(this.tabId)
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
localList = () => {
|
|
130
|
-
window.store.localList(this.
|
|
132
|
+
window.store.localList(this.tabId)
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
onEnd = (update = {}) => {
|
|
@@ -223,7 +225,7 @@ export default class TransportAction extends Component {
|
|
|
223
225
|
fromPath,
|
|
224
226
|
toPath,
|
|
225
227
|
typeFrom,
|
|
226
|
-
|
|
228
|
+
tabId,
|
|
227
229
|
operation // 'mv' or 'cp'
|
|
228
230
|
} = transfer
|
|
229
231
|
|
|
@@ -245,7 +247,7 @@ export default class TransportAction extends Component {
|
|
|
245
247
|
this.onError(e)
|
|
246
248
|
})
|
|
247
249
|
}
|
|
248
|
-
const sftp = refs.get('sftp-' +
|
|
250
|
+
const sftp = refs.get('sftp-' + tabId)?.sftp
|
|
249
251
|
return sftp[operation](fromPath, finalToPath)
|
|
250
252
|
.then(this.onEnd)
|
|
251
253
|
.catch(e => {
|
|
@@ -272,7 +274,7 @@ export default class TransportAction extends Component {
|
|
|
272
274
|
? fromPath
|
|
273
275
|
: toPath
|
|
274
276
|
const mode = toFile.mode || fromMode
|
|
275
|
-
const sftp = refs.get('sftp-' + this.
|
|
277
|
+
const sftp = refs.get('sftp-' + this.tabId).sftp
|
|
276
278
|
this.transport = await sftp[transferType]({
|
|
277
279
|
remotePath,
|
|
278
280
|
localPath,
|
|
@@ -318,7 +320,7 @@ export default class TransportAction extends Component {
|
|
|
318
320
|
|
|
319
321
|
const fromFile = transfer.fromFile
|
|
320
322
|
? transfer.fromFile
|
|
321
|
-
: await this.checkExist(typeFrom, fromPath, this.
|
|
323
|
+
: await this.checkExist(typeFrom, fromPath, this.tabId)
|
|
322
324
|
if (!fromFile) {
|
|
323
325
|
return this.tagTransferError(id, 'file not exist')
|
|
324
326
|
}
|
|
@@ -344,13 +346,13 @@ export default class TransportAction extends Component {
|
|
|
344
346
|
const {
|
|
345
347
|
typeTo,
|
|
346
348
|
toPath,
|
|
347
|
-
|
|
349
|
+
tabId
|
|
348
350
|
} = transfer
|
|
349
351
|
const transferStillExists = window.store.fileTransfers.some(t => t.id === transfer.id)
|
|
350
352
|
if (!transferStillExists) {
|
|
351
353
|
return false
|
|
352
354
|
}
|
|
353
|
-
const toFile = await this.checkExist(typeTo, toPath,
|
|
355
|
+
const toFile = await this.checkExist(typeTo, toPath, tabId)
|
|
354
356
|
|
|
355
357
|
if (toFile) {
|
|
356
358
|
this.update({
|
|
@@ -405,8 +407,8 @@ export default class TransportAction extends Component {
|
|
|
405
407
|
})
|
|
406
408
|
}
|
|
407
409
|
|
|
408
|
-
list = async (type, path,
|
|
409
|
-
const sftp = refs.get('sftp-' +
|
|
410
|
+
list = async (type, path, tabId) => {
|
|
411
|
+
const sftp = refs.get('sftp-' + tabId)
|
|
410
412
|
return sftp[type + 'List'](true, path)
|
|
411
413
|
}
|
|
412
414
|
|
|
@@ -456,7 +458,7 @@ export default class TransportAction extends Component {
|
|
|
456
458
|
const localPath = isDown ? toPath : fromPath
|
|
457
459
|
const remotePath = isDown ? fromPath : toPath
|
|
458
460
|
const mode = toFile.mode || fromMode
|
|
459
|
-
const sftp = refs.get('sftp-' + this.
|
|
461
|
+
const sftp = refs.get('sftp-' + this.tabId).sftp
|
|
460
462
|
|
|
461
463
|
return new Promise((resolve, reject) => {
|
|
462
464
|
let transport
|
|
@@ -611,7 +613,7 @@ export default class TransportAction extends Component {
|
|
|
611
613
|
const {
|
|
612
614
|
fromPath,
|
|
613
615
|
typeFrom,
|
|
614
|
-
|
|
616
|
+
tabId,
|
|
615
617
|
toFile,
|
|
616
618
|
isRenamed
|
|
617
619
|
} = transfer
|
|
@@ -623,11 +625,11 @@ export default class TransportAction extends Component {
|
|
|
623
625
|
}
|
|
624
626
|
}
|
|
625
627
|
|
|
626
|
-
const list = await this.list(typeFrom, fromPath,
|
|
628
|
+
const list = await this.list(typeFrom, fromPath, tabId)
|
|
627
629
|
const bigFileSize = 1024 * 1024
|
|
628
|
-
const smallFilesBatch = 30
|
|
629
|
-
const BigFilesBatch = 3
|
|
630
|
-
const foldersBatch = 50
|
|
630
|
+
const smallFilesBatch = this.isFtp ? 1 : 30
|
|
631
|
+
const BigFilesBatch = this.isFtp ? 1 : 3
|
|
632
|
+
const foldersBatch = this.isFtp ? 1 : 50
|
|
631
633
|
|
|
632
634
|
const {
|
|
633
635
|
folders,
|
|
@@ -672,14 +674,14 @@ export default class TransportAction extends Component {
|
|
|
672
674
|
const {
|
|
673
675
|
typeTo,
|
|
674
676
|
toPath,
|
|
675
|
-
|
|
677
|
+
tabId
|
|
676
678
|
} = transfer
|
|
677
679
|
if (typeTo === typeMap.local) {
|
|
678
680
|
return fs.mkdir(toPath)
|
|
679
681
|
.then(() => true)
|
|
680
682
|
.catch(() => false)
|
|
681
683
|
}
|
|
682
|
-
const sftp = refs.get('sftp-' +
|
|
684
|
+
const sftp = refs.get('sftp-' + tabId).sftp
|
|
683
685
|
return sftp.mkdir(toPath)
|
|
684
686
|
.then(() => true)
|
|
685
687
|
.catch(() => false)
|