@electerm/electerm-react 1.38.65 → 1.38.80

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 (43) hide show
  1. package/client/common/constants.js +6 -3
  2. package/client/common/create-title.jsx +9 -1
  3. package/client/common/sftp.js +3 -0
  4. package/client/components/batch-op/batch-op.jsx +1 -6
  5. package/client/components/bookmark-form/bookmark-form.styl +3 -1
  6. package/client/components/bookmark-form/index.jsx +12 -8
  7. package/client/components/bookmark-form/render-ssh-tunnel.jsx +210 -88
  8. package/client/components/bookmark-form/ssh-form-ui.jsx +1 -1
  9. package/client/components/bookmark-form/web-form-ui.jsx +96 -0
  10. package/client/components/bookmark-form/web-form.jsx +16 -0
  11. package/client/components/main/main.jsx +14 -0
  12. package/client/components/quick-commands/qm.styl +1 -1
  13. package/client/components/session/session.styl +4 -1
  14. package/client/components/session/sessions.jsx +16 -2
  15. package/client/components/session/web-session.jsx +20 -0
  16. package/client/components/sftp/{confirm-modal.jsx → confirm-modal-store.jsx} +81 -50
  17. package/client/components/sftp/file-item.jsx +2 -0
  18. package/client/components/sftp/sftp-entry.jsx +27 -37
  19. package/client/components/sftp/transfer-conflict-store.jsx +291 -0
  20. package/client/components/sftp/transport-action-store.jsx +430 -0
  21. package/client/components/sftp/transports-action-store.jsx +102 -0
  22. package/client/components/sftp/transports-ui-store.jsx +30 -0
  23. package/client/components/sidebar/transfer-list-control.jsx +5 -14
  24. package/client/components/sidebar/transport-ui.jsx +2 -12
  25. package/client/components/tabs/tab.jsx +43 -2
  26. package/client/components/tabs/tabs.styl +1 -1
  27. package/client/components/terminal/index.jsx +14 -1
  28. package/client/components/terminal/terminal-interactive.jsx +15 -0
  29. package/client/components/terminal-info/disk.jsx +9 -0
  30. package/client/entry/worker.js +5 -1
  31. package/client/store/index.js +16 -1
  32. package/client/store/init-state.js +2 -3
  33. package/client/store/sync.js +5 -2
  34. package/client/store/tab.js +1 -1
  35. package/client/store/transfer-list.js +55 -2
  36. package/client/store/watch.js +0 -8
  37. package/package.json +1 -1
  38. package/client/components/sftp/transfer-conflict.jsx +0 -323
  39. package/client/components/sftp/transport-action.jsx +0 -412
  40. package/client/components/sftp/transport-entry.jsx +0 -108
  41. package/client/components/sftp/transport-types.js +0 -8
  42. package/client/components/sftp/transports-action.jsx +0 -111
  43. package/client/components/sftp/transports-ui.jsx +0 -93
@@ -1,5 +1,6 @@
1
1
  import { Component } from '../common/react-subx'
2
2
  import Session from './session'
3
+ import WebSession from './web-session'
3
4
  import { findIndex, pick } from 'lodash-es'
4
5
  import classNames from 'classnames'
5
6
  import generate from '../../common/uid'
@@ -11,7 +12,8 @@ import {
11
12
  tabActions,
12
13
  termInitId,
13
14
  paneMap,
14
- statusMap
15
+ statusMap,
16
+ terminalWebType
15
17
  } from '../../common/constants'
16
18
  import newTerm, { updateCount } from '../../common/new-terminal'
17
19
  import postMsg from '../../common/post-msg'
@@ -336,7 +338,7 @@ class Sessions extends Component {
336
338
  return this.renderNoSession()
337
339
  }
338
340
  return tabs.map((tab) => {
339
- const { id } = tab
341
+ const { id, type } = tab
340
342
  const cls = classNames(
341
343
  `session-wrap session-${id}`,
342
344
  {
@@ -372,6 +374,18 @@ class Sessions extends Component {
372
374
  'editTab'
373
375
  ])
374
376
  }
377
+ if (type === terminalWebType) {
378
+ const webProps = {
379
+ tab
380
+ }
381
+ return (
382
+ <div className={cls} key={id}>
383
+ <WebSession
384
+ {...webProps}
385
+ />
386
+ </div>
387
+ )
388
+ }
375
389
  return (
376
390
  <div className={cls} key={id}>
377
391
  <Session
@@ -0,0 +1,20 @@
1
+ import { useEffect } from 'react'
2
+ import Link from '../common/external-link'
3
+
4
+ export default function WebSession (props) {
5
+ const {
6
+ tab
7
+ } = props
8
+ useEffect(() => {
9
+ tab.url && window.openLink(tab.url)
10
+ }, [])
11
+ return (
12
+ <div className='web-session-wrap'>
13
+ <div className='pd3 aligncenter'>
14
+ <h1>{tab.title}</h1>
15
+ <p>{tab.description}</p>
16
+ <Link to={tab.url}>{tab.url}</Link>
17
+ </div>
18
+ </div>
19
+ )
20
+ }
@@ -3,6 +3,7 @@
3
3
  *
4
4
  */
5
5
 
6
+ import { Component } from '../common/react-subx'
6
7
  import { Modal, Button } from 'antd'
7
8
  import { isString } from 'lodash-es'
8
9
  import AnimateText from '../common/animate-text'
@@ -23,42 +24,51 @@ function formatTimeAuto (strOrDigit) {
23
24
  return formatTime(strOrDigit * 1000)
24
25
  }
25
26
 
26
- export default (props) => {
27
- if (!props.transferToConfirm) {
28
- return null
29
- }
30
- const {
31
- fromPath,
32
- toPath,
33
- fromFile: {
34
- isDirectory,
35
- name,
36
- id: fileId,
37
- modifyTime: modifyTimeFrom,
38
- size: sizeFrom,
39
- type: typeFrom
40
- },
41
- toFile: {
42
- modifyTime: modifyTimeTo,
43
- size: sizeTo,
44
- type: typeTo
45
- },
46
- id,
47
- transferGroupId
48
- } = props.transferToConfirm
49
- function act (action) {
50
- props.modifier({
51
- transferToConfirm: null
52
- })
27
+ export default class ConfirmModalStore extends Component {
28
+ act (action) {
29
+ const { store } = this.props
30
+ const {
31
+ transferToConfirm
32
+ } = store
33
+ store.setState(
34
+ 'transferToConfirm', {}
35
+ )
36
+ const {
37
+ fromFile: {
38
+ id: fileId
39
+ },
40
+ id,
41
+ transferGroupId
42
+ } = transferToConfirm
53
43
  postMessage({
54
44
  transferGroupId,
55
45
  fileId,
56
46
  id,
57
- transfer: props.transferToConfirm,
47
+ transfer: transferToConfirm,
58
48
  action
59
49
  })
60
50
  }
61
- function renderContent () {
51
+
52
+ renderContent () {
53
+ const {
54
+ transferToConfirm
55
+ } = this.props.store
56
+ const {
57
+ fromPath,
58
+ toPath,
59
+ fromFile: {
60
+ isDirectory,
61
+ name,
62
+ modifyTime: modifyTimeFrom,
63
+ size: sizeFrom,
64
+ type: typeFrom
65
+ },
66
+ toFile: {
67
+ modifyTime: modifyTimeTo,
68
+ size: sizeTo,
69
+ type: typeTo
70
+ }
71
+ } = transferToConfirm
62
72
  const action = isDirectory ? e('merge') : e('replace')
63
73
  const typeTxt = isDirectory ? e('folder') : e('file')
64
74
  const Icon = isDirectory ? FolderOutlined : FileOutlined
@@ -95,27 +105,39 @@ export default (props) => {
95
105
  </div>
96
106
  )
97
107
  }
98
- function renderFooter () {
108
+
109
+ renderFooter () {
110
+ const {
111
+ transferToConfirm
112
+ } = this.props.store
113
+ if (!transferToConfirm) {
114
+ return null
115
+ }
116
+ const {
117
+ fromFile: {
118
+ isDirectory
119
+ }
120
+ } = transferToConfirm
99
121
  return (
100
122
  <div className='mgq1t pd1y alignright'>
101
123
  <Button
102
124
  type='dashed'
103
125
  className='mg1l'
104
- onClick={() => act(fileActions.cancel)}
126
+ onClick={() => this.act(fileActions.cancel)}
105
127
  >
106
128
  {e('cancel')}
107
129
  </Button>
108
130
  <Button
109
131
  type='dashed'
110
132
  className='mg1l'
111
- onClick={() => act(fileActions.skip)}
133
+ onClick={() => this.act(fileActions.skip)}
112
134
  >
113
135
  {e('skip')}
114
136
  </Button>
115
137
  <Button
116
138
  type='dashed'
117
139
  className='mg1l'
118
- onClick={() => act(fileActions.skipAll)}
140
+ onClick={() => this.act(fileActions.skipAll)}
119
141
  >
120
142
  {e('skipAll')}
121
143
  </Button>
@@ -123,7 +145,7 @@ export default (props) => {
123
145
  danger
124
146
  className='mg1l'
125
147
  onClick={
126
- () => act(fileActions.mergeOrOverwrite)
148
+ () => this.act(fileActions.mergeOrOverwrite)
127
149
  }
128
150
  >
129
151
  {isDirectory ? e('merge') : e('overwrite')}
@@ -132,7 +154,7 @@ export default (props) => {
132
154
  type='primary'
133
155
  className='mg1l'
134
156
  onClick={
135
- () => act(fileActions.rename)
157
+ () => this.act(fileActions.rename)
136
158
  }
137
159
  >
138
160
  {e('rename')}
@@ -148,7 +170,7 @@ export default (props) => {
148
170
  : e('overwriteDesc')
149
171
  }
150
172
  onClick={
151
- () => act(fileActions.mergeOrOverwriteAll)
173
+ () => this.act(fileActions.mergeOrOverwriteAll)
152
174
  }
153
175
  >
154
176
  {isDirectory ? e('mergeAll') : e('overwriteAll')}
@@ -158,7 +180,7 @@ export default (props) => {
158
180
  className='mg1l'
159
181
  title={e('renameDesc')}
160
182
  onClick={
161
- () => act(fileActions.renameAll)
183
+ () => this.act(fileActions.renameAll)
162
184
  }
163
185
  >
164
186
  {e('renameAll')}
@@ -167,18 +189,27 @@ export default (props) => {
167
189
  </div>
168
190
  )
169
191
  }
170
- const modalProps = {
171
- open: true,
172
- width: 500,
173
- title: e('fileConflict'),
174
- footer: renderFooter(),
175
- onCancel: () => act(fileActions.cancel)
192
+
193
+ render () {
194
+ const {
195
+ transferToConfirm
196
+ } = this.props.store
197
+ if (!transferToConfirm.id) {
198
+ return null
199
+ }
200
+ const modalProps = {
201
+ open: true,
202
+ width: 500,
203
+ title: e('fileConflict'),
204
+ footer: this.renderFooter(),
205
+ onCancel: () => this.act(fileActions.cancel)
206
+ }
207
+ return (
208
+ <Modal
209
+ {...modalProps}
210
+ >
211
+ {this.renderContent()}
212
+ </Modal>
213
+ )
176
214
  }
177
- return (
178
- <Modal
179
- {...modalProps}
180
- >
181
- {renderContent()}
182
- </Modal>
183
- )
184
215
  }
@@ -168,6 +168,7 @@ export default class FileSection extends React.Component {
168
168
  fromPath,
169
169
  toPath,
170
170
  id: generate(),
171
+ host: this.props.tab?.host,
171
172
  ...createTransferProps(this.props),
172
173
  operation
173
174
  })
@@ -804,6 +805,7 @@ export default class FileSection extends React.Component {
804
805
  }
805
806
  toPath = resolve(toPath, name)
806
807
  const obj = {
808
+ host: this.props.tab?.host,
807
809
  typeFrom: type,
808
810
  typeTo,
809
811
  fromPath: resolve(path, name),
@@ -14,8 +14,10 @@ import {
14
14
  typeMap, maxSftpHistory, paneMap,
15
15
  eventTypes,
16
16
  fileTypeMap,
17
- terminalSshConfigType, terminalSerialType,
18
- unexpectedPacketErrorDesc, sftpRetryInterval,
17
+ terminalSshConfigType,
18
+ terminalSerialType,
19
+ unexpectedPacketErrorDesc,
20
+ sftpRetryInterval,
19
21
  commonActions
20
22
  } from '../../common/constants'
21
23
  import { hasFileInClipboardText } from '../../common/clipboard'
@@ -27,7 +29,6 @@ import ListTable from './list-table-ui'
27
29
  import deepCopy from 'json-deep-copy'
28
30
  import isValidPath from '../../common/is-valid-path'
29
31
  import memoizeOne from 'memoize-one'
30
- import TransportEntry from './transport-entry'
31
32
  import postMessage from '../../common/post-msg'
32
33
  import { runCmd } from '../terminal/terminal-apis'
33
34
  import * as owner from './owner-list'
@@ -58,9 +59,6 @@ export default class Sftp extends Component {
58
59
  onEditFile: false,
59
60
  ...this.defaultState(),
60
61
  loadingSftp: false,
61
- transferToConfirm: null,
62
- transferList: [],
63
- pauseAll: false,
64
62
  inited: false
65
63
  }
66
64
  this.retryCount = 0
@@ -190,11 +188,27 @@ export default class Sftp extends Component {
190
188
  }, isEqual)
191
189
 
192
190
  initEvent () {
191
+ window.addEventListener('message', this.handleMsg)
193
192
  window.addEventListener('keydown', this.handleEvent)
194
193
  }
195
194
 
196
195
  destroyEvent () {
197
196
  window.removeEventListener('keydown', this.handleEvent)
197
+ window.removeEventListener('message', this.handleMsg)
198
+ }
199
+
200
+ handleMsg = event => {
201
+ const {
202
+ action,
203
+ sessionId,
204
+ type
205
+ } = event?.data || {}
206
+ if (
207
+ action === commonActions.sftpList &&
208
+ sessionId === this.props.sessionId
209
+ ) {
210
+ this[type + 'List']()
211
+ }
198
212
  }
199
213
 
200
214
  isActive () {
@@ -437,32 +451,28 @@ export default class Sftp extends Component {
437
451
  }
438
452
  const { type } = lastClickedFile
439
453
  const { inputFocus, onDelete } = this
454
+ e.stopPropagation()
440
455
  if (keyControlPressed(e) && keyPressed(e, 'keyA') && !inputFocus) {
441
- e.stopPropagation()
442
456
  this.selectAll(type, e)
443
457
  } else if (keyPressed(e, 'arrowdown') && !inputFocus) {
444
- e.stopPropagation()
445
458
  this.selectNext(type)
446
459
  } else if (keyPressed(e, 'arrowup') && !inputFocus) {
447
- e.stopPropagation()
448
460
  this.selectPrev(type)
449
- } else if (keyPressed(e, 'delete') && !inputFocus) {
450
- e.stopPropagation()
461
+ } else if (
462
+ keyPressed(e, 'delete') &&
463
+ !inputFocus &&
464
+ !this.state.onEditFile
465
+ ) {
451
466
  this.onDel(type)
452
467
  } else if (keyPressed(e, 'enter') && !inputFocus && !onDelete) {
453
- e.stopPropagation()
454
468
  this.enter(type, e)
455
469
  } else if (keyControlPressed(e) && keyPressed(e, 'keyC') && !inputFocus) {
456
- e.stopPropagation()
457
470
  this.doCopy(type, e)
458
471
  } else if (keyControlPressed(e) && keyPressed(e, 'keyX') && !inputFocus) {
459
- e.stopPropagation()
460
472
  this.doCut(type, e)
461
473
  } else if (keyControlPressed(e) && keyPressed(e, 'keyV') && !inputFocus) {
462
- e.stopPropagation()
463
474
  this.doPaste(type, e)
464
475
  } else if (keyPressed(e, 'f5')) {
465
- e.stopPropagation()
466
476
  this.onGoto(type)
467
477
  }
468
478
  }
@@ -496,11 +506,7 @@ export default class Sftp extends Component {
496
506
  }
497
507
 
498
508
  addTransferList = list => {
499
- postMessage({
500
- list,
501
- action: commonActions.addTransfer,
502
- sessionId: this.props.sessionId
503
- })
509
+ window.store.addTransferList(list)
504
510
  }
505
511
 
506
512
  computeListHeight = () => {
@@ -906,11 +912,8 @@ export default class Sftp extends Component {
906
912
  typeMap.remote,
907
913
  'lastClickedFile',
908
914
  'lastMataKey',
909
- 'transferToConfirm',
910
- 'transferList',
911
915
  'targetTransferType',
912
916
  'selectedFiles',
913
- 'pauseAll',
914
917
  'localGidTree',
915
918
  'remoteUidTree',
916
919
  'localUidTree',
@@ -1108,18 +1111,6 @@ export default class Sftp extends Component {
1108
1111
  const {
1109
1112
  id
1110
1113
  } = this.state
1111
- const prps = {
1112
- localList: this.localList,
1113
- remoteList: this.remoteList,
1114
- sftp: this.sftp,
1115
- sessionId: this.props.sessionId,
1116
- host: this.props.tab.host,
1117
- localListDebounce: this.localListDebounce,
1118
- remoteListDebounce: this.remoteListDebounce,
1119
- config: this.props.config,
1120
- tab: this.props.tab,
1121
- pid: this.props.pid
1122
- }
1123
1114
  const all = {
1124
1115
  className: 'sftp-wrap overhide relative',
1125
1116
  id: `id-${id}`,
@@ -1132,7 +1123,6 @@ export default class Sftp extends Component {
1132
1123
  {
1133
1124
  this.renderSections()
1134
1125
  }
1135
- <TransportEntry {...prps} />
1136
1126
  </div>
1137
1127
  )
1138
1128
  }