@electerm/electerm-react 1.39.35 → 1.39.46
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/components/bookmark-form/bookmark-group-tree-format.js +25 -24
- package/client/components/bookmark-form/form-ssh-common.jsx +10 -0
- package/client/components/bookmark-form/render-connection-hopping.jsx +21 -20
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +4 -3
- package/client/components/bookmark-form/ssh-form.jsx +2 -1
- package/client/components/bookmark-form/vnc-form-ui.jsx +42 -3
- package/client/components/main/main.jsx +1 -1
- package/client/components/profile/profile-form-elem.jsx +0 -1
- package/client/components/quick-commands/quick-command-transport-mod.jsx +1 -1
- package/client/components/setting-panel/bookmark-tree-list.jsx +1 -1
- package/client/components/setting-panel/start-session-select.jsx +4 -3
- package/client/components/sftp/file-item.jsx +3 -3
- package/client/components/sidebar/bookmark-select.jsx +1 -1
- package/client/components/tabs/index.jsx +1 -1
- package/client/components/tabs/tabs.styl +2 -2
- package/client/components/terminal/index.jsx +1 -1
- package/client/components/tree-list/tree-expander.jsx +36 -0
- package/client/components/tree-list/tree-list-item.jsx +263 -0
- package/client/components/{setting-panel → tree-list}/tree-list.jsx +397 -324
- package/client/components/{setting-panel → tree-list}/tree-list.styl +26 -6
- package/client/store/common.js +15 -1
- package/client/store/index.js +24 -0
- package/package.json +1 -1
- /package/client/components/{setting-panel → tree-list}/bookmark-transport.jsx +0 -0
|
@@ -3,37 +3,38 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export default (bookmarkGroups = []) => {
|
|
6
|
-
const
|
|
6
|
+
const btree = bookmarkGroups
|
|
7
7
|
.reduce((prev, k) => {
|
|
8
8
|
return {
|
|
9
9
|
...prev,
|
|
10
10
|
[k.id]: k
|
|
11
11
|
}
|
|
12
12
|
}, {})
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
function buildSubCats (id) {
|
|
14
|
+
const x = btree[id]
|
|
15
|
+
if (!x) {
|
|
16
|
+
return ''
|
|
17
|
+
}
|
|
18
|
+
const y = {
|
|
19
|
+
key: x.id,
|
|
20
|
+
value: x.id,
|
|
21
|
+
title: x.title
|
|
22
|
+
}
|
|
23
|
+
y.children = (x.bookmarkGroupIds || []).map(buildSubCats).filter(d => d)
|
|
24
|
+
if (!y.children.length) {
|
|
25
|
+
delete y.children
|
|
26
|
+
}
|
|
27
|
+
return y
|
|
28
|
+
}
|
|
29
|
+
const level1 = bookmarkGroups.filter(d => d.level !== 2)
|
|
30
|
+
.map(d => {
|
|
16
31
|
const r = {
|
|
17
|
-
title:
|
|
18
|
-
value:
|
|
19
|
-
key:
|
|
20
|
-
|
|
21
|
-
if (j.bookmarkGroupIds && j.bookmarkGroupIds.length) {
|
|
22
|
-
r.children = j.bookmarkGroupIds.map(k => {
|
|
23
|
-
const o = dict[k]
|
|
24
|
-
return o
|
|
25
|
-
? {
|
|
26
|
-
title: o.title,
|
|
27
|
-
value: o.id,
|
|
28
|
-
key: o.id
|
|
29
|
-
}
|
|
30
|
-
: null
|
|
31
|
-
})
|
|
32
|
-
r.children = r.children.filter(d => d)
|
|
33
|
-
if (!r.children.length) {
|
|
34
|
-
delete r.children
|
|
35
|
-
}
|
|
32
|
+
title: d.title,
|
|
33
|
+
value: d.id,
|
|
34
|
+
key: d.id,
|
|
35
|
+
children: (d.bookmarkGroupIds || []).map(buildSubCats).filter(d => d)
|
|
36
36
|
}
|
|
37
37
|
return r
|
|
38
|
-
})
|
|
38
|
+
}).filter(d => d)
|
|
39
|
+
return level1
|
|
39
40
|
}
|
|
@@ -192,6 +192,16 @@ export default function renderCommon (props) {
|
|
|
192
192
|
>
|
|
193
193
|
<Input />
|
|
194
194
|
</FormItem>
|
|
195
|
+
<FormItem
|
|
196
|
+
{...formItemLayout}
|
|
197
|
+
label={e('interactiveValues')}
|
|
198
|
+
name='interactiveValues'
|
|
199
|
+
hasFeedback
|
|
200
|
+
>
|
|
201
|
+
<Input.TextArea
|
|
202
|
+
rows={1}
|
|
203
|
+
/>
|
|
204
|
+
</FormItem>
|
|
195
205
|
{renderRunScripts()}
|
|
196
206
|
<FormItem
|
|
197
207
|
{...formItemLayout}
|
|
@@ -37,11 +37,11 @@ export default function renderConnectionHopping (props) {
|
|
|
37
37
|
authType: authTypeMap.password
|
|
38
38
|
})
|
|
39
39
|
const [list, setList] = useState(formData.connectionHoppings || [])
|
|
40
|
-
function onChangeAuthType (
|
|
40
|
+
function onChangeAuthType (e) {
|
|
41
41
|
editState(old => {
|
|
42
42
|
return {
|
|
43
43
|
...old,
|
|
44
|
-
authType
|
|
44
|
+
authType: e.target.value
|
|
45
45
|
}
|
|
46
46
|
})
|
|
47
47
|
}
|
|
@@ -68,7 +68,7 @@ export default function renderConnectionHopping (props) {
|
|
|
68
68
|
})
|
|
69
69
|
formChild.resetFields()
|
|
70
70
|
}
|
|
71
|
-
const authTypes = Object.keys(authTypeMap).map(k => {
|
|
71
|
+
const authTypes = props.authTypes || Object.keys(authTypeMap).map(k => {
|
|
72
72
|
return k
|
|
73
73
|
})
|
|
74
74
|
|
|
@@ -95,7 +95,8 @@ export default function renderConnectionHopping (props) {
|
|
|
95
95
|
const pass = item.password ? ':*****' : ''
|
|
96
96
|
const ph = item.passphase ? '(passphase:*****)' : ''
|
|
97
97
|
const pk = item.privateKey ? '(privateKey:*****)' : ''
|
|
98
|
-
|
|
98
|
+
const useProfile = item.profile ? '[profile] ' : ''
|
|
99
|
+
return <span>{useProfile}{item.username}{pass}@{item.host}:{item.port}{pk}{ph}</span>
|
|
99
100
|
}
|
|
100
101
|
}, {
|
|
101
102
|
title: m('del'),
|
|
@@ -159,6 +160,22 @@ export default function renderConnectionHopping (props) {
|
|
|
159
160
|
>
|
|
160
161
|
<Input />
|
|
161
162
|
</FormItem>
|
|
163
|
+
<FormItem
|
|
164
|
+
{...formItemLayout}
|
|
165
|
+
label={f('port')}
|
|
166
|
+
hasFeedback
|
|
167
|
+
name='port'
|
|
168
|
+
rules={[{
|
|
169
|
+
required: true, message: 'port required'
|
|
170
|
+
}]}
|
|
171
|
+
>
|
|
172
|
+
<InputNumber
|
|
173
|
+
placeholder={f('port')}
|
|
174
|
+
min={1}
|
|
175
|
+
max={65535}
|
|
176
|
+
step={1}
|
|
177
|
+
/>
|
|
178
|
+
</FormItem>
|
|
162
179
|
<FormItem
|
|
163
180
|
{...formItemLayout}
|
|
164
181
|
label={f('username')}
|
|
@@ -192,22 +209,6 @@ export default function renderConnectionHopping (props) {
|
|
|
192
209
|
}
|
|
193
210
|
</RadioGroup>
|
|
194
211
|
</FormItem>
|
|
195
|
-
<FormItem
|
|
196
|
-
{...formItemLayout}
|
|
197
|
-
label={f('port')}
|
|
198
|
-
hasFeedback
|
|
199
|
-
name='port'
|
|
200
|
-
rules={[{
|
|
201
|
-
required: true, message: 'port required'
|
|
202
|
-
}]}
|
|
203
|
-
>
|
|
204
|
-
<InputNumber
|
|
205
|
-
placeholder={f('port')}
|
|
206
|
-
min={1}
|
|
207
|
-
max={65535}
|
|
208
|
-
step={1}
|
|
209
|
-
/>
|
|
210
|
-
</FormItem>
|
|
211
212
|
<RenderAuth
|
|
212
213
|
form={formChild}
|
|
213
214
|
store={store}
|
|
@@ -88,13 +88,14 @@ export default function renderSshTunnels (props) {
|
|
|
88
88
|
const {
|
|
89
89
|
sshTunnel,
|
|
90
90
|
sshTunnelRemoteHost = '127.0.0.1',
|
|
91
|
-
sshTunnelRemotePort,
|
|
91
|
+
sshTunnelRemotePort = '',
|
|
92
92
|
sshTunnelLocalHost = '127.0.0.1',
|
|
93
|
-
sshTunnelLocalPort,
|
|
93
|
+
sshTunnelLocalPort = '',
|
|
94
94
|
name
|
|
95
95
|
} = item
|
|
96
96
|
if (sshTunnel === 'dynamicForward') {
|
|
97
|
-
|
|
97
|
+
const n = name ? `[${name}] ` : ''
|
|
98
|
+
return `${n}socks5://${sshTunnelLocalHost}:${sshTunnelLocalPort}`
|
|
98
99
|
}
|
|
99
100
|
const to = sshTunnel === 'forwardRemoteToLocal'
|
|
100
101
|
? `${s('local')}:${sshTunnelLocalHost}:${sshTunnelLocalPort}`
|
|
@@ -225,7 +225,7 @@ export default class BookmarkForm extends PureComponent {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
test = async (update) => {
|
|
228
|
-
|
|
228
|
+
let options = {
|
|
229
229
|
...this.props.formData,
|
|
230
230
|
...update
|
|
231
231
|
}
|
|
@@ -233,6 +233,7 @@ export default class BookmarkForm extends PureComponent {
|
|
|
233
233
|
this.setState({
|
|
234
234
|
testing: true
|
|
235
235
|
})
|
|
236
|
+
options = window.store.applyProfileToTabs(options)
|
|
236
237
|
const res = await testCon(options)
|
|
237
238
|
.then(r => r)
|
|
238
239
|
.catch((e) => {
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
Form,
|
|
9
9
|
InputNumber,
|
|
10
10
|
TreeSelect,
|
|
11
|
-
Switch
|
|
11
|
+
Switch,
|
|
12
|
+
Tabs
|
|
12
13
|
} from 'antd'
|
|
13
14
|
import { formItemLayout } from '../../common/form-layout'
|
|
14
15
|
import {
|
|
@@ -22,6 +23,8 @@ import { ColorPickerItem } from './color-picker-item.jsx'
|
|
|
22
23
|
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
23
24
|
import formatBookmarkGroups from './bookmark-group-tree-format'
|
|
24
25
|
import findBookmarkGroupId from '../../common/find-bookmark-group-id'
|
|
26
|
+
import renderProxy from './proxy'
|
|
27
|
+
import ConnectionHopping from './render-connection-hopping.jsx'
|
|
25
28
|
|
|
26
29
|
const FormItem = Form.Item
|
|
27
30
|
const { prefix } = window
|
|
@@ -58,9 +61,42 @@ export default function VncFormUi (props) {
|
|
|
58
61
|
category: initBookmarkGroupId,
|
|
59
62
|
color: getRandomDefaultColor(),
|
|
60
63
|
viewOnly: false,
|
|
61
|
-
scaleViewport: true
|
|
64
|
+
scaleViewport: true,
|
|
65
|
+
connectionHoppings: []
|
|
62
66
|
}
|
|
63
67
|
initialValues = defaults(initialValues, defaultValues)
|
|
68
|
+
|
|
69
|
+
function renderTabs (props) {
|
|
70
|
+
const items = [
|
|
71
|
+
{
|
|
72
|
+
key: 'auth',
|
|
73
|
+
label: e('auth'),
|
|
74
|
+
forceRender: true,
|
|
75
|
+
children: renderCommon()
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: 'connectionHopping',
|
|
79
|
+
label: e('connectionHopping'),
|
|
80
|
+
forceRender: true,
|
|
81
|
+
children: renderHopping()
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
return (
|
|
85
|
+
<Tabs
|
|
86
|
+
items={items}
|
|
87
|
+
/>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function renderHopping () {
|
|
92
|
+
return (
|
|
93
|
+
<ConnectionHopping
|
|
94
|
+
{...props}
|
|
95
|
+
form={form}
|
|
96
|
+
/>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
64
100
|
function renderCommon () {
|
|
65
101
|
const {
|
|
66
102
|
bookmarkGroups = []
|
|
@@ -153,6 +189,9 @@ export default function VncFormUi (props) {
|
|
|
153
189
|
showSearch
|
|
154
190
|
/>
|
|
155
191
|
</FormItem>
|
|
192
|
+
{
|
|
193
|
+
renderProxy(props)
|
|
194
|
+
}
|
|
156
195
|
<FormItem
|
|
157
196
|
{...formItemLayout}
|
|
158
197
|
label='type'
|
|
@@ -172,7 +211,7 @@ export default function VncFormUi (props) {
|
|
|
172
211
|
initialValues={initialValues}
|
|
173
212
|
name='vnc-form'
|
|
174
213
|
>
|
|
175
|
-
{
|
|
214
|
+
{renderTabs()}
|
|
176
215
|
{submitUi}
|
|
177
216
|
</Form>
|
|
178
217
|
)
|
|
@@ -83,7 +83,7 @@ export default class Index extends Component {
|
|
|
83
83
|
loaded: configLoaded,
|
|
84
84
|
'system-ui': store.config.useSystemTitleBar,
|
|
85
85
|
'not-system-ui': !store.config.useSystemTitleBar,
|
|
86
|
-
'is-mac': isMac,
|
|
86
|
+
'is-mac': isMac && !window.et.isWebApp,
|
|
87
87
|
'is-win': isWin,
|
|
88
88
|
pinned,
|
|
89
89
|
'qm-pinned': pinnedQuickCommandBar,
|
|
@@ -34,9 +34,10 @@ export default class StartSessionSelect extends Component {
|
|
|
34
34
|
value: x.id,
|
|
35
35
|
title: x.title
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
y.children = [
|
|
38
|
+
...(x.bookmarkGroupIds || []).map(buildSubCats),
|
|
39
|
+
...(x.bookmarkIds || []).map(buildLeaf)
|
|
40
|
+
].filter(d => d)
|
|
40
41
|
if (y.children && !y.children.length) {
|
|
41
42
|
delete y.children
|
|
42
43
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
11
|
import classnames from 'classnames'
|
|
12
12
|
import copy from 'json-deep-copy'
|
|
13
|
-
import { pick, some } from 'lodash-es'
|
|
13
|
+
import { pick, some, without } from 'lodash-es'
|
|
14
14
|
import Input from '../common/input-auto-focus'
|
|
15
15
|
import resolve from '../../common/resolve'
|
|
16
16
|
import { addClass, removeClass } from '../../common/class'
|
|
@@ -382,7 +382,7 @@ export default class FileSection extends React.Component {
|
|
|
382
382
|
const { type } = this.props
|
|
383
383
|
window.store.openFileInfoModal({
|
|
384
384
|
file: this.state.file,
|
|
385
|
-
tab: this.props.tab,
|
|
385
|
+
tab: without(this.props.tab, 'terminals'),
|
|
386
386
|
visible: true,
|
|
387
387
|
pid: this.props.pid,
|
|
388
388
|
sessionId: this.props.sessionId,
|
|
@@ -531,7 +531,7 @@ export default class FileSection extends React.Component {
|
|
|
531
531
|
'message', this.changeFileMode
|
|
532
532
|
)
|
|
533
533
|
window.store.openFileModeModal({
|
|
534
|
-
tab: this.props.tab,
|
|
534
|
+
tab: without(this.props.tab, 'terminals'),
|
|
535
535
|
visible: true,
|
|
536
536
|
uidTree: this.props[`${type}UidTree`],
|
|
537
537
|
gidTree: this.props[`${type}GidTree`]
|
|
@@ -256,7 +256,7 @@ export default class Tabs extends React.Component {
|
|
|
256
256
|
const left = overflow
|
|
257
257
|
? '100%'
|
|
258
258
|
: tabsWidthAll
|
|
259
|
-
const w1 = isMacJs ? 30 : windowControlWidth
|
|
259
|
+
const w1 = isMacJs && window.et.isWebApp ? 30 : windowControlWidth
|
|
260
260
|
const style = {
|
|
261
261
|
width: width - w1 - 166
|
|
262
262
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
.tabs-inner
|
|
12
12
|
margin-left 72px
|
|
13
13
|
.tabs-extra
|
|
14
|
-
right
|
|
14
|
+
right 96px
|
|
15
15
|
.tabs-inner
|
|
16
16
|
position relative
|
|
17
17
|
z-index 2
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
position absolute
|
|
138
138
|
height 40px
|
|
139
139
|
top 0
|
|
140
|
-
right
|
|
140
|
+
right 0
|
|
141
141
|
line-height 40px
|
|
142
142
|
z-index 20
|
|
143
143
|
|
|
@@ -1092,7 +1092,7 @@ class Term extends Component {
|
|
|
1092
1092
|
server = ''
|
|
1093
1093
|
} = config
|
|
1094
1094
|
const { sessionId, terminalIndex, id, logName } = this.props
|
|
1095
|
-
const tab = window.store.
|
|
1095
|
+
const tab = window.store.applyProfileToTabs(deepCopy(this.props.tab || {}))
|
|
1096
1096
|
const {
|
|
1097
1097
|
srcId, from = 'bookmarks',
|
|
1098
1098
|
type,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CaretDownOutlined,
|
|
3
|
+
CaretRightOutlined
|
|
4
|
+
} from '@ant-design/icons'
|
|
5
|
+
import { memo } from 'react'
|
|
6
|
+
|
|
7
|
+
export default memo(function TreeExpander (props) {
|
|
8
|
+
function onExpand () {
|
|
9
|
+
props.onExpand(group)
|
|
10
|
+
}
|
|
11
|
+
function onUnExpand () {
|
|
12
|
+
props.onUnExpand(group)
|
|
13
|
+
}
|
|
14
|
+
const { group } = props
|
|
15
|
+
if (
|
|
16
|
+
!group?.bookmarkIds?.length &&
|
|
17
|
+
!group?.bookmarkGroupIds?.length
|
|
18
|
+
) {
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
const shouldOpen = props.keyword || props.expandedKeys.includes(group.id)
|
|
22
|
+
const Icon = shouldOpen
|
|
23
|
+
? CaretDownOutlined
|
|
24
|
+
: CaretRightOutlined
|
|
25
|
+
const func = shouldOpen
|
|
26
|
+
? onUnExpand
|
|
27
|
+
: onExpand
|
|
28
|
+
return (
|
|
29
|
+
<div
|
|
30
|
+
className='tree-expander pointer'
|
|
31
|
+
onClick={func}
|
|
32
|
+
>
|
|
33
|
+
<Icon />
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
})
|