@electerm/electerm-react 1.80.18 → 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.
Files changed (37) hide show
  1. package/client/common/constants.js +3 -1
  2. package/client/common/default-setting.js +2 -1
  3. package/client/common/fetch-from-server.js +1 -1
  4. package/client/common/sftp.js +13 -9
  5. package/client/common/transfer.js +4 -4
  6. package/client/common/ws.js +1 -2
  7. package/client/components/batch-op/batch-op.jsx +3 -4
  8. package/client/components/bookmark-form/ftp-form-ui.jsx +168 -0
  9. package/client/components/bookmark-form/ftp-form.jsx +16 -0
  10. package/client/components/bookmark-form/index.jsx +8 -3
  11. package/client/components/bookmark-form/render-ssh-tunnel.jsx +2 -0
  12. package/client/components/bookmark-form/x11.jsx +6 -15
  13. package/client/components/file-transfer/transfer.jsx +26 -24
  14. package/client/components/footer/tab-select.jsx +1 -1
  15. package/client/components/rdp/rdp-session.jsx +2 -3
  16. package/client/components/session/session.jsx +21 -22
  17. package/client/components/setting-panel/setting-terminal.jsx +5 -0
  18. package/client/components/sftp/address-bar.jsx +6 -1
  19. package/client/components/sftp/file-info-modal.jsx +0 -2
  20. package/client/components/sftp/file-item.jsx +60 -24
  21. package/client/components/sftp/owner-list.js +4 -4
  22. package/client/components/sftp/sftp-entry.jsx +62 -21
  23. package/client/components/sftp/transfer-common.js +1 -2
  24. package/client/components/sidebar/transfer-list-control.jsx +5 -5
  25. package/client/components/terminal/terminal-apis.js +4 -8
  26. package/client/components/terminal/terminal.jsx +6 -10
  27. package/client/components/terminal-info/base.jsx +4 -8
  28. package/client/components/terminal-info/run-cmd.jsx +2 -3
  29. package/client/components/terminal-info/terminal-info.jsx +2 -3
  30. package/client/components/theme/theme-list-item.jsx +22 -42
  31. package/client/components/tree-list/bookmark-toolbar.jsx +58 -46
  32. package/client/components/vnc/vnc-session.jsx +2 -3
  33. package/client/entry/worker.js +1 -2
  34. package/client/store/tab.js +7 -5
  35. package/client/store/ui-theme.js +1 -1
  36. package/client/store/watch.js +3 -2
  37. 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'
@@ -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
  }
@@ -13,7 +13,7 @@ export const initWsCommon = async () => {
13
13
  if (window.et.wsOpened) {
14
14
  return
15
15
  }
16
- const ws = await initWs('common', id, undefined, undefined, true)
16
+ const ws = await initWs('common', id, undefined, true)
17
17
  if (!ws) {
18
18
  return
19
19
  }
@@ -10,16 +10,17 @@ import initWs from './ws'
10
10
  const transferKeys = Object.keys(transferTypeMap)
11
11
 
12
12
  class Sftp {
13
- async init (sessionId) {
13
+ async init (terminalId) {
14
14
  const id = generate()
15
- const ws = await initWs('sftp', id, sessionId)
15
+ const ws = await initWs('sftp', id, terminalId)
16
16
  this.ws = ws
17
17
  this.id = id
18
- this.sessionId = sessionId
18
+ this.terminalId = terminalId
19
19
  ws.s({
20
20
  action: 'sftp-new',
21
21
  id,
22
- sessionId
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
- sessionId,
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
- sessionId
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
- sessionId: this.sessionId
68
+ terminalId: this.terminalId
66
69
  })
67
70
  ws.close()
68
71
  }
69
72
  }
70
73
 
71
- export default async (sessionId) => {
74
+ export default async (terminalId, type = 'sftp') => {
72
75
  const sftp = new Sftp()
73
- await sftp.init(sessionId)
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
- sessionId,
22
- sftpId
21
+ sftpId,
22
+ isFtp
23
23
  } = rest
24
- const ws = await initWs('transfer', id, sessionId, sftpId)
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
  })
@@ -140,7 +140,7 @@ function onEvent (e) {
140
140
 
141
141
  window.worker.addEventListener('message', onEvent)
142
142
 
143
- export default (type, id, sessionId = '', sftpId = '', persist) => {
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, tab.sessionId, conf.cmd)
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, tab.sessionId, conf.cmdAfterTransfer)
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.sessionId === tab.sessionId) {
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}>{e(v)}</Radio.Button>
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='multiple'
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='multiple'
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>
@@ -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, sessionId) => {
71
+ remoteCheckExist = (path, tabId) => {
70
72
  // return true
71
- const sftp = refs.get('sftp-' + sessionId)?.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, sessionId) => {
85
- return this[type + 'CheckExist'](path, sessionId)
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.sessionId)
128
+ window.store.remoteList(this.tabId)
127
129
  }
128
130
 
129
131
  localList = () => {
130
- window.store.localList(this.sessionId)
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
- sessionId,
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-' + sessionId)?.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.sessionId).sftp
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.sessionId)
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
- sessionId
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, sessionId)
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, sessionId) => {
409
- const sftp = refs.get('sftp-' + sessionId)
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.sessionId).sftp
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
- sessionId,
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, sessionId)
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
- sessionId
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-' + sessionId).sftp
684
+ const sftp = refs.get('sftp-' + tabId).sftp
683
685
  return sftp.mkdir(toPath)
684
686
  .then(() => true)
685
687
  .catch(() => false)
@@ -52,7 +52,7 @@ export default function TabSelect (props) {
52
52
  }
53
53
  function renderContent () {
54
54
  return (
55
- <div className='pd1x'>
55
+ <div className='pd1x alignright'>
56
56
  {renderBtns()}
57
57
  {renderTabs()}
58
58
  </div>
@@ -67,7 +67,7 @@ export default class RdpSession extends PureComponent {
67
67
  tokenElecterm,
68
68
  server = ''
69
69
  } = config
70
- const { sessionId, id } = this.props
70
+ const { id } = this.props
71
71
  const tab = window.store.applyProfile(deepCopy(this.props.tab || {}))
72
72
  const {
73
73
  type,
@@ -75,7 +75,6 @@ export default class RdpSession extends PureComponent {
75
75
  } = tab
76
76
  const opts = clone({
77
77
  term: terminalType || config.terminalType,
78
- sessionId,
79
78
  tabId: id,
80
79
  srcTabId: tab.id,
81
80
  termType: type,
@@ -101,7 +100,7 @@ export default class RdpSession extends PureComponent {
101
100
  : `${host}:${port}`
102
101
  const pre = server.startsWith('https') ? 'wss' : 'ws'
103
102
  const { width, height } = this.state
104
- const wsUrl = `${pre}://${hs}/rdp/${pid}?sessionId=${sessionId}&token=${tokenElecterm}&width=${width}&height=${height}`
103
+ const wsUrl = `${pre}://${hs}/rdp/${pid}?&token=${tokenElecterm}&width=${width}&height=${height}`
105
104
  const socket = new WebSocket(wsUrl)
106
105
  socket.onclose = this.oncloseSocket
107
106
  socket.onerror = this.onerrorSocket