@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.
- package/client/common/create-title.jsx +1 -1
- package/client/components/ai/ai-output.jsx +19 -1
- package/client/components/bookmark-form/config/common-fields.js +2 -1
- package/client/components/bookmark-form/config/serial.js +1 -0
- package/client/components/sys-menu/menu-btn.jsx +19 -14
- package/client/components/tabs/index.jsx +15 -6
- package/client/components/tabs/no-session.jsx +7 -2
- package/client/components/tabs/tab.jsx +5 -1
- package/client/store/db-upgrade.js +41 -17
- package/client/store/init-state.js +1 -0
- package/client/store/tab.js +10 -0
- package/client/store/watch.js +5 -1
- package/package.json +1 -1
|
@@ -35,7 +35,25 @@ export default function AIOutput ({ item }) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const runInTerminal = () => {
|
|
38
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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'
|
|
@@ -12,31 +12,55 @@ export default (Store) => {
|
|
|
12
12
|
return false
|
|
13
13
|
}
|
|
14
14
|
const shouldUpgrade = await window.pre.runGlobalAsync('checkDbUpgrade')
|
|
15
|
-
|
|
15
|
+
const shouldMigrate = await window.pre.runGlobalAsync('checkMigrate')
|
|
16
|
+
if (!shouldUpgrade && !shouldMigrate) {
|
|
17
|
+
window.migrating = false
|
|
16
18
|
return false
|
|
17
19
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
package/client/store/tab.js
CHANGED
|
@@ -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()
|
package/client/store/watch.js
CHANGED
|
@@ -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
|
-
|
|
64
|
+
newOrder
|
|
61
65
|
)
|
|
62
66
|
refsStatic.add('oldState-' + name, deepCopy(n) || [])
|
|
63
67
|
if (name === 'bookmarks') {
|