@electerm/electerm-react 1.38.70 → 1.38.81
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 -1
- package/client/components/bookmark-form/index.jsx +12 -8
- package/client/components/bookmark-form/web-form-ui.jsx +96 -0
- package/client/components/bookmark-form/web-form.jsx +16 -0
- package/client/components/quick-commands/qm.styl +1 -1
- package/client/components/session/session.styl +4 -1
- package/client/components/session/sessions.jsx +16 -2
- package/client/components/session/web-session.jsx +20 -0
- package/client/components/terminal/index.jsx +13 -1
- package/client/entry/worker.js +5 -1
- package/client/store/index.js +12 -1
- package/package.json +1 -1
|
@@ -66,7 +66,8 @@ export const connectionMap = buildConst([
|
|
|
66
66
|
'ssh',
|
|
67
67
|
'telnet',
|
|
68
68
|
'serial',
|
|
69
|
-
'local'
|
|
69
|
+
'local',
|
|
70
|
+
'web'
|
|
70
71
|
])
|
|
71
72
|
|
|
72
73
|
export const authTypeMap = buildConst([
|
|
@@ -131,6 +132,7 @@ export const terminalSplitDirectionMap = buildConst([
|
|
|
131
132
|
])
|
|
132
133
|
|
|
133
134
|
export const terminalSshConfigType = 'ssh-config'
|
|
135
|
+
export const terminalWebType = 'web'
|
|
134
136
|
export const terminalSerialType = 'serial'
|
|
135
137
|
export const terminalTelnetType = 'telnet'
|
|
136
138
|
export const terminalLocalType = 'local'
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
settingMap,
|
|
10
10
|
connectionMap,
|
|
11
11
|
terminalSerialType,
|
|
12
|
+
terminalWebType,
|
|
12
13
|
terminalLocalType,
|
|
13
14
|
terminalTelnetType,
|
|
14
15
|
newBookmarkIdPrefix
|
|
@@ -17,6 +18,7 @@ import SshForm from './ssh-form'
|
|
|
17
18
|
import SerialForm from './serial-form'
|
|
18
19
|
import LocalForm from './local-form'
|
|
19
20
|
import TelnetForm from './telnet-form'
|
|
21
|
+
import WebForm from './web-form'
|
|
20
22
|
import { createTitleWithTag } from '../../common/create-title'
|
|
21
23
|
import {
|
|
22
24
|
LoadingOutlined,
|
|
@@ -33,13 +35,14 @@ export default class BookmarkIndex extends Component {
|
|
|
33
35
|
constructor (props) {
|
|
34
36
|
super(props)
|
|
35
37
|
let initType = props.formData.type
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
if (
|
|
39
|
+
![
|
|
40
|
+
terminalTelnetType,
|
|
41
|
+
terminalWebType,
|
|
42
|
+
terminalLocalType,
|
|
43
|
+
terminalSerialType
|
|
44
|
+
].includes(initType)
|
|
45
|
+
) {
|
|
43
46
|
initType = connectionMap.ssh
|
|
44
47
|
}
|
|
45
48
|
this.state = {
|
|
@@ -64,7 +67,8 @@ export default class BookmarkIndex extends Component {
|
|
|
64
67
|
[connectionMap.ssh]: SshForm,
|
|
65
68
|
[connectionMap.telnet]: TelnetForm,
|
|
66
69
|
[connectionMap.serial]: SerialForm,
|
|
67
|
-
[connectionMap.local]: LocalForm
|
|
70
|
+
[connectionMap.local]: LocalForm,
|
|
71
|
+
[connectionMap.web]: WebForm
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
handleChange = (e) => {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web form
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { useEffect } from 'react'
|
|
6
|
+
import {
|
|
7
|
+
Input,
|
|
8
|
+
Form
|
|
9
|
+
} from 'antd'
|
|
10
|
+
import { formItemLayout } from '../../common/form-layout'
|
|
11
|
+
import {
|
|
12
|
+
newBookmarkIdPrefix,
|
|
13
|
+
terminalWebType
|
|
14
|
+
} from '../../common/constants'
|
|
15
|
+
import useSubmit from './use-submit'
|
|
16
|
+
import copy from 'json-deep-copy'
|
|
17
|
+
import { defaults } from 'lodash-es'
|
|
18
|
+
import { ColorPickerItem } from './color-picker-item.jsx'
|
|
19
|
+
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
20
|
+
|
|
21
|
+
const FormItem = Form.Item
|
|
22
|
+
const { prefix } = window
|
|
23
|
+
const e = prefix('form')
|
|
24
|
+
|
|
25
|
+
export default function LocalFormUi (props) {
|
|
26
|
+
const [
|
|
27
|
+
form,
|
|
28
|
+
handleFinish,
|
|
29
|
+
submitUi
|
|
30
|
+
] = useSubmit(props)
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (props.formData.id.startsWith(newBookmarkIdPrefix)) {
|
|
33
|
+
form.setFieldsValue({
|
|
34
|
+
category: props.currentBookmarkGroupId
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
}, [props.currentBookmarkGroupId])
|
|
38
|
+
let initialValues = copy(props.formData)
|
|
39
|
+
const defaultValues = {
|
|
40
|
+
type: terminalWebType,
|
|
41
|
+
color: getRandomDefaultColor()
|
|
42
|
+
}
|
|
43
|
+
initialValues = defaults(initialValues, defaultValues)
|
|
44
|
+
function renderCommon () {
|
|
45
|
+
return (
|
|
46
|
+
<div className='pd1x'>
|
|
47
|
+
<FormItem
|
|
48
|
+
{...formItemLayout}
|
|
49
|
+
label={e('title')}
|
|
50
|
+
hasFeedback
|
|
51
|
+
>
|
|
52
|
+
<FormItem noStyle name='title'>
|
|
53
|
+
<Input addonBefore={<ColorPickerItem />} />
|
|
54
|
+
</FormItem>
|
|
55
|
+
</FormItem>
|
|
56
|
+
<FormItem
|
|
57
|
+
{...formItemLayout}
|
|
58
|
+
label={e('URL')}
|
|
59
|
+
hasFeedback
|
|
60
|
+
name='url'
|
|
61
|
+
required
|
|
62
|
+
>
|
|
63
|
+
<Input addonBefore={<ColorPickerItem />} />
|
|
64
|
+
</FormItem>
|
|
65
|
+
<FormItem
|
|
66
|
+
{...formItemLayout}
|
|
67
|
+
label={e('description')}
|
|
68
|
+
name='description'
|
|
69
|
+
hasFeedback
|
|
70
|
+
>
|
|
71
|
+
<Input.TextArea rows={1} />
|
|
72
|
+
</FormItem>
|
|
73
|
+
<FormItem
|
|
74
|
+
{...formItemLayout}
|
|
75
|
+
label='type'
|
|
76
|
+
name='type'
|
|
77
|
+
className='hide'
|
|
78
|
+
>
|
|
79
|
+
<Input />
|
|
80
|
+
</FormItem>
|
|
81
|
+
</div>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Form
|
|
87
|
+
form={form}
|
|
88
|
+
onFinish={handleFinish}
|
|
89
|
+
initialValues={initialValues}
|
|
90
|
+
name='local-form'
|
|
91
|
+
>
|
|
92
|
+
{renderCommon()}
|
|
93
|
+
{submitUi}
|
|
94
|
+
</Form>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bookmark form
|
|
3
|
+
*/
|
|
4
|
+
import BookmarkForm from './ssh-form'
|
|
5
|
+
import WebFormUi from './web-form-ui'
|
|
6
|
+
|
|
7
|
+
export default class WebForm extends BookmarkForm {
|
|
8
|
+
render () {
|
|
9
|
+
return (
|
|
10
|
+
<WebFormUi
|
|
11
|
+
{...this.props}
|
|
12
|
+
{...this.getProps()}
|
|
13
|
+
/>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component } from '../common/react-subx'
|
|
2
2
|
import Session from './session'
|
|
3
|
+
import WebSession from './web-session'
|
|
3
4
|
import { findIndex, pick } from 'lodash-es'
|
|
4
5
|
import classNames from 'classnames'
|
|
5
6
|
import generate from '../../common/uid'
|
|
@@ -11,7 +12,8 @@ import {
|
|
|
11
12
|
tabActions,
|
|
12
13
|
termInitId,
|
|
13
14
|
paneMap,
|
|
14
|
-
statusMap
|
|
15
|
+
statusMap,
|
|
16
|
+
terminalWebType
|
|
15
17
|
} from '../../common/constants'
|
|
16
18
|
import newTerm, { updateCount } from '../../common/new-terminal'
|
|
17
19
|
import postMsg from '../../common/post-msg'
|
|
@@ -336,7 +338,7 @@ class Sessions extends Component {
|
|
|
336
338
|
return this.renderNoSession()
|
|
337
339
|
}
|
|
338
340
|
return tabs.map((tab) => {
|
|
339
|
-
const { id } = tab
|
|
341
|
+
const { id, type } = tab
|
|
340
342
|
const cls = classNames(
|
|
341
343
|
`session-wrap session-${id}`,
|
|
342
344
|
{
|
|
@@ -372,6 +374,18 @@ class Sessions extends Component {
|
|
|
372
374
|
'editTab'
|
|
373
375
|
])
|
|
374
376
|
}
|
|
377
|
+
if (type === terminalWebType) {
|
|
378
|
+
const webProps = {
|
|
379
|
+
tab
|
|
380
|
+
}
|
|
381
|
+
return (
|
|
382
|
+
<div className={cls} key={id}>
|
|
383
|
+
<WebSession
|
|
384
|
+
{...webProps}
|
|
385
|
+
/>
|
|
386
|
+
</div>
|
|
387
|
+
)
|
|
388
|
+
}
|
|
375
389
|
return (
|
|
376
390
|
<div className={cls} key={id}>
|
|
377
391
|
<Session
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import Link from '../common/external-link'
|
|
3
|
+
|
|
4
|
+
export default function WebSession (props) {
|
|
5
|
+
const {
|
|
6
|
+
tab
|
|
7
|
+
} = props
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
tab.url && window.openLink(tab.url)
|
|
10
|
+
}, [])
|
|
11
|
+
return (
|
|
12
|
+
<div className='web-session-wrap'>
|
|
13
|
+
<div className='pd3 aligncenter'>
|
|
14
|
+
<h1>{tab.title}</h1>
|
|
15
|
+
<p>{tab.description}</p>
|
|
16
|
+
<Link to={tab.url}>{tab.url}</Link>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -138,9 +138,13 @@ class Term extends Component {
|
|
|
138
138
|
clearTimeout(this.timers[k])
|
|
139
139
|
})
|
|
140
140
|
this.onClose = true
|
|
141
|
-
|
|
141
|
+
if (this.socket) {
|
|
142
|
+
this.socket.close()
|
|
143
|
+
delete this.socket
|
|
144
|
+
}
|
|
142
145
|
if (this.term) {
|
|
143
146
|
this.term.dispose()
|
|
147
|
+
delete this.term
|
|
144
148
|
}
|
|
145
149
|
window.removeEventListener(
|
|
146
150
|
'resize',
|
|
@@ -149,6 +153,13 @@ class Term extends Component {
|
|
|
149
153
|
window.removeEventListener('message', this.handleEvent)
|
|
150
154
|
this.dom.removeEventListener('contextmenu', this.onContextMenu)
|
|
151
155
|
window.removeEventListener('message', this.onContextAction)
|
|
156
|
+
delete this.dom
|
|
157
|
+
delete this.attachAddon
|
|
158
|
+
delete this.fitAddon
|
|
159
|
+
delete this.zmodemAddon
|
|
160
|
+
delete this.searchAddon
|
|
161
|
+
delete this.serializeAddon
|
|
162
|
+
delete this.fitAddon
|
|
152
163
|
}
|
|
153
164
|
|
|
154
165
|
terminalConfigProps = [
|
|
@@ -1226,6 +1237,7 @@ class Term extends Component {
|
|
|
1226
1237
|
this.socketCloseWarning = notification.warning({
|
|
1227
1238
|
key,
|
|
1228
1239
|
message: e('socketCloseTip'),
|
|
1240
|
+
duration: 30,
|
|
1229
1241
|
description: (
|
|
1230
1242
|
<div className='pd2y'>
|
|
1231
1243
|
<Button
|
package/client/entry/worker.js
CHANGED
|
@@ -16,7 +16,11 @@ function createWs (
|
|
|
16
16
|
const wsUrl = `ws://${host}:${port}/${type}/${id}?sessionId=${sessionId}&sftpId=${sftpId}&token=${tokenElecterm}`
|
|
17
17
|
const ws = new WebSocket(wsUrl)
|
|
18
18
|
ws.s = msg => {
|
|
19
|
-
|
|
19
|
+
try {
|
|
20
|
+
ws.send(JSON.stringify(msg))
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error('ws send error', e)
|
|
23
|
+
}
|
|
20
24
|
}
|
|
21
25
|
ws.id = id
|
|
22
26
|
ws.once = (callack, id) => {
|
package/client/store/index.js
CHANGED
|
@@ -63,7 +63,18 @@ function expandShorthandColor (color) {
|
|
|
63
63
|
if (color.length === 4) {
|
|
64
64
|
return '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
if (color.length === 7) {
|
|
67
|
+
return color
|
|
68
|
+
}
|
|
69
|
+
if (color.length < 7) {
|
|
70
|
+
return expandShorthandColor(color + 'f')
|
|
71
|
+
}
|
|
72
|
+
if (color.length > 7) {
|
|
73
|
+
return expandShorthandColor(color.slice(0, 7))
|
|
74
|
+
}
|
|
75
|
+
if (!/^#[A-Fa-f0-9]{6}$/.test(color)) {
|
|
76
|
+
return '#141314'
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
function isColorDark (_color) {
|