@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
@@ -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, sessionId, cmd)
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, sessionId, cmd)
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 { Tooltip, Tag } from 'antd'
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'
@@ -29,38 +29,21 @@ export default function ThemeListItem (props) {
29
29
  store.setTheme(item.id)
30
30
  }
31
31
 
32
- function renderPreview () {
33
- const {
34
- main,
35
- text
36
- } = item.uiThemeConfig
37
- const arr = [
38
- 'error',
39
- 'success',
40
- 'warn',
41
- 'info',
42
- 'primary'
43
- ]
44
- return (
45
- <div
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
- )
32
+ function handleMouseEnter () {
33
+ if (!item.id) return
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
- <Tooltip
72
- title={renderPreview()}
73
- placement='topLeft'
74
- >
75
- <CheckCircleOutlined
76
- className='pointer list-item-apply'
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
 
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  BookOutlined,
3
3
  FolderOutlined,
4
- UploadOutlined,
5
- DownloadOutlined,
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 beforeUpload = action(async (file) => {
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
- // Using Map instead of reduce
43
- const bmTree = new Map(
44
- bookmarks0.map(bookmark => [bookmark.id, bookmark])
45
- )
46
- const bmgTree = new Map(
47
- bookmarkGroups0.map(group => [group.id, group])
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
- const fixed = fixBookmarks(bookmarks1)
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
- fixed.forEach(bg => {
53
- if (!bmTree.has(bg.id)) {
54
- store.bookmarks.push(bg)
55
- }
56
- })
51
+ const fixed = fixBookmarks(bookmarks1)
57
52
 
58
- bookmarkGroups1.forEach(bg => {
59
- if (!bmgTree.has(bg.id)) {
60
- store.bookmarkGroups.push(bg)
61
- } else {
62
- const bg1 = store.bookmarkGroups.find(
63
- b => b.id === bg.id
64
- )
65
- bg1.bookmarkIds = uniq(
66
- [
67
- ...bg1.bookmarkIds,
68
- ...bg.bookmarkIds
69
- ]
70
- )
71
- }
72
- })
73
- } catch (e) {
74
- store.onError(e)
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: <UploadOutlined />
123
+ icon: <ImportOutlined />
112
124
  },
113
125
  {
114
126
  label: e('export'),
115
127
  onClick: onExport,
116
- icon: <DownloadOutlined />
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={<DownloadOutlined />}
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={<UploadOutlined />}
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 { sessionId, id } = this.props
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}?sessionId=${sessionId}&token=${tokenElecterm}&width=${width}&height=${height}`
113
+ const wsUrl = `${pre}://${hs}/vnc/${pid}?token=${tokenElecterm}&width=${width}&height=${height}`
115
114
  const vncOpts = {
116
115
  scaleViewport,
117
116
  viewOnly,
@@ -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}?sessionId=${sessionId}&sftpId=${sftpId}&token=${tokenElecterm}`
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 {
@@ -511,7 +511,9 @@ export default Store => {
511
511
 
512
512
  Store.prototype.updateBatchInputSelectedTabIds = function () {
513
513
  const { store } = window
514
- store._batchInputSelectedTabIds = new Set([store.activeTabId])
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 (sessionId) {
569
- const sftp = refs.get('sftp-' + sessionId)
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 (sessionId) {
576
- const sftp = refs.get('sftp-' + sessionId)
577
+ Store.prototype.localList = function (tabId) {
578
+ const sftp = refs.get('sftp-' + tabId)
577
579
  if (sftp) {
578
580
  sftp.localListDebounce()
579
581
  }
@@ -38,7 +38,7 @@ export default Store => {
38
38
  }
39
39
 
40
40
  Store.prototype.sortTheme = function (a, b) {
41
- const { theme } = window.store.config
41
+ const theme = window.originalTheme || window.store.config.theme
42
42
  const ax = a.id === theme ? -1 : 1
43
43
  const bx = b.id === theme ? -1 : 1
44
44
  return ax - bx
@@ -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
- }).start()
73
+ })
74
+ window[`watch${name}`].start()
74
75
  }
75
76
 
76
77
  autoRun(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.80.18",
3
+ "version": "1.90.6",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",