@electerm/electerm-react 2.8.8 → 2.10.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.
- package/client/common/constants.js +3 -3
- package/client/common/pre.js +1 -120
- package/client/components/bookmark-form/ai-bookmark-form.jsx +324 -0
- package/client/components/bookmark-form/bookmark-form.styl +1 -1
- package/client/components/bookmark-form/bookmark-schema.js +179 -0
- package/client/components/bookmark-form/common/ai-category-select.jsx +32 -0
- package/client/components/bookmark-form/common/category-select.jsx +2 -4
- package/client/components/bookmark-form/common/fields.jsx +0 -10
- package/client/components/bookmark-form/config/rdp.js +0 -1
- package/client/components/bookmark-form/config/session-config.js +3 -1
- package/client/components/bookmark-form/config/spice.js +44 -0
- package/client/components/bookmark-form/config/vnc.js +1 -2
- package/client/components/bookmark-form/fix-bookmark-default.js +134 -0
- package/client/components/bookmark-form/index.jsx +74 -13
- package/client/components/session/session.jsx +13 -3
- package/client/components/setting-panel/keywords-transport.jsx +0 -1
- package/client/components/shortcuts/shortcut-handler.js +11 -5
- package/client/components/sidebar/index.jsx +11 -1
- package/client/components/spice/spice-session.jsx +276 -0
- package/client/components/tabs/add-btn-menu.jsx +9 -2
- package/client/components/terminal/attach-addon-custom.js +20 -76
- package/client/components/terminal/terminal.jsx +34 -28
- package/client/components/terminal/transfer-client-base.js +232 -0
- package/client/components/terminal/trzsz-client.js +306 -0
- package/client/components/terminal/xterm-loader.js +109 -0
- package/client/components/terminal/zmodem-client.js +13 -166
- package/client/components/text-editor/simple-editor.jsx +1 -2
- package/client/entry/electerm.jsx +0 -2
- package/client/store/system-menu.js +10 -0
- package/package.json +1 -1
- package/client/common/trzsz.js +0 -46
- package/client/components/bookmark-form/common/wiki-alert.jsx +0 -9
- package/client/components/terminal/fs.js +0 -59
|
@@ -14,7 +14,7 @@ const e = window.translate
|
|
|
14
14
|
export default function BookmarkCategorySelect ({
|
|
15
15
|
bookmarkGroups = [],
|
|
16
16
|
form,
|
|
17
|
-
formItemLayout,
|
|
17
|
+
formItemLayout = defaultFormItemLayout,
|
|
18
18
|
name = 'category',
|
|
19
19
|
onChange,
|
|
20
20
|
formData = {} // Add formData prop to access bookmark ID
|
|
@@ -67,11 +67,9 @@ export default function BookmarkCategorySelect ({
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const layout = formItemLayout || defaultFormItemLayout
|
|
71
|
-
|
|
72
70
|
return (
|
|
73
71
|
<FormItem
|
|
74
|
-
{...
|
|
72
|
+
{...formItemLayout}
|
|
75
73
|
label={e('bookmarkCategory')}
|
|
76
74
|
name={name}
|
|
77
75
|
>
|
|
@@ -21,12 +21,6 @@ import SshHostSelector from './ssh-host-selector.jsx'
|
|
|
21
21
|
import SshAuthTypeSelector from './ssh-auth-type-selector.jsx'
|
|
22
22
|
import SshAuthSelector from './ssh-auth-selector.jsx'
|
|
23
23
|
import CategorySelect from './category-select.jsx'
|
|
24
|
-
import WikiAlert from './wiki-alert.jsx'
|
|
25
|
-
import {
|
|
26
|
-
rdpWikiLink,
|
|
27
|
-
vncWikiLink
|
|
28
|
-
} from '../../../common/constants.js'
|
|
29
|
-
|
|
30
24
|
const Fragment = React.Fragment
|
|
31
25
|
const FormItem = Form.Item
|
|
32
26
|
|
|
@@ -126,10 +120,6 @@ export function renderFormItem (item, formItemLayout, form, ctxProps, index) {
|
|
|
126
120
|
return <Alert key={name} type='info' {...item.props} />
|
|
127
121
|
case 'warning':
|
|
128
122
|
return <Alert key={name} type='warning' {...item.props} />
|
|
129
|
-
case 'rdpWarning':
|
|
130
|
-
return <WikiAlert key={name} wikiUrl={rdpWikiLink} />
|
|
131
|
-
case 'vncWarning':
|
|
132
|
-
return <WikiAlert key={name} wikiUrl={vncWikiLink} />
|
|
133
123
|
case 'categorySelect':
|
|
134
124
|
return (
|
|
135
125
|
<CategorySelect
|
|
@@ -21,7 +21,6 @@ const rdpConfig = {
|
|
|
21
21
|
key: 'auth',
|
|
22
22
|
label: e('auth'),
|
|
23
23
|
fields: [
|
|
24
|
-
{ type: 'rdpWarning', name: 'rdpWarning' },
|
|
25
24
|
commonFields.category,
|
|
26
25
|
commonFields.colorTitle,
|
|
27
26
|
{ type: 'input', name: 'host', label: () => e('host'), rules: [{ required: true, message: e('host') + ' required' }] },
|
|
@@ -8,6 +8,7 @@ import serial from './serial'
|
|
|
8
8
|
import local from './local'
|
|
9
9
|
import rdp from './rdp'
|
|
10
10
|
import ftp from './ftp'
|
|
11
|
+
import spice from './spice'
|
|
11
12
|
|
|
12
13
|
const sessionConfig = {
|
|
13
14
|
[connectionMap.ssh]: ssh,
|
|
@@ -17,7 +18,8 @@ const sessionConfig = {
|
|
|
17
18
|
[connectionMap.vnc]: vnc,
|
|
18
19
|
[connectionMap.rdp]: rdp,
|
|
19
20
|
[connectionMap.ftp]: ftp,
|
|
20
|
-
[connectionMap.web]: web
|
|
21
|
+
[connectionMap.web]: web,
|
|
22
|
+
[connectionMap.spice]: spice
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export default sessionConfig
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { formItemLayout } from '../../../common/form-layout.js'
|
|
2
|
+
import { terminalSpiceType } from '../../../common/constants.js'
|
|
3
|
+
import { createBaseInitValues, getAuthTypeDefault } from '../common/init-values.js'
|
|
4
|
+
import { isEmpty } from 'lodash-es'
|
|
5
|
+
import { commonFields, connectionHoppingTab } from './common-fields.js'
|
|
6
|
+
|
|
7
|
+
const e = window.translate
|
|
8
|
+
|
|
9
|
+
const spiceConfig = {
|
|
10
|
+
key: 'spice',
|
|
11
|
+
type: terminalSpiceType,
|
|
12
|
+
initValues: (props) => {
|
|
13
|
+
return createBaseInitValues(props, terminalSpiceType, {
|
|
14
|
+
port: 5900,
|
|
15
|
+
viewOnly: false,
|
|
16
|
+
scaleViewport: true,
|
|
17
|
+
connectionHoppings: [],
|
|
18
|
+
...getAuthTypeDefault(props)
|
|
19
|
+
})
|
|
20
|
+
},
|
|
21
|
+
layout: formItemLayout,
|
|
22
|
+
tabs: () => [
|
|
23
|
+
{
|
|
24
|
+
key: 'auth',
|
|
25
|
+
label: e('auth'),
|
|
26
|
+
fields: [
|
|
27
|
+
commonFields.category,
|
|
28
|
+
commonFields.colorTitle,
|
|
29
|
+
{ type: 'input', name: 'host', label: () => e('host'), rules: [{ required: true, message: e('host') + ' required' }] },
|
|
30
|
+
commonFields.port,
|
|
31
|
+
{ type: 'switch', name: 'viewOnly', label: () => e('viewOnly'), valuePropName: 'checked' },
|
|
32
|
+
{ type: 'switch', name: 'scaleViewport', label: () => e('scaleViewport'), valuePropName: 'checked' },
|
|
33
|
+
{ type: 'profileItem', name: '__profile__', label: '', profileFilter: d => !isEmpty(d.spice) },
|
|
34
|
+
commonFields.password,
|
|
35
|
+
commonFields.description,
|
|
36
|
+
commonFields.proxy,
|
|
37
|
+
commonFields.type
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
connectionHoppingTab()
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default spiceConfig
|
|
@@ -13,7 +13,7 @@ const vncConfig = {
|
|
|
13
13
|
return createBaseInitValues(props, terminalVncType, {
|
|
14
14
|
port: 5900,
|
|
15
15
|
viewOnly: false,
|
|
16
|
-
clipViewport:
|
|
16
|
+
clipViewport: false,
|
|
17
17
|
scaleViewport: true,
|
|
18
18
|
qualityLevel: 3, // 0-9, lower = faster performance, default 6
|
|
19
19
|
compressionLevel: 1, // 0-9, lower = faster performance, default 2
|
|
@@ -28,7 +28,6 @@ const vncConfig = {
|
|
|
28
28
|
key: 'auth',
|
|
29
29
|
label: e('auth'),
|
|
30
30
|
fields: [
|
|
31
|
-
{ type: 'vncWarning', name: 'vncWarning' },
|
|
32
31
|
commonFields.category,
|
|
33
32
|
commonFields.colorTitle,
|
|
34
33
|
{ type: 'input', name: 'host', label: () => e('host'), rules: [{ required: true, message: e('host') + ' required' }] },
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import bookmarkSchema from './bookmark-schema.js'
|
|
2
|
+
|
|
3
|
+
const defaultValues = {
|
|
4
|
+
ssh: {
|
|
5
|
+
port: 22,
|
|
6
|
+
enableSsh: true,
|
|
7
|
+
enableSftp: true,
|
|
8
|
+
useSshAgent: true,
|
|
9
|
+
x11: false,
|
|
10
|
+
term: 'xterm-256color',
|
|
11
|
+
displayRaw: false,
|
|
12
|
+
encode: 'utf8',
|
|
13
|
+
envLang: 'en_US.UTF-8'
|
|
14
|
+
},
|
|
15
|
+
telnet: {
|
|
16
|
+
port: 23
|
|
17
|
+
},
|
|
18
|
+
serial: {
|
|
19
|
+
baudRate: 9600,
|
|
20
|
+
dataBits: 8,
|
|
21
|
+
stopBits: 1,
|
|
22
|
+
parity: 'none',
|
|
23
|
+
rtscts: false,
|
|
24
|
+
xon: false,
|
|
25
|
+
xoff: false,
|
|
26
|
+
xany: false
|
|
27
|
+
},
|
|
28
|
+
vnc: {
|
|
29
|
+
port: 5900,
|
|
30
|
+
viewOnly: false,
|
|
31
|
+
clipViewport: false,
|
|
32
|
+
scaleViewport: true,
|
|
33
|
+
qualityLevel: 3,
|
|
34
|
+
compressionLevel: 1,
|
|
35
|
+
shared: true
|
|
36
|
+
},
|
|
37
|
+
rdp: {
|
|
38
|
+
port: 3389
|
|
39
|
+
},
|
|
40
|
+
ftp: {
|
|
41
|
+
port: 21,
|
|
42
|
+
secure: false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const requiredFields = {
|
|
47
|
+
ssh: ['host', 'username', 'term'],
|
|
48
|
+
telnet: ['host'],
|
|
49
|
+
serial: ['path'],
|
|
50
|
+
vnc: ['host'],
|
|
51
|
+
rdp: ['host'],
|
|
52
|
+
ftp: ['host'],
|
|
53
|
+
web: ['url']
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function fixBookmarkData (data) {
|
|
57
|
+
if (!data || typeof data !== 'object') {
|
|
58
|
+
return data
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const type = data.type || 'ssh'
|
|
62
|
+
const schema = bookmarkSchema[type]
|
|
63
|
+
|
|
64
|
+
if (!schema) {
|
|
65
|
+
return data
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const fixed = { ...data }
|
|
69
|
+
|
|
70
|
+
if (!fixed.type) {
|
|
71
|
+
fixed.type = type
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const defaults = defaultValues[type] || {}
|
|
75
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
76
|
+
if (fixed[key] === undefined || fixed[key] === null) {
|
|
77
|
+
fixed[key] = value
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (fixed.connectionHoppings?.length) {
|
|
82
|
+
fixed.hasHopping = true
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return fixed
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function validateBookmarkData (data) {
|
|
89
|
+
if (!data || typeof data !== 'object') {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
errors: ['Invalid data format']
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const type = data.type || 'ssh'
|
|
97
|
+
const required = requiredFields[type] || []
|
|
98
|
+
const errors = []
|
|
99
|
+
|
|
100
|
+
for (const field of required) {
|
|
101
|
+
if (!data[field]) {
|
|
102
|
+
errors.push(`Missing required field: ${field}`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
valid: errors.length === 0,
|
|
108
|
+
errors
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function getMissingRequiredFields (data) {
|
|
113
|
+
if (!data || typeof data !== 'object') {
|
|
114
|
+
return []
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const type = data.type || 'ssh'
|
|
118
|
+
const required = requiredFields[type] || []
|
|
119
|
+
const missing = []
|
|
120
|
+
|
|
121
|
+
for (const field of required) {
|
|
122
|
+
if (!data[field]) {
|
|
123
|
+
missing.push(field)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return missing
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default {
|
|
131
|
+
fixBookmarkData,
|
|
132
|
+
validateBookmarkData,
|
|
133
|
+
getMissingRequiredFields
|
|
134
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Config-driven bookmark form (drop-in replacement)
|
|
3
3
|
*/
|
|
4
4
|
import { PureComponent } from 'react'
|
|
5
|
-
import { Radio } from 'antd'
|
|
5
|
+
import { Radio, Button } from 'antd'
|
|
6
6
|
import {
|
|
7
7
|
settingMap,
|
|
8
8
|
connectionMap,
|
|
@@ -13,12 +13,14 @@ import {
|
|
|
13
13
|
terminalLocalType,
|
|
14
14
|
terminalTelnetType,
|
|
15
15
|
terminalFtpType,
|
|
16
|
-
newBookmarkIdPrefix
|
|
16
|
+
newBookmarkIdPrefix,
|
|
17
|
+
terminalSpiceType
|
|
17
18
|
} from '../../common/constants'
|
|
18
19
|
import { createTitleWithTag } from '../../common/create-title'
|
|
19
|
-
import { LoadingOutlined, BookOutlined } from '@ant-design/icons'
|
|
20
|
+
import { LoadingOutlined, BookOutlined, RobotOutlined } from '@ant-design/icons'
|
|
20
21
|
import sessionConfig from './config/session-config'
|
|
21
22
|
import renderForm from './render-form'
|
|
23
|
+
import AIBookmarkForm from './ai-bookmark-form'
|
|
22
24
|
import './bookmark-form.styl'
|
|
23
25
|
|
|
24
26
|
const e = window.translate
|
|
@@ -34,27 +36,56 @@ export default class BookmarkIndex2 extends PureComponent {
|
|
|
34
36
|
terminalSerialType,
|
|
35
37
|
terminalRdpType,
|
|
36
38
|
terminalVncType,
|
|
37
|
-
terminalFtpType
|
|
39
|
+
terminalFtpType,
|
|
40
|
+
terminalSpiceType
|
|
38
41
|
].includes(initType)) {
|
|
39
42
|
initType = connectionMap.ssh
|
|
40
43
|
}
|
|
41
|
-
|
|
44
|
+
const v = this.getInitAiModeState()
|
|
45
|
+
this.state = {
|
|
46
|
+
ready: v,
|
|
47
|
+
bookmarkType: initType,
|
|
48
|
+
aiMode: v
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
componentDidMount () {
|
|
45
|
-
this.timer = setTimeout(() =>
|
|
53
|
+
this.timer = setTimeout(() => {
|
|
54
|
+
this.setState({ ready: true })
|
|
55
|
+
}, 75)
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
componentWillUnmount () {
|
|
49
59
|
clearTimeout(this.timer)
|
|
50
60
|
}
|
|
51
61
|
|
|
62
|
+
getInitAiModeState () {
|
|
63
|
+
const v = window.et.openBookmarkWithAIMode
|
|
64
|
+
if (v !== true) {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
delete window.et.openBookmarkWithAIMode
|
|
68
|
+
return true
|
|
69
|
+
}
|
|
70
|
+
|
|
52
71
|
handleChange = (e) => {
|
|
53
72
|
this.setState({ bookmarkType: e.target.value })
|
|
54
73
|
}
|
|
55
74
|
|
|
75
|
+
handleCancelAiMode = () => {
|
|
76
|
+
this.setState({ aiMode: false })
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
handleToggleAIMode = () => {
|
|
80
|
+
if (window.store.aiConfigMissing()) {
|
|
81
|
+
window.store.toggleAIConfig()
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
this.setState(prev => ({ aiMode: !prev.aiMode }))
|
|
85
|
+
}
|
|
86
|
+
|
|
56
87
|
renderTypes (bookmarkType, isNew, keys) {
|
|
57
|
-
if (!isNew) return null
|
|
88
|
+
if (!isNew || this.state.aiMode) return null
|
|
58
89
|
return (
|
|
59
90
|
<Radio.Group
|
|
60
91
|
buttonStyle='solid'
|
|
@@ -66,11 +97,7 @@ export default class BookmarkIndex2 extends PureComponent {
|
|
|
66
97
|
>
|
|
67
98
|
{keys.map(v => {
|
|
68
99
|
const txt = v === 'ssh' ? 'Ssh/Sftp' : e(v)
|
|
69
|
-
|
|
70
|
-
if (v === connectionMap.vnc || v === connectionMap.rdp) {
|
|
71
|
-
sup = <sup className='color-red'>Beta</sup>
|
|
72
|
-
}
|
|
73
|
-
return (<Radio.Button key={v} value={v}>{txt}{sup}</Radio.Button>)
|
|
100
|
+
return (<Radio.Button key={v} value={v}>{txt}</Radio.Button>)
|
|
74
101
|
})}
|
|
75
102
|
</Radio.Group>
|
|
76
103
|
)
|
|
@@ -85,6 +112,39 @@ export default class BookmarkIndex2 extends PureComponent {
|
|
|
85
112
|
)
|
|
86
113
|
}
|
|
87
114
|
|
|
115
|
+
renderAIButton (isNew) {
|
|
116
|
+
if (!isNew || this.state.aiMode) {
|
|
117
|
+
return null
|
|
118
|
+
}
|
|
119
|
+
return (
|
|
120
|
+
<Button
|
|
121
|
+
type='primary'
|
|
122
|
+
size='small'
|
|
123
|
+
className='mg2l create-ai-btn'
|
|
124
|
+
icon={<RobotOutlined />}
|
|
125
|
+
onClick={this.handleToggleAIMode}
|
|
126
|
+
>
|
|
127
|
+
{e('createBookmarkByAI')}
|
|
128
|
+
</Button>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
renderAiForm () {
|
|
133
|
+
return (
|
|
134
|
+
<AIBookmarkForm
|
|
135
|
+
onCancel={this.handleCancelAiMode}
|
|
136
|
+
/>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
renderForm () {
|
|
141
|
+
const { bookmarkType, aiMode } = this.state
|
|
142
|
+
if (aiMode) {
|
|
143
|
+
return this.renderAiForm()
|
|
144
|
+
}
|
|
145
|
+
return renderForm(bookmarkType, this.props)
|
|
146
|
+
}
|
|
147
|
+
|
|
88
148
|
render () {
|
|
89
149
|
const { formData } = this.props
|
|
90
150
|
const { id = '' } = formData
|
|
@@ -109,8 +169,9 @@ export default class BookmarkIndex2 extends PureComponent {
|
|
|
109
169
|
</span>
|
|
110
170
|
{this.renderTitle(formData, isNew)}
|
|
111
171
|
{this.renderTypes(bookmarkType, isNew, keys)}
|
|
172
|
+
{this.renderAIButton(isNew)}
|
|
112
173
|
</div>
|
|
113
|
-
{renderForm(
|
|
174
|
+
{this.renderForm()}
|
|
114
175
|
</div>
|
|
115
176
|
)
|
|
116
177
|
}
|
|
@@ -8,6 +8,7 @@ import Sftp from '../sftp/sftp-entry'
|
|
|
8
8
|
import RdpSession from '../rdp/rdp-session'
|
|
9
9
|
import VncSession from '../vnc/vnc-session'
|
|
10
10
|
import WebSession from '../web/web-session.jsx'
|
|
11
|
+
import SpiceSession from '../spice/spice-session'
|
|
11
12
|
import {
|
|
12
13
|
SearchOutlined,
|
|
13
14
|
FullscreenOutlined,
|
|
@@ -29,7 +30,8 @@ import {
|
|
|
29
30
|
terminalVncType,
|
|
30
31
|
terminalWebType,
|
|
31
32
|
terminalTelnetType,
|
|
32
|
-
terminalFtpType
|
|
33
|
+
terminalFtpType,
|
|
34
|
+
terminalSpiceType
|
|
33
35
|
} from '../../common/constants'
|
|
34
36
|
import { SplitViewIcon } from '../icons/split-view'
|
|
35
37
|
import { refs } from '../common/ref'
|
|
@@ -269,7 +271,7 @@ export default class SessionWrapper extends Component {
|
|
|
269
271
|
/>
|
|
270
272
|
)
|
|
271
273
|
}
|
|
272
|
-
if (type === terminalRdpType || type === terminalVncType) {
|
|
274
|
+
if (type === terminalRdpType || type === terminalVncType || type === terminalSpiceType) {
|
|
273
275
|
const rdpProps = {
|
|
274
276
|
tab: this.props.tab,
|
|
275
277
|
...pick(this.props, [
|
|
@@ -299,6 +301,13 @@ export default class SessionWrapper extends Component {
|
|
|
299
301
|
/>
|
|
300
302
|
)
|
|
301
303
|
}
|
|
304
|
+
if (type === terminalSpiceType) {
|
|
305
|
+
return (
|
|
306
|
+
<SpiceSession
|
|
307
|
+
{...rdpProps}
|
|
308
|
+
/>
|
|
309
|
+
)
|
|
310
|
+
}
|
|
302
311
|
|
|
303
312
|
return (
|
|
304
313
|
<RdpSession
|
|
@@ -373,7 +382,8 @@ export default class SessionWrapper extends Component {
|
|
|
373
382
|
type === terminalVncType ||
|
|
374
383
|
type === terminalWebType ||
|
|
375
384
|
type === terminalTelnetType ||
|
|
376
|
-
type === terminalFtpType
|
|
385
|
+
type === terminalFtpType ||
|
|
386
|
+
type === terminalSpiceType
|
|
377
387
|
}
|
|
378
388
|
|
|
379
389
|
calcSftpWidthHeight = () => {
|
|
@@ -27,7 +27,6 @@ export default class KeywordsTransport extends BookmarkTransport {
|
|
|
27
27
|
const { store } = this.props
|
|
28
28
|
const arr = store.config.keywords || []
|
|
29
29
|
const txt = JSON.stringify(arr, null, 2)
|
|
30
|
-
console.log(txt, 'txt')
|
|
31
30
|
const stamp = time(undefined, 'YYYY-MM-DD-HH-mm-ss')
|
|
32
31
|
download('electerm-' + this.name + '-' + stamp + '.json', txt)
|
|
33
32
|
}
|
|
@@ -175,12 +175,18 @@ export function shortcutExtend (Cls) {
|
|
|
175
175
|
type === 'keydown' &&
|
|
176
176
|
!altKey &&
|
|
177
177
|
!shiftKey &&
|
|
178
|
-
ctrlKey
|
|
179
|
-
this.zmodemClient &&
|
|
180
|
-
this.zmodemClient.isActive
|
|
178
|
+
ctrlKey
|
|
181
179
|
) {
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
// Cancel zmodem transfer if active
|
|
181
|
+
if (this.zmodemClient && this.zmodemClient.isActive) {
|
|
182
|
+
this.zmodemClient.cancel()
|
|
183
|
+
return false
|
|
184
|
+
}
|
|
185
|
+
// Cancel trzsz transfer if active
|
|
186
|
+
if (this.trzszClient && this.trzszClient.isActive) {
|
|
187
|
+
this.trzszClient.cancel()
|
|
188
|
+
return false
|
|
189
|
+
}
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
let codeName
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
SettingOutlined,
|
|
8
8
|
UpCircleOutlined,
|
|
9
9
|
BarsOutlined,
|
|
10
|
-
AppstoreOutlined
|
|
10
|
+
AppstoreOutlined,
|
|
11
|
+
RobotOutlined
|
|
11
12
|
} from '@ant-design/icons'
|
|
12
13
|
import { Tooltip } from 'antd'
|
|
13
14
|
import SideBarPanel from './sidebar-panel'
|
|
@@ -86,6 +87,7 @@ export default function Sidebar (props) {
|
|
|
86
87
|
|
|
87
88
|
const {
|
|
88
89
|
onNewSsh,
|
|
90
|
+
onNewSshAI,
|
|
89
91
|
openSetting,
|
|
90
92
|
openAbout,
|
|
91
93
|
openSettingSync,
|
|
@@ -142,6 +144,14 @@ export default function Sidebar (props) {
|
|
|
142
144
|
onClick={onNewSsh}
|
|
143
145
|
/>
|
|
144
146
|
</SideIcon>
|
|
147
|
+
<SideIcon
|
|
148
|
+
title={e('createBookmarkByAI')}
|
|
149
|
+
>
|
|
150
|
+
<RobotOutlined
|
|
151
|
+
className='font20 iblock control-icon'
|
|
152
|
+
onClick={onNewSshAI}
|
|
153
|
+
/>
|
|
154
|
+
</SideIcon>
|
|
145
155
|
<SideIcon
|
|
146
156
|
title={e(settingMap.bookmarks)}
|
|
147
157
|
active={bookmarksActive}
|