@electerm/electerm-react 5.3.15 → 5.5.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 (149) hide show
  1. package/README.md +246 -12
  2. package/client/common/choose-save-folder.js +21 -2
  3. package/client/common/constants.js +23 -6
  4. package/client/common/create-title.jsx +6 -0
  5. package/client/common/default-setting.js +14 -0
  6. package/client/common/init-setting-item.js +5 -0
  7. package/client/common/platform.js +24 -0
  8. package/client/components/ai/agent-tool-call-card.jsx +10 -2
  9. package/client/components/ai/agent.js +4 -1
  10. package/client/components/ai/ai-attachments.js +87 -0
  11. package/client/components/ai/ai-chat-empty.jsx +43 -0
  12. package/client/components/ai/ai-chat-entry.jsx +13 -4
  13. package/client/components/ai/ai-chat-history-item.jsx +28 -4
  14. package/client/components/ai/ai-chat-history.jsx +2 -1
  15. package/client/components/ai/ai-chat.jsx +104 -13
  16. package/client/components/ai/ai-config-props.js +4 -130
  17. package/client/components/ai/ai-config.jsx +135 -15
  18. package/client/components/ai/ai-presets.js +173 -0
  19. package/client/components/ai/ai.styl +83 -0
  20. package/client/components/bg/css-overwrite.jsx +11 -0
  21. package/client/components/bookmark-form/bookmark-schema.js +4 -0
  22. package/client/components/bookmark-form/common/fields.jsx +3 -0
  23. package/client/components/bookmark-form/config/common-fields.js +12 -0
  24. package/client/components/bookmark-form/config/local.js +3 -2
  25. package/client/components/bookmark-form/config/serial.js +3 -2
  26. package/client/components/bookmark-form/config/ssh.js +2 -1
  27. package/client/components/bookmark-form/config/telnet.js +3 -2
  28. package/client/components/bookmark-form/index.jsx +10 -8
  29. package/client/components/common/item-filter.jsx +76 -0
  30. package/client/components/common/item-filter.styl +54 -0
  31. package/client/components/common/lazy-boundary.jsx +34 -0
  32. package/client/components/common/opacity.jsx +3 -1
  33. package/client/components/footer/footer-entry.jsx +35 -5
  34. package/client/components/footer/footer.styl +8 -1
  35. package/client/components/layout/layout.jsx +23 -31
  36. package/client/components/layout/pixed.js +3 -0
  37. package/client/components/main/main.jsx +80 -28
  38. package/client/components/main/term-fullscreen.styl +9 -3
  39. package/client/components/quick-commands/qm.styl +3 -2
  40. package/client/components/rdp/file-transfer.js +4 -4
  41. package/client/components/remote-monitor/monitor-details.jsx +458 -0
  42. package/client/components/remote-monitor/monitor-details.styl +87 -0
  43. package/client/components/remote-monitor/monitor-model.js +764 -0
  44. package/client/components/remote-monitor/remote-monitor-bar-entry.jsx +18 -0
  45. package/client/components/remote-monitor/remote-monitor-bar.jsx +344 -0
  46. package/client/components/remote-monitor/remote-monitor-bar.styl +106 -0
  47. package/client/components/remote-monitor/session-monitor.js +361 -0
  48. package/client/components/remote-monitor/use-monitor-details.js +10 -0
  49. package/client/components/remote-monitor/visibility.js +18 -0
  50. package/client/components/session/session-control.jsx +29 -2
  51. package/client/components/session/session.jsx +40 -18
  52. package/client/components/session/sessions.jsx +5 -2
  53. package/client/components/setting-panel/col.jsx +32 -6
  54. package/client/components/setting-panel/list.styl +12 -0
  55. package/client/components/setting-panel/setting-common.jsx +25 -56
  56. package/client/components/setting-panel/setting-mobile-breadcrumb.jsx +29 -0
  57. package/client/components/setting-panel/setting-modal.jsx +64 -44
  58. package/client/components/setting-panel/setting-terminal.jsx +7 -2
  59. package/client/components/setting-panel/setting-wrap.jsx +0 -3
  60. package/client/components/setting-panel/setting-wrap.styl +80 -11
  61. package/client/components/setting-panel/setting.styl +1 -1
  62. package/client/components/setting-panel/tab-triggers.jsx +71 -0
  63. package/client/components/sftp/file-compare-modal.jsx +6 -3
  64. package/client/components/sftp/file-item.jsx +5 -3
  65. package/client/components/sftp/owner-list.js +11 -2
  66. package/client/components/side-panel-r/side-panel-r.jsx +2 -2
  67. package/client/components/sidebar/index.jsx +28 -21
  68. package/client/components/sidebar/left-sidebar-icons.jsx +1 -1
  69. package/client/components/sidebar/sidebar.styl +16 -0
  70. package/client/components/sys-menu/menu-btn.jsx +30 -1
  71. package/client/components/tabs/index.jsx +2 -2
  72. package/client/components/tabs/tab-title.jsx +3 -2
  73. package/client/components/tabs/tab.jsx +5 -1
  74. package/client/components/tabs/tabs.styl +4 -0
  75. package/client/components/terminal/attach-addon-custom.js +295 -49
  76. package/client/components/terminal/automation/index.js +64 -0
  77. package/client/components/terminal/automation/keys.js +49 -0
  78. package/client/components/terminal/automation/stream-matcher.js +82 -0
  79. package/client/components/terminal/automation/strip-ansi.js +19 -0
  80. package/client/components/terminal/automation/trigger-engine.js +233 -0
  81. package/client/components/terminal/automation/trigger-presets.js +110 -0
  82. package/client/components/terminal/command-tracker-addon.js +31 -1
  83. package/client/components/terminal/mixins/index.js +27 -0
  84. package/client/components/terminal/mixins/term-attach.js +123 -0
  85. package/client/components/terminal/mixins/term-config.jsx +84 -0
  86. package/client/components/terminal/mixins/term-content.js +88 -0
  87. package/client/components/terminal/mixins/term-context-menu.jsx +291 -0
  88. package/client/components/terminal/mixins/term-file-drop.js +149 -0
  89. package/client/components/terminal/mixins/term-init.js +122 -0
  90. package/client/components/terminal/mixins/term-log.jsx +96 -0
  91. package/client/components/terminal/mixins/term-resize.js +87 -0
  92. package/client/components/terminal/mixins/term-socket.js +433 -0
  93. package/client/components/terminal/mixins/term-suggestions.js +224 -0
  94. package/client/components/terminal/mixins/term-theme.js +190 -0
  95. package/client/components/terminal/mixins/term-touch.js +136 -0
  96. package/client/components/terminal/shell-detect.js +37 -0
  97. package/client/components/terminal/shell.js +0 -28
  98. package/client/components/terminal/shortcut-bar-entry.jsx +32 -27
  99. package/client/components/terminal/shortcut-bar.jsx +4 -6
  100. package/client/components/terminal/shortcut-bar.styl +4 -0
  101. package/client/components/terminal/ssh-reload-state.js +56 -0
  102. package/client/components/terminal/startup-queue.js +379 -0
  103. package/client/components/terminal/terminal-interactive.jsx +32 -0
  104. package/client/components/terminal/terminal.jsx +102 -2007
  105. package/client/components/terminal/transfer-client-base.js +5 -29
  106. package/client/components/terminal/trzsz-client.js +1 -3
  107. package/client/components/terminal/xmodem-client.js +1 -3
  108. package/client/components/terminal/xterm-loader.js +7 -0
  109. package/client/components/terminal/zmodem-client.js +1 -3
  110. package/client/components/terminal-info/base.jsx +18 -70
  111. package/client/components/terminal-info/terminal-info-entry.jsx +13 -5
  112. package/client/components/terminal-info/terminal-info.jsx +50 -59
  113. package/client/components/terminal-info/terminal-info.styl +6 -49
  114. package/client/components/text-editor/open-text-editor.js +30 -0
  115. package/client/components/text-editor/text-editor-entry.jsx +17 -6
  116. package/client/components/text-editor/text-editor.jsx +14 -0
  117. package/client/components/theme/theme-form.jsx +22 -0
  118. package/client/components/tree-list/bookmark-transport.jsx +7 -31
  119. package/client/components/tree-list/tree-list.styl +13 -0
  120. package/client/components/triggers/trigger-editor.jsx +246 -0
  121. package/client/components/triggers/trigger-form.jsx +200 -0
  122. package/client/components/triggers/trigger-session-modal.jsx +199 -0
  123. package/client/components/triggers/trigger-setting-list.jsx +89 -0
  124. package/client/components/triggers/trigger-transport.jsx +60 -0
  125. package/client/components/triggers/triggers-field.jsx +19 -0
  126. package/client/components/widgets/widgets-list.jsx +11 -1
  127. package/client/css/mobile.styl +9 -1
  128. package/client/store/common.js +12 -1
  129. package/client/store/init-state.js +14 -0
  130. package/client/store/mcp-handler.js +158 -30
  131. package/client/store/setting.js +20 -0
  132. package/client/store/sidebar.js +12 -0
  133. package/client/store/store.js +2 -0
  134. package/client/store/sync.js +45 -9
  135. package/client/store/system-menu.js +2 -0
  136. package/client/store/tab.js +41 -3
  137. package/client/store/trigger.js +118 -0
  138. package/client/store/watch.js +13 -5
  139. package/client/views/index.pug +3 -0
  140. package/package.json +1 -1
  141. package/client/components/terminal-info/activity.jsx +0 -57
  142. package/client/components/terminal-info/data-cols-parser.jsx +0 -54
  143. package/client/components/terminal-info/disk.jsx +0 -45
  144. package/client/components/terminal-info/format-disks.js +0 -45
  145. package/client/components/terminal-info/network.jsx +0 -121
  146. package/client/components/terminal-info/resource.jsx +0 -99
  147. package/client/components/terminal-info/run-cmd.jsx +0 -263
  148. package/client/components/terminal-info/sys-info.jsx +0 -56
  149. package/client/components/terminal-info/up.jsx +0 -17
@@ -1,3 +1,4 @@
1
+ import { useEffect } from 'react'
1
2
  import {
2
3
  InfoCircleOutlined,
3
4
  UpCircleOutlined,
@@ -48,37 +49,43 @@ export default function Sidebar (props) {
48
49
  const { store } = window
49
50
 
50
51
  const handleClickOutside = (event) => {
51
- // Don't close if pinned or has active input
52
- if (store.pinned || hasActiveInput()) {
52
+ const { store } = window
53
+ // Nothing to dismiss when the panel is closed or pinned; also ignore
54
+ // clicks while typing in an input so the panel is not yanked away
55
+ // mid-interaction.
56
+ if (!store.openedSideBar || store.pinned || hasActiveInput()) {
53
57
  return
54
58
  }
59
+ const target = event.target
60
+ // Never treat the panel itself or the bookmark toggle button as "outside".
61
+ // The very click that toggles the panel open lands on that button, so this
62
+ // guard makes the toggle immune to event-ordering races — and, in dev hot
63
+ // reloads, to stale listeners left behind by an older build.
64
+ if (target.closest && (
65
+ target.closest('.sidebar-panel') ||
66
+ target.closest('.bookmark-sidebar-toggle')
67
+ )) {
68
+ return
69
+ }
70
+ store.setOpenedSideBar('')
71
+ }
55
72
 
56
- // Check if click is outside the sidebar panel
57
- const sidebarPanel = document.querySelector('.sidebar-panel')
58
- if (sidebarPanel && !sidebarPanel.contains(event.target)) {
59
- store.setOpenedSideBar('')
73
+ // One always-on document listener for click-outside dismissal, attached
74
+ // once. Previously the listener was added/removed from inside the bookmark
75
+ // click handler, so it leaked when the panel was closed via the ✕ icon and
76
+ // then instantly re-closed the panel on the next bookmark-icon click.
77
+ useEffect(() => {
78
+ document.addEventListener('click', handleClickOutside)
79
+ return () => {
60
80
  document.removeEventListener('click', handleClickOutside)
61
81
  }
62
- }
82
+ }, [])
63
83
 
64
84
  const handleClickBookmark = () => {
65
85
  if (showModal) {
66
86
  store.showModal = 0
67
87
  }
68
- if (pinned) {
69
- return
70
- }
71
- if (openedSideBar === 'bookmarks') {
72
- // Remove listener when closing
73
- document.removeEventListener('click', handleClickOutside)
74
- store.setOpenedSideBar('')
75
- } else {
76
- // Add listener when opening, with slight delay to avoid conflict with this click
77
- setTimeout(() => {
78
- document.addEventListener('click', handleClickOutside)
79
- }, 0)
80
- store.setOpenedSideBar('bookmarks')
81
- }
88
+ store.openLeftSidePanel()
82
89
  }
83
90
 
84
91
  const handleShowUpgrade = () => {
@@ -81,7 +81,7 @@ export default function LeftSidebarIcons (props) {
81
81
  >
82
82
  <BookOutlined
83
83
  onClick={handleClickBookmark}
84
- className='font20 iblock control-icon'
84
+ className='font20 iblock control-icon bookmark-sidebar-toggle'
85
85
  />
86
86
  </SideIcon>
87
87
  ),
@@ -23,6 +23,8 @@
23
23
  z-index 100
24
24
  bottom 0
25
25
  background var(--main-dark)
26
+ display flex
27
+ flex-direction column
26
28
 
27
29
  .item-list
28
30
  padding-right 0
@@ -105,6 +107,20 @@
105
107
  z-index 200
106
108
  width 0
107
109
 
110
+ // icon bar: fills sidebar height, scrolls when overflow on small screens,
111
+ // scrollbar hidden but scrolling still works
112
+ .sidebar-bar
113
+ flex 1
114
+ min-height 0
115
+ overflow-y auto
116
+ overflow-x hidden
117
+ scrollbar-width none // Firefox
118
+ -ms-overflow-style none // IE/Edge
119
+ &::-webkit-scrollbar
120
+ width 0
121
+ height 0
122
+ display none
123
+
108
124
  // mobile: icon bar hidden — hide its buttons
109
125
  .sidebar.collapsed
110
126
  .sidebar-bar
@@ -65,6 +65,7 @@ class MenuBtn extends PureComponent {
65
65
  renderContext = () => {
66
66
  const items = [
67
67
  {
68
+ key: 'onNewSsh',
68
69
  func: 'onNewSsh',
69
70
  icon: 'CodeFilled',
70
71
  text: e('newBookmark'),
@@ -73,6 +74,7 @@ class MenuBtn extends PureComponent {
73
74
  ]
74
75
  if (window.store.hasNodePty) {
75
76
  items.push({
77
+ key: 'addTab',
76
78
  func: 'addTab',
77
79
  icon: 'RightSquareFilled',
78
80
  text: e('newTab'),
@@ -83,6 +85,7 @@ class MenuBtn extends PureComponent {
83
85
  // type: 'hr'
84
86
  // },
85
87
  items.push({
88
+ key: 'bookmarks',
86
89
  noCloseMenu: true,
87
90
  icon: 'BookOutlined',
88
91
  text: e('bookmarks'),
@@ -90,18 +93,21 @@ class MenuBtn extends PureComponent {
90
93
  })
91
94
  items.push(
92
95
  {
96
+ key: 'history',
93
97
  noCloseMenu: true,
94
98
  icon: 'ClockCircleOutlined',
95
99
  text: e('history'),
96
100
  submenu: 'History'
97
101
  },
98
102
  {
103
+ key: 'sessions',
99
104
  noCloseMenu: true,
100
105
  icon: 'BarsOutlined',
101
106
  text: e('sessions'),
102
107
  submenu: 'Tabs'
103
108
  },
104
109
  {
110
+ key: 'layout',
105
111
  icon: 'AppstoreOutlined',
106
112
  text: e('layout'),
107
113
  submenu: 'Layout'
@@ -110,16 +116,19 @@ class MenuBtn extends PureComponent {
110
116
  // type: 'hr'
111
117
  // },
112
118
  {
119
+ key: 'openAbout',
113
120
  func: 'openAbout',
114
121
  icon: 'InfoCircleOutlined',
115
122
  text: e('about')
116
123
  },
117
124
  {
125
+ key: 'openSetting',
118
126
  func: 'openSetting',
119
127
  icon: 'SettingOutlined',
120
128
  text: e('settings')
121
129
  },
122
130
  {
131
+ key: 'openDevTools',
123
132
  func: 'openDevTools',
124
133
  icon: 'LeftSquareFilled',
125
134
  text: e('toggledevtools')
@@ -128,19 +137,23 @@ class MenuBtn extends PureComponent {
128
137
  // type: 'hr'
129
138
  // },
130
139
  {
140
+ key: 'zoom',
131
141
  module: 'Zoom'
132
142
  },
133
143
  {
144
+ key: 'minimize',
134
145
  func: 'minimize',
135
146
  icon: 'SwitcherFilled',
136
147
  text: e('minimize')
137
148
  },
138
149
  {
150
+ key: 'maximize',
139
151
  func: 'maximize',
140
152
  icon: 'LayoutFilled',
141
153
  text: e('maximize')
142
154
  },
143
155
  {
156
+ key: 'reload',
144
157
  func: 'reload',
145
158
  icon: 'ReloadOutlined',
146
159
  text: e('reload')
@@ -149,6 +162,7 @@ class MenuBtn extends PureComponent {
149
162
  // type: 'hr'
150
163
  // },
151
164
  {
165
+ key: 'onCheckUpdate',
152
166
  func: 'onCheckUpdate',
153
167
  icon: 'UpCircleOutlined',
154
168
  text: e('checkForUpdate')
@@ -157,17 +171,32 @@ class MenuBtn extends PureComponent {
157
171
  // type: 'hr'
158
172
  // },
159
173
  {
174
+ key: 'restart',
160
175
  func: 'restart',
161
176
  icon: 'RedoOutlined',
162
177
  text: e('restart')
163
178
  },
164
179
  {
180
+ key: 'close',
165
181
  func: 'close',
166
182
  icon: 'CloseOutlined',
167
183
  text: e('close')
168
184
  }
169
185
  )
170
- return items
186
+ return this.filterMenus(items)
187
+ }
188
+
189
+ // Only show menus listed in window.et.sysMenus, when it is defined,
190
+ // eg: window.et.sysMenus = ['onNewSsh', 'bookmarks', 'openSetting', 'close']
191
+ // available keys: onNewSsh, addTab, bookmarks, history, sessions, layout,
192
+ // openAbout, openSetting, openDevTools, zoom, minimize, maximize, reload,
193
+ // onCheckUpdate, restart, close
194
+ filterMenus = (items) => {
195
+ const { sysMenus } = window.et || {}
196
+ if (!Array.isArray(sysMenus)) {
197
+ return items
198
+ }
199
+ return items.filter(d => d.type === 'hr' || sysMenus.includes(d.key))
171
200
  }
172
201
 
173
202
  renderMenu () {
@@ -225,7 +225,7 @@ export default class Tabs extends Component {
225
225
  return {
226
226
  key: i + '##' + t.id,
227
227
  label: (
228
- <span><TabTitle tab={t} /></span>
228
+ <span><TabTitle tab={t} config={this.props.config} /></span>
229
229
  ),
230
230
  onClick: () => this.handleClickMenu({ key: i + '##' + t.id })
231
231
  }
@@ -423,7 +423,7 @@ export default class Tabs extends Component {
423
423
  return {
424
424
  key: i + '##' + t.id,
425
425
  label: (
426
- <span><TabTitle tab={t} /></span>
426
+ <span><TabTitle tab={t} config={this.props.config} /></span>
427
427
  ),
428
428
  onClick: () => this.handleClickMenu({ key: i + '##' + t.id })
429
429
  }
@@ -1,7 +1,7 @@
1
1
  import createName from '../../common/create-title'
2
2
 
3
3
  export default function tabTitle (props) {
4
- const { tab } = props
4
+ const { tab, config } = props
5
5
  const title = createName(tab)
6
6
  const { tabCount, color } = props.tab
7
7
  const styleTag = color
@@ -9,7 +9,8 @@ export default function tabTitle (props) {
9
9
  : {}
10
10
  return (
11
11
  <span className='tab-title'>
12
- <span style={styleTag}>●</span> {tabCount}. {title}
12
+ <span style={styleTag}>●</span>
13
+ {!(config && config.disableTabIndex) ? ` ${tabCount}.` : ''} {title}
13
14
  </span>
14
15
  )
15
16
  }
@@ -561,7 +561,11 @@ class Tab extends Component {
561
561
  )
562
562
  }
563
563
  <span className='tab-title'>
564
- <span className='iblock mg1r tab-count' style={styleTag}>{tabCount}</span>
564
+ {!(config && config.disableTabIndex)
565
+ ? (
566
+ <span className='iblock mg1r tab-count' style={styleTag}>{tabCount}</span>
567
+ )
568
+ : null}
565
569
  {tab.isPinned && <PushpinFilled className='tab-pin' />}
566
570
  <span className='mg1r'>{title}</span>
567
571
  </span>
@@ -135,6 +135,10 @@
135
135
  font-size 10px
136
136
  &:hover
137
137
  background var(--error)
138
+ // touch screens have no hover — always reveal the close icon
139
+ .is-touch-device
140
+ .tab-close
141
+ display block
138
142
 
139
143
  .tabs-add-btn
140
144
  display inline-block