@electerm/electerm-react 1.101.16 → 2.1.8

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.
@@ -42,7 +42,7 @@ export default function createTitle (res, hide = true) {
42
42
  ) {
43
43
  f = `[T]${f}`
44
44
  }
45
- if (type) {
45
+ if (type && type !== 'ssh') {
46
46
  f = `[${type}]${f}`
47
47
  }
48
48
  return f || e(terminalLocalType)
@@ -35,7 +35,25 @@ export default function AIOutput ({ item }) {
35
35
  }
36
36
 
37
37
  const runInTerminal = () => {
38
- window.store.runCommandInTerminal(code)
38
+ // Filter out comments from the code before running
39
+ const filteredCode = code
40
+ .split('\n')
41
+ .map(line => line.trim())
42
+ .filter(line => {
43
+ // Remove empty lines and comments
44
+ if (!line) {
45
+ return false
46
+ }
47
+ if (line.startsWith('#')) {
48
+ return false
49
+ }
50
+ return true
51
+ })
52
+ .join('\n') // Join multiple commands with &&
53
+
54
+ if (filteredCode) {
55
+ window.store.runCommandInTerminal(filteredCode)
56
+ }
39
57
  }
40
58
 
41
59
  return (
@@ -270,12 +270,13 @@ export const sshAuthFields = [
270
270
  // Telnet auth fields - similar to SSH but with filtered auth types (no privateKey)
271
271
  export const telnetAuthFields = [
272
272
  commonFields.category,
273
+ commonFields.title,
273
274
  commonFields.host,
274
275
  commonFields.username,
275
276
  commonFields.password,
276
277
  { type: 'profileItem', name: '__profile__', label: '', profileFilter: d => !isEmpty(d.telnet) },
277
278
  commonFields.port,
278
- commonFields.title,
279
+ commonFields.runScripts,
279
280
  commonFields.description,
280
281
  commonFields.setEnv,
281
282
  commonFields.startDirectoryLocal,
@@ -45,6 +45,7 @@ const serialConfig = {
45
45
  { type: 'switch', name: 'xon', label: 'xon', valuePropName: 'checked' },
46
46
  { type: 'switch', name: 'xoff', label: 'xoff', valuePropName: 'checked' },
47
47
  { type: 'switch', name: 'xany', label: 'xany', valuePropName: 'checked' },
48
+ commonFields.runScripts,
48
49
  commonFields.description,
49
50
  { type: 'input', name: 'type', label: 'type', hidden: true }
50
51
  ]
@@ -64,27 +64,31 @@ class MenuBtn extends PureComponent {
64
64
  }
65
65
 
66
66
  renderContext = () => {
67
- return [
67
+ const items = [
68
68
  {
69
69
  func: 'onNewSsh',
70
70
  icon: 'CodeFilled',
71
71
  text: e('newBookmark'),
72
72
  subText: this.getShortcut('app_newBookmark')
73
- },
74
- {
73
+ }
74
+ ]
75
+ if (window.store.hasNodePty) {
76
+ items.push({
75
77
  func: 'addTab',
76
78
  icon: 'RightSquareFilled',
77
79
  text: e('newTab')
78
- },
79
- // {
80
- // type: 'hr'
81
- // },
82
- {
83
- noCloseMenu: true,
84
- icon: 'BookOutlined',
85
- text: e('bookmarks'),
86
- submenu: 'Bookmark'
87
- },
80
+ })
81
+ }
82
+ // {
83
+ // type: 'hr'
84
+ // },
85
+ items.push({
86
+ noCloseMenu: true,
87
+ icon: 'BookOutlined',
88
+ text: e('bookmarks'),
89
+ submenu: 'Bookmark'
90
+ })
91
+ items.push(
88
92
  {
89
93
  noCloseMenu: true,
90
94
  icon: 'ClockCircleOutlined',
@@ -162,7 +166,8 @@ class MenuBtn extends PureComponent {
162
166
  icon: 'CloseOutlined',
163
167
  text: e('close')
164
168
  }
165
- ]
169
+ )
170
+ return items
166
171
  }
167
172
 
168
173
  renderMenu () {
@@ -124,6 +124,10 @@ export default class Tabs extends Component {
124
124
  }
125
125
 
126
126
  handleTabAdd = () => {
127
+ if (!window.store.hasNodePty) {
128
+ window.store.onNewSsh()
129
+ return
130
+ }
127
131
  window.store.addTab(
128
132
  undefined, undefined,
129
133
  this.props.batch
@@ -195,6 +199,16 @@ export default class Tabs extends Component {
195
199
  renderMenus () {
196
200
  const { onNewSsh } = window.store
197
201
  const cls = 'pd2x pd1y context-item pointer'
202
+ const addTabBtn = window.store.hasNodePty
203
+ ? (
204
+ <div
205
+ className={cls}
206
+ onClick={this.handleTabAdd}
207
+ >
208
+ <RightSquareFilled /> {e('newTab')}
209
+ </div>
210
+ )
211
+ : null
198
212
  return (
199
213
  <div
200
214
  className='add-menu-wrap' style={{
@@ -207,12 +221,7 @@ export default class Tabs extends Component {
207
221
  >
208
222
  <CodeFilled /> {e('newBookmark')}
209
223
  </div>
210
- <div
211
- className={cls}
212
- onClick={this.handleTabAdd}
213
- >
214
- <RightSquareFilled /> {e('newTab')}
215
- </div>
224
+ {addTabBtn}
216
225
  <BookmarksList
217
226
  store={window.store}
218
227
  />
@@ -13,8 +13,8 @@ export default function NoSessionPanel ({ height, onNewTab, onNewSsh, batch }) {
13
13
  const handleClick = () => {
14
14
  window.openTabBatch = batch
15
15
  }
16
- return (
17
- <div className='no-sessions electerm-logo-bg' {...props}>
16
+ const newTabDom = window.store.hasNodePty
17
+ ? (
18
18
  <Button
19
19
  onClick={onNewTab}
20
20
  size='large'
@@ -22,6 +22,11 @@ export default function NoSessionPanel ({ height, onNewTab, onNewSsh, batch }) {
22
22
  >
23
23
  {e('newTab')}
24
24
  </Button>
25
+ )
26
+ : null
27
+ return (
28
+ <div className='no-sessions electerm-logo-bg' {...props}>
29
+ {newTabDom}
25
30
  <Button
26
31
  onClick={onNewSsh}
27
32
  size='large'
@@ -220,7 +220,11 @@ class Tab extends Component {
220
220
  }
221
221
 
222
222
  newTab = () => {
223
- this.props.addTab()
223
+ if (window.store.hasNodePty) {
224
+ this.props.addTab()
225
+ } else {
226
+ window.store.onNewSsh()
227
+ }
224
228
  }
225
229
 
226
230
  doRename = () => {
@@ -12,31 +12,55 @@ export default (Store) => {
12
12
  return false
13
13
  }
14
14
  const shouldUpgrade = await window.pre.runGlobalAsync('checkDbUpgrade')
15
- if (!shouldUpgrade) {
15
+ const shouldMigrate = await window.pre.runGlobalAsync('checkMigrate')
16
+ if (!shouldUpgrade && !shouldMigrate) {
17
+ window.migrating = false
16
18
  return false
17
19
  }
18
- const {
19
- dbVersion,
20
- packVersion
21
- } = shouldUpgrade
22
- const mod = Modal.info({
23
- title: 'Upgrading database',
24
- content: `Upgrading database... from v${dbVersion} to v${packVersion} please wait`,
20
+ window.migrating = true
21
+ let mod
22
+ const commonProps = {
25
23
  keyboard: false,
26
24
  okButtonProps: {
27
25
  style: {
28
26
  display: 'none'
29
27
  }
30
28
  }
31
- })
32
- await window.pre.runGlobalAsync('doUpgrade')
33
- mod.update({
34
- title: 'Done',
35
- content: 'Database Upgraded',
36
- okButtonProps: {}
37
- })
38
- await delay(2000)
39
- mod.destroy()
29
+ }
30
+ if (shouldMigrate) {
31
+ mod = Modal.info({
32
+ title: 'Migrating database',
33
+ content: 'Migrating database... please wait',
34
+ ...commonProps
35
+ })
36
+ await window.pre.runGlobalAsync('migrate')
37
+ mod.update({
38
+ title: 'Done',
39
+ content: 'Database Migrated',
40
+ okButtonProps: {}
41
+ })
42
+ await delay(2000)
43
+ mod.destroy()
44
+ }
45
+ if (shouldUpgrade) {
46
+ const {
47
+ dbVersion,
48
+ packVersion
49
+ } = shouldUpgrade
50
+ mod = Modal.info({
51
+ title: 'Upgrading database',
52
+ content: `Upgrading database... from v${dbVersion} to v${packVersion} please wait`,
53
+ ...commonProps
54
+ })
55
+ await window.pre.runGlobalAsync('doUpgrade')
56
+ mod.update({
57
+ title: 'Done',
58
+ content: 'Database Upgraded',
59
+ okButtonProps: {}
60
+ })
61
+ await delay(2000)
62
+ mod.destroy()
63
+ }
40
64
  await store.restart()
41
65
  return true
42
66
  }
@@ -188,6 +188,7 @@ export default () => {
188
188
  innerWidth: window.innerWidth,
189
189
  height: 500,
190
190
  isMaximized: window.pre.runSync('isMaximized'),
191
+ hasNodePty: window.pre.runSync('nodePtyCheck'),
191
192
  terminalFullScreen: false,
192
193
  hideDelKeyTip: ls.getItem(dismissDelKeyTipLsKey) === 'y',
193
194
  tabsHeight: 36
@@ -10,6 +10,7 @@ import {
10
10
  maxHistory
11
11
  } from '../common/constants'
12
12
  import { refs } from '../components/common/ref'
13
+ import { message } from 'antd'
13
14
  import * as ls from '../common/safe-local-storage'
14
15
  import deepCopy from 'json-deep-copy'
15
16
  import generate from '../common/id-with-stamp'
@@ -312,6 +313,15 @@ export default Store => {
312
313
  index,
313
314
  batch
314
315
  ) {
316
+ if (
317
+ (!newTab.type || newTab.type === 'local') &&
318
+ !newTab.host &&
319
+ !window.store.hasNodePty
320
+ ) {
321
+ return message.warning(
322
+ 'local terminal is not supported, due to node-pty not working in this build'
323
+ )
324
+ }
315
325
  const { store } = window
316
326
  const { tabs } = store
317
327
  newTab.tabCount = store.nextTabCount()
@@ -40,6 +40,9 @@ export default store => {
40
40
 
41
41
  for (const name of dbNamesForWatch) {
42
42
  window[`watch${name}`] = autoRun(async () => {
43
+ if (window.migrating) {
44
+ return
45
+ }
43
46
  const old = refsStatic.get('oldState-' + name)
44
47
  const n = store.getItems(name)
45
48
  const { updated, added, removed } = dataCompare(
@@ -55,9 +58,10 @@ export default store => {
55
58
  for (const item of added) {
56
59
  await insert(name, item)
57
60
  }
61
+ const newOrder = (n || []).map(d => d.id)
58
62
  await update(
59
63
  `${name}:order`,
60
- (n || []).map(d => d.id)
64
+ newOrder
61
65
  )
62
66
  refsStatic.add('oldState-' + name, deepCopy(n) || [])
63
67
  if (name === 'bookmarks') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.101.16",
3
+ "version": "2.1.8",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",