@electerm/electerm-react 1.37.38 → 1.37.58
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 +2 -0
- package/client/common/update-check.js +7 -1
- package/client/components/footer/footer-entry.jsx +13 -2
- package/client/components/main/upgrade.jsx +3 -2
- package/client/components/session/session.jsx +27 -7
- package/client/components/session/sessions.jsx +18 -2
- package/client/components/setting-sync/setting-sync-form.jsx +1 -1
- package/client/components/sftp/sftp-entry.jsx +6 -6
- package/client/components/shortcuts/shortcuts-defaults.js +0 -1
- package/client/components/sidebar/index.jsx +19 -4
- package/client/components/sidebar/side-panel.jsx +51 -0
- package/client/components/sidebar/sidebar.styl +28 -12
- package/client/components/tabs/index.jsx +8 -4
- package/client/components/tabs/tabs.styl +5 -0
- package/client/components/terminal-info/content.jsx +112 -66
- package/client/components/terminal-info/terminal-info.styl +10 -4
- package/client/store/common.js +14 -1
- package/client/store/init-state.js +5 -1
- package/client/store/setting.js +3 -9
- package/package.json +1 -1
|
@@ -138,6 +138,8 @@ export const terminalTelnetType = 'telnet'
|
|
|
138
138
|
export const terminalLocalType = 'local'
|
|
139
139
|
export const openedSidebarKey = 'opened-sidebar'
|
|
140
140
|
export const sidebarPinnedKey = 'sidebar-pinned'
|
|
141
|
+
export const leftSidebarWidthKey = 'left-sidebar-width'
|
|
142
|
+
export const rightSidebarWidthKey = 'right-sidebar-width'
|
|
141
143
|
export const sftpDefaultSortSettingKey = 'sftp-default-sort'
|
|
142
144
|
// https://github.com/tinkertrain/panda-syntax-vscode/blob/master/themes/workbench.yaml
|
|
143
145
|
export const defaultTheme = {
|
|
@@ -6,6 +6,7 @@ import fetch from './fetch-from-server'
|
|
|
6
6
|
import {
|
|
7
7
|
baseUpdateCheckUrls, packInfo
|
|
8
8
|
} from './constants'
|
|
9
|
+
import dayjs from 'dayjs'
|
|
9
10
|
|
|
10
11
|
async function fetchData (url, options) {
|
|
11
12
|
const data = {
|
|
@@ -75,5 +76,10 @@ export async function getLatestReleaseInfo () {
|
|
|
75
76
|
url = `${baseUpdateCheckUrls[1]}/data/electerm-github-release.json`
|
|
76
77
|
res = await getInfo(url)
|
|
77
78
|
}
|
|
78
|
-
return res
|
|
79
|
+
return res && res.release
|
|
80
|
+
? {
|
|
81
|
+
body: res.release.body,
|
|
82
|
+
date: dayjs(res.release.published_at).format('YYYY-MM-DD')
|
|
83
|
+
}
|
|
84
|
+
: undefined
|
|
79
85
|
}
|
|
@@ -122,13 +122,24 @@ export default class SystemMenu extends Component {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
render () {
|
|
125
|
-
const { tabs } = this.props.store
|
|
125
|
+
const { tabs, leftSidebarWidth, openedSideBar } = this.props.store
|
|
126
126
|
const pane = this.props.store.currentTab?.pane
|
|
127
127
|
if (pane === paneMap.fileManager || !tabs.length) {
|
|
128
128
|
return null
|
|
129
129
|
}
|
|
130
|
+
const w = 43 + leftSidebarWidth
|
|
131
|
+
const sideProps = openedSideBar
|
|
132
|
+
? {
|
|
133
|
+
className: 'main-footer',
|
|
134
|
+
style: {
|
|
135
|
+
left: `${w}px`
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
: {
|
|
139
|
+
className: 'main-footer'
|
|
140
|
+
}
|
|
130
141
|
return (
|
|
131
|
-
<div
|
|
142
|
+
<div {...sideProps}>
|
|
132
143
|
<div className='terminal-footer-flex'>
|
|
133
144
|
{this.renderQuickCommands()}
|
|
134
145
|
{this.renderBatchInputs()}
|
|
@@ -246,7 +246,7 @@ export default class Upgrade extends PureComponent {
|
|
|
246
246
|
return (
|
|
247
247
|
<div className='pd1t'>
|
|
248
248
|
<div className='bold'>Changelog:</div>
|
|
249
|
-
<Markdown text={releaseInfo} />
|
|
249
|
+
<Markdown text={releaseInfo.body} />
|
|
250
250
|
<Link
|
|
251
251
|
to={packInfo.releases}
|
|
252
252
|
>{e('moreChangeLog')}
|
|
@@ -279,6 +279,7 @@ export default class Upgrade extends PureComponent {
|
|
|
279
279
|
showUpgradeModal,
|
|
280
280
|
upgradePercent,
|
|
281
281
|
shouldUpgrade,
|
|
282
|
+
releaseInfo,
|
|
282
283
|
error
|
|
283
284
|
} = this.props.upgradeInfo
|
|
284
285
|
if (error) {
|
|
@@ -317,7 +318,7 @@ export default class Upgrade extends PureComponent {
|
|
|
317
318
|
<div className={cls}>
|
|
318
319
|
<div className='upgrade-panel-title'>
|
|
319
320
|
<MinusSquareOutlined className='pointer font16 close-upgrade-panel' onClick={this.handleMinimize} />
|
|
320
|
-
{e('newVersion')} <b>{remoteVersion}</b>
|
|
321
|
+
{e('newVersion')} <b>{remoteVersion} [{releaseInfo.date}]</b>
|
|
321
322
|
</div>
|
|
322
323
|
<div className='upgrade-panel-body'>
|
|
323
324
|
{
|
|
@@ -74,6 +74,7 @@ export default class SessionWrapper extends Component {
|
|
|
74
74
|
enableSftp: false,
|
|
75
75
|
splitDirection: terminalSplitDirectionMap.horizontal,
|
|
76
76
|
activeSplitId,
|
|
77
|
+
infoPanelPinned: false,
|
|
77
78
|
key: Math.random(),
|
|
78
79
|
sessionOptions: null,
|
|
79
80
|
sessionId: generate(),
|
|
@@ -104,6 +105,12 @@ export default class SessionWrapper extends Component {
|
|
|
104
105
|
})
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
toggleInfoPinned = () => {
|
|
109
|
+
this.setState({
|
|
110
|
+
infoPanelPinned: !this.state.infoPanelPinned
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
hideInfoPanel = () => {
|
|
108
115
|
this.setState({
|
|
109
116
|
showInfo: false
|
|
@@ -217,7 +224,7 @@ export default class SessionWrapper extends Component {
|
|
|
217
224
|
|
|
218
225
|
computePosition = (index) => {
|
|
219
226
|
const len = this.state.terminals.length || 1
|
|
220
|
-
const
|
|
227
|
+
const windowWidth = this.getWidth()
|
|
221
228
|
const { splitDirection } = this.state
|
|
222
229
|
const isHori = splitDirection === terminalSplitDirectionMap.horizontal
|
|
223
230
|
const heightAll = this.computeHeight()
|
|
@@ -241,6 +248,18 @@ export default class SessionWrapper extends Component {
|
|
|
241
248
|
}
|
|
242
249
|
}
|
|
243
250
|
|
|
251
|
+
getWidth = () => {
|
|
252
|
+
const {
|
|
253
|
+
infoPanelPinned,
|
|
254
|
+
showInfo
|
|
255
|
+
} = this.state
|
|
256
|
+
if (!infoPanelPinned || !showInfo) {
|
|
257
|
+
return this.props.width
|
|
258
|
+
}
|
|
259
|
+
const { rightSidebarWidth, width } = this.props
|
|
260
|
+
return width - rightSidebarWidth
|
|
261
|
+
}
|
|
262
|
+
|
|
244
263
|
renderTerminals = () => {
|
|
245
264
|
const {
|
|
246
265
|
terminals,
|
|
@@ -256,7 +275,8 @@ export default class SessionWrapper extends Component {
|
|
|
256
275
|
? 'terms-box'
|
|
257
276
|
: 'terms-box hide'
|
|
258
277
|
const height = this.computeHeight()
|
|
259
|
-
const {
|
|
278
|
+
const { tab } = this.props
|
|
279
|
+
const width = this.getWidth()
|
|
260
280
|
const themeConfig = copy(window.store.getThemeConfig())
|
|
261
281
|
return (
|
|
262
282
|
<div
|
|
@@ -467,20 +487,20 @@ export default class SessionWrapper extends Component {
|
|
|
467
487
|
const {
|
|
468
488
|
splitDirection,
|
|
469
489
|
infoPanelProps,
|
|
470
|
-
showInfo
|
|
490
|
+
showInfo,
|
|
491
|
+
infoPanelPinned
|
|
471
492
|
} = this.state
|
|
472
493
|
const { pane } = this.props.tab
|
|
473
494
|
const infoProps = {
|
|
495
|
+
infoPanelPinned,
|
|
474
496
|
...pick(this.props.config, ['host', 'port', 'saveTerminalLogToFile']),
|
|
475
497
|
...infoPanelProps,
|
|
476
498
|
appPath: this.props.appPath,
|
|
499
|
+
rightSidebarWidth: this.props.rightSidebarWidth,
|
|
477
500
|
showInfo,
|
|
478
501
|
tabsHeight: this.props.tabsHeight,
|
|
479
502
|
topMenuHeight: this.props.topMenuHeight,
|
|
480
|
-
|
|
481
|
-
// sessionId,
|
|
482
|
-
// isRemote: this.isRemote(),
|
|
483
|
-
// isActive: this.isActiveTerminal(),
|
|
503
|
+
toggleInfoPinned: this.toggleInfoPinned,
|
|
484
504
|
hideInfoPanel: this.hideInfoPanel
|
|
485
505
|
}
|
|
486
506
|
const cls = classnames(
|
|
@@ -346,7 +346,8 @@ class Sessions extends Component {
|
|
|
346
346
|
'pinnedQuickCommandBar',
|
|
347
347
|
'tabsHeight',
|
|
348
348
|
'appPath',
|
|
349
|
-
'topMenuHeight'
|
|
349
|
+
'topMenuHeight',
|
|
350
|
+
'rightSidebarWidth'
|
|
350
351
|
]),
|
|
351
352
|
config,
|
|
352
353
|
...pick(this, [
|
|
@@ -407,8 +408,23 @@ class Sessions extends Component {
|
|
|
407
408
|
}
|
|
408
409
|
|
|
409
410
|
renderSessionsWrap = () => {
|
|
411
|
+
const { leftSidebarWidth, openedSideBar } = this.props.store
|
|
412
|
+
const w = leftSidebarWidth + 43
|
|
413
|
+
const ptp = openedSideBar
|
|
414
|
+
? {
|
|
415
|
+
className: 'sessions',
|
|
416
|
+
style: {
|
|
417
|
+
marginLeft: `${w}px`
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
: {
|
|
421
|
+
className: 'sessions'
|
|
422
|
+
}
|
|
410
423
|
return (
|
|
411
|
-
<div
|
|
424
|
+
<div
|
|
425
|
+
{...ptp}
|
|
426
|
+
key='main-sess'
|
|
427
|
+
>
|
|
412
428
|
{this.renderSessions()}
|
|
413
429
|
</div>
|
|
414
430
|
)
|
|
@@ -373,11 +373,11 @@ export default class Sftp extends Component {
|
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
doCopy = (type, e) => {
|
|
376
|
-
this[type + 'Dom'].onCopy(
|
|
376
|
+
this[type + 'Dom'].onCopy(this.state.selectedFiles)
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
doCut = (type, e) => {
|
|
380
|
-
this[type + 'Dom'].onCut(
|
|
380
|
+
this[type + 'Dom'].onCut(this.state.selectedFiles)
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
doPaste = (type) => {
|
|
@@ -396,7 +396,7 @@ export default class Sftp extends Component {
|
|
|
396
396
|
}
|
|
397
397
|
const { type } = lastClickedFile
|
|
398
398
|
const { inputFocus, onDelete } = this
|
|
399
|
-
if (keyControlPressed(e) && keyPressed(e, '
|
|
399
|
+
if (keyControlPressed(e) && keyPressed(e, 'keyA') && !inputFocus) {
|
|
400
400
|
e.stopPropagation()
|
|
401
401
|
this.selectAll(type, e)
|
|
402
402
|
} else if (keyPressed(e, 'arrowdown') && !inputFocus) {
|
|
@@ -411,13 +411,13 @@ export default class Sftp extends Component {
|
|
|
411
411
|
} else if (keyPressed(e, 'enter') && !inputFocus && !onDelete) {
|
|
412
412
|
e.stopPropagation()
|
|
413
413
|
this.enter(type, e)
|
|
414
|
-
} else if (keyControlPressed(e) && keyPressed(e, '
|
|
414
|
+
} else if (keyControlPressed(e) && keyPressed(e, 'keyC') && !inputFocus) {
|
|
415
415
|
e.stopPropagation()
|
|
416
416
|
this.doCopy(type, e)
|
|
417
|
-
} else if (keyControlPressed(e) && keyPressed(e, '
|
|
417
|
+
} else if (keyControlPressed(e) && keyPressed(e, 'keyX') && !inputFocus) {
|
|
418
418
|
e.stopPropagation()
|
|
419
419
|
this.doCut(type, e)
|
|
420
|
-
} else if (keyControlPressed(e) && keyPressed(e, '
|
|
420
|
+
} else if (keyControlPressed(e) && keyPressed(e, 'keyV') && !inputFocus) {
|
|
421
421
|
e.stopPropagation()
|
|
422
422
|
this.doPaste(type, e)
|
|
423
423
|
} else if (keyPressed(e, 'f5')) {
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
modals
|
|
24
24
|
} from '../../common/constants'
|
|
25
25
|
import SideIcon from './side-icon'
|
|
26
|
+
import SidePanel from './side-panel'
|
|
26
27
|
import './sidebar.styl'
|
|
27
28
|
|
|
28
29
|
const { prefix } = window
|
|
@@ -91,7 +92,9 @@ export default class Sidebar extends Component {
|
|
|
91
92
|
showModal,
|
|
92
93
|
showInfoModal,
|
|
93
94
|
settingItem,
|
|
94
|
-
isSyncingSetting
|
|
95
|
+
isSyncingSetting,
|
|
96
|
+
leftSidebarWidth,
|
|
97
|
+
setLeftSidePanelWidth
|
|
95
98
|
} = store
|
|
96
99
|
const {
|
|
97
100
|
showUpgradeModal,
|
|
@@ -106,6 +109,16 @@ export default class Sidebar extends Component {
|
|
|
106
109
|
const themeActive = showSetting && settingTab === settingMap.terminalThemes
|
|
107
110
|
const historyActive = showSetting && settingTab === settingMap.history
|
|
108
111
|
const bookmarksActive = showSetting && settingTab === settingMap.bookmarks
|
|
112
|
+
const sideProps = openedSideBar
|
|
113
|
+
? {
|
|
114
|
+
className: 'sidebar-list',
|
|
115
|
+
style: {
|
|
116
|
+
width: `${leftSidebarWidth}px`
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
: {
|
|
120
|
+
className: 'sidebar-list'
|
|
121
|
+
}
|
|
109
122
|
return (
|
|
110
123
|
<div
|
|
111
124
|
className={`sidebar type-${openedSideBar}`}
|
|
@@ -210,8 +223,10 @@ export default class Sidebar extends Component {
|
|
|
210
223
|
}
|
|
211
224
|
</div>
|
|
212
225
|
<InfoModal store={store} />
|
|
213
|
-
<
|
|
214
|
-
|
|
226
|
+
<SidePanel
|
|
227
|
+
sideProps={sideProps}
|
|
228
|
+
setLeftSidePanelWidth={setLeftSidePanelWidth}
|
|
229
|
+
leftSidebarWidth={leftSidebarWidth}
|
|
215
230
|
>
|
|
216
231
|
<BookMarksWrap
|
|
217
232
|
store={store}
|
|
@@ -223,7 +238,7 @@ export default class Sidebar extends Component {
|
|
|
223
238
|
onMouseEnter={this.handleMouseEnterHistory}
|
|
224
239
|
onMouseLeave={this.handleMouseLeave}
|
|
225
240
|
/>
|
|
226
|
-
</
|
|
241
|
+
</SidePanel>
|
|
227
242
|
</div>
|
|
228
243
|
)
|
|
229
244
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PureComponent } from 'react'
|
|
2
|
+
export default class SidePanel extends PureComponent {
|
|
3
|
+
handleMousedown = (e) => {
|
|
4
|
+
this.dragStart = true
|
|
5
|
+
this.clientX = e.clientX
|
|
6
|
+
document.body.addEventListener('mouseup', this.handleMouseup)
|
|
7
|
+
document.body.addEventListener('mousemove', this.handleMousemove)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
handleMouseup = (e) => {
|
|
11
|
+
this.dragStart = false
|
|
12
|
+
const {
|
|
13
|
+
clientX
|
|
14
|
+
} = e
|
|
15
|
+
let nw = clientX - this.clientX + 300
|
|
16
|
+
if (nw < 343) {
|
|
17
|
+
nw = 343
|
|
18
|
+
} else if (nw > 600) {
|
|
19
|
+
nw = 600
|
|
20
|
+
}
|
|
21
|
+
this.props.setLeftSidePanelWidth(nw)
|
|
22
|
+
document.body.removeEventListener('mouseup', this.handleMouseup)
|
|
23
|
+
document.body.removeEventListener('mousemove', this.handleMousemove)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
handleMousemove = (e) => {
|
|
27
|
+
const {
|
|
28
|
+
clientX
|
|
29
|
+
} = e
|
|
30
|
+
const el = document.getElementById('side-panel')
|
|
31
|
+
const nw = clientX - this.clientX + this.props.leftSidebarWidth
|
|
32
|
+
el.style.width = nw + 'px'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
render () {
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
{...this.props.sideProps}
|
|
39
|
+
id='side-panel'
|
|
40
|
+
draggable={false}
|
|
41
|
+
>
|
|
42
|
+
<div
|
|
43
|
+
className='drag-handle'
|
|
44
|
+
onMouseDown={this.handleMousedown}
|
|
45
|
+
draggable={false}
|
|
46
|
+
/>
|
|
47
|
+
{this.props.children}
|
|
48
|
+
</div>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
animation-duration .2s
|
|
4
4
|
.sidebar-panel
|
|
5
5
|
position absolute
|
|
6
|
-
left
|
|
7
|
-
top
|
|
8
|
-
bottom
|
|
6
|
+
left 0
|
|
7
|
+
top 0
|
|
8
|
+
bottom 0
|
|
9
9
|
z-index 200
|
|
10
10
|
width 0
|
|
11
11
|
overflow-y scroll
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
.list-item-remove
|
|
16
16
|
display none !important
|
|
17
17
|
|
|
18
|
-
.pinned .sidebar-panel
|
|
19
|
-
bottom 0
|
|
20
18
|
.sidebar
|
|
21
19
|
position absolute
|
|
22
20
|
left 0
|
|
@@ -30,10 +28,10 @@
|
|
|
30
28
|
padding-right 0
|
|
31
29
|
.type-bookmarks
|
|
32
30
|
.bookmarks-panel
|
|
33
|
-
width
|
|
31
|
+
width 100%
|
|
34
32
|
.type-history
|
|
35
33
|
.history-panel
|
|
36
|
-
width
|
|
34
|
+
width 100%
|
|
37
35
|
.control-icon-text
|
|
38
36
|
color text
|
|
39
37
|
&:hover
|
|
@@ -50,11 +48,21 @@
|
|
|
50
48
|
&:hover
|
|
51
49
|
color text-light
|
|
52
50
|
.sidebar-list
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
position absolute
|
|
52
|
+
left 43px
|
|
53
|
+
top 45px
|
|
54
|
+
bottom 36px
|
|
55
|
+
z-index 200
|
|
56
|
+
width 0
|
|
57
|
+
border-top 5px solid main
|
|
57
58
|
|
|
59
|
+
.pinned
|
|
60
|
+
.sidebar-list
|
|
61
|
+
bottom 0
|
|
62
|
+
.drag-handle
|
|
63
|
+
display block
|
|
64
|
+
.sidebar-panel .pinned
|
|
65
|
+
color success
|
|
58
66
|
//btns
|
|
59
67
|
.btns
|
|
60
68
|
background main-dark
|
|
@@ -69,7 +77,15 @@
|
|
|
69
77
|
// background transparent
|
|
70
78
|
// color #aaa
|
|
71
79
|
// border-color #555
|
|
72
|
-
|
|
80
|
+
.drag-handle
|
|
81
|
+
position absolute
|
|
82
|
+
right 0
|
|
83
|
+
top 0
|
|
84
|
+
width 3px
|
|
85
|
+
bottom 0
|
|
86
|
+
cursor ew-resize
|
|
87
|
+
display none
|
|
88
|
+
z-index 201
|
|
73
89
|
// Hover.css (http://ianlunn.github.io/Hover/)
|
|
74
90
|
// Version: 2.3.2
|
|
75
91
|
// Author: Ian Lunn @IanLunn
|
|
@@ -23,6 +23,7 @@ import findParentBySel from '../../common/find-parent'
|
|
|
23
23
|
import WindowControl from './window-control'
|
|
24
24
|
import BookmarksList from '../sidebar/bookmark-select'
|
|
25
25
|
import AppDrag from './app-drag'
|
|
26
|
+
import classNames from 'classnames'
|
|
26
27
|
|
|
27
28
|
const { prefix } = window
|
|
28
29
|
const e = prefix('tabs')
|
|
@@ -176,16 +177,19 @@ export default class Tabs extends React.Component {
|
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
renderAddBtn = () => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
const cls = classNames(
|
|
181
|
+
'pointer tabs-add-btn font16',
|
|
182
|
+
{
|
|
183
|
+
empty: !this.props.tabs.length
|
|
184
|
+
}
|
|
185
|
+
)
|
|
182
186
|
return (
|
|
183
187
|
<Popover
|
|
184
188
|
content={this.renderMenus()}
|
|
185
189
|
>
|
|
186
190
|
<PlusCircleOutlined
|
|
187
191
|
title={e('openNewTerm')}
|
|
188
|
-
className=
|
|
192
|
+
className={cls}
|
|
189
193
|
onClick={() => this.props.addTab()}
|
|
190
194
|
/>
|
|
191
195
|
</Popover>
|
|
@@ -121,6 +121,10 @@
|
|
|
121
121
|
margin 10px 3px 0 3px
|
|
122
122
|
-webkit-app-region no-drag
|
|
123
123
|
color text
|
|
124
|
+
&.empty
|
|
125
|
+
font-size 20px
|
|
126
|
+
margin-left 20px
|
|
127
|
+
margin-top 20px
|
|
124
128
|
&:hover
|
|
125
129
|
color text-light
|
|
126
130
|
.tabs-extra
|
|
@@ -131,6 +135,7 @@
|
|
|
131
135
|
line-height 20px
|
|
132
136
|
z-index 20
|
|
133
137
|
-webkit-app-region no-drag
|
|
138
|
+
|
|
134
139
|
// .ant-btn
|
|
135
140
|
// background #333
|
|
136
141
|
// color #aaa
|
|
@@ -2,27 +2,26 @@
|
|
|
2
2
|
* info content module
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { PureComponent } from 'react'
|
|
5
6
|
import TerminalInfoBase from './base'
|
|
6
7
|
import TerminalInfoUp from './up'
|
|
7
8
|
import TerminalInfoNetwork from './network'
|
|
8
9
|
import TerminalInfoResource from './resource'
|
|
9
10
|
import TerminalInfoActivities from './activity'
|
|
10
11
|
import TerminalInfoDisk from './disk'
|
|
11
|
-
import { useState } from 'react'
|
|
12
12
|
import RunCmd from './run-cmd'
|
|
13
13
|
import {
|
|
14
|
-
sidebarWidth,
|
|
15
14
|
termControlHeight
|
|
16
15
|
} from '../../common/constants'
|
|
17
16
|
import { runCmd } from '../terminal/terminal-apis'
|
|
18
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
CloseCircleOutlined,
|
|
19
|
+
PushpinOutlined
|
|
20
|
+
} from '@ant-design/icons'
|
|
21
|
+
import classNames from 'classnames'
|
|
19
22
|
|
|
20
|
-
export default
|
|
21
|
-
|
|
22
|
-
return null
|
|
23
|
-
}
|
|
24
|
-
const [state, setter] = useState({
|
|
25
|
-
expand: false,
|
|
23
|
+
export default class TerminalInfoContent extends PureComponent {
|
|
24
|
+
state = {
|
|
26
25
|
uptime: '',
|
|
27
26
|
cpu: '',
|
|
28
27
|
mem: {},
|
|
@@ -30,72 +29,119 @@ export default function TerminalInfoContent (props) {
|
|
|
30
29
|
activities: [],
|
|
31
30
|
disks: [],
|
|
32
31
|
network: {}
|
|
33
|
-
})
|
|
34
|
-
function setState (ext) {
|
|
35
|
-
setter(s => {
|
|
36
|
-
return Object.assign({}, s, ext)
|
|
37
|
-
})
|
|
38
32
|
}
|
|
39
|
-
|
|
33
|
+
|
|
34
|
+
setStateRef = (...args) => {
|
|
35
|
+
this.setState(...args)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
togglePin = () => {
|
|
39
|
+
this.props.toggleInfoPinned()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
handleMousedown = (e) => {
|
|
43
|
+
this.dragStart = true
|
|
44
|
+
this.clientX = e.clientX
|
|
45
|
+
document.body.addEventListener('mouseup', this.handleMouseup)
|
|
46
|
+
document.body.addEventListener('mousemove', this.handleMousemove)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
handleMouseup = (e) => {
|
|
50
|
+
this.dragStart = false
|
|
51
|
+
const {
|
|
52
|
+
clientX
|
|
53
|
+
} = e
|
|
54
|
+
let nw = this.clientX - clientX + this.props.rightSidebarWidth
|
|
55
|
+
if (nw < 400) {
|
|
56
|
+
nw = 400
|
|
57
|
+
} else if (nw > 1000) {
|
|
58
|
+
nw = 1000
|
|
59
|
+
}
|
|
60
|
+
window.store.setRightSidePanelWidth(nw)
|
|
61
|
+
document.body.removeEventListener('mouseup', this.handleMouseup)
|
|
62
|
+
document.body.removeEventListener('mousemove', this.handleMousemove)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
handleMousemove = (e) => {
|
|
66
|
+
const {
|
|
67
|
+
clientX
|
|
68
|
+
} = e
|
|
69
|
+
const el = document.getElementById('info-panel-wrap')
|
|
70
|
+
const nw = this.clientX - clientX + this.props.rightSidebarWidth
|
|
71
|
+
console.log(nw, this.clientX, clientX, this.props.rightSidebarWidth)
|
|
72
|
+
el.style.width = nw + 'px'
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
killProcess = async (id) => {
|
|
40
76
|
const {
|
|
41
77
|
pid,
|
|
42
78
|
sessionId
|
|
43
|
-
} = props
|
|
79
|
+
} = this.props
|
|
44
80
|
const cmd = `kill ${id}`
|
|
45
81
|
runCmd(pid, sessionId, cmd)
|
|
46
82
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
83
|
+
|
|
84
|
+
render () {
|
|
85
|
+
const { props, state } = this
|
|
86
|
+
if (!props.showInfo) {
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const pops = {
|
|
91
|
+
onClick: props.hideInfoPanel,
|
|
92
|
+
className: 'pointer font20 hide-info-panel-wrap'
|
|
93
|
+
}
|
|
94
|
+
const pops2 = {
|
|
95
|
+
onClick: this.togglePin,
|
|
96
|
+
className: 'pointer font20 toggle-info-panel-wrap mg1l'
|
|
97
|
+
}
|
|
98
|
+
const pops1 = {
|
|
99
|
+
className: classNames(
|
|
100
|
+
'info-panel-wrap',
|
|
63
101
|
{
|
|
64
|
-
|
|
65
|
-
? (
|
|
66
|
-
<RightCircleOutlined
|
|
67
|
-
onClick={() => setState({
|
|
68
|
-
expand: false
|
|
69
|
-
})}
|
|
70
|
-
className='pointer font20 mg1l'
|
|
71
|
-
/>
|
|
72
|
-
)
|
|
73
|
-
: (
|
|
74
|
-
<LeftCircleOutlined
|
|
75
|
-
onClick={() => setState({
|
|
76
|
-
expand: true
|
|
77
|
-
})}
|
|
78
|
-
className='pointer font20 mg1l'
|
|
79
|
-
/>
|
|
80
|
-
)
|
|
102
|
+
'info-panel-wrap-pin': props.infoPanelPinned
|
|
81
103
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
104
|
+
),
|
|
105
|
+
id: 'info-panel-wrap',
|
|
106
|
+
draggable: false,
|
|
107
|
+
style: {
|
|
108
|
+
width: props.rightSidebarWidth,
|
|
109
|
+
top: props.topMenuHeight + props.tabsHeight + termControlHeight - 4
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return (
|
|
113
|
+
<div
|
|
114
|
+
{...pops1}
|
|
115
|
+
>
|
|
116
|
+
<div
|
|
117
|
+
className='drag-handle'
|
|
118
|
+
onMouseDown={this.handleMousedown}
|
|
119
|
+
draggable={false}
|
|
94
120
|
/>
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
<div className='pd2t pd2x'>
|
|
122
|
+
<CloseCircleOutlined
|
|
123
|
+
{...pops}
|
|
124
|
+
/>
|
|
125
|
+
<PushpinOutlined
|
|
126
|
+
{...pops2}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
<div className='pd2'>
|
|
130
|
+
<TerminalInfoBase {...props} {...state} />
|
|
131
|
+
<TerminalInfoUp {...props} {...state} />
|
|
132
|
+
<TerminalInfoResource
|
|
133
|
+
{...props} {...state}
|
|
134
|
+
/>
|
|
135
|
+
<TerminalInfoActivities
|
|
136
|
+
{...props}
|
|
137
|
+
{...state}
|
|
138
|
+
killProcess={this.killProcess}
|
|
139
|
+
/>
|
|
140
|
+
<TerminalInfoNetwork {...props} {...state} />
|
|
141
|
+
<TerminalInfoDisk {...props} {...state} />
|
|
142
|
+
<RunCmd {...props} setState={this.setStateRef} />
|
|
143
|
+
</div>
|
|
98
144
|
</div>
|
|
99
|
-
|
|
100
|
-
|
|
145
|
+
)
|
|
146
|
+
}
|
|
101
147
|
}
|
|
@@ -4,17 +4,20 @@
|
|
|
4
4
|
&:hover
|
|
5
5
|
color text
|
|
6
6
|
.info-panel-wrap
|
|
7
|
-
position
|
|
7
|
+
position absolute
|
|
8
8
|
right 0
|
|
9
9
|
top 100px
|
|
10
10
|
bottom 0
|
|
11
11
|
width 500px
|
|
12
|
-
background main
|
|
12
|
+
background main-light
|
|
13
13
|
color text
|
|
14
|
-
box-shadow 0px 3px 3px 3px alpha(main, .25)
|
|
15
14
|
z-index 100
|
|
16
15
|
overflow-y scroll
|
|
17
16
|
opacity .9
|
|
17
|
+
.drag-handle
|
|
18
|
+
left 0
|
|
19
|
+
right auto
|
|
20
|
+
display block
|
|
18
21
|
.terminal-info-section
|
|
19
22
|
padding 10px 0
|
|
20
23
|
.terminal-info-act
|
|
@@ -26,4 +29,7 @@
|
|
|
26
29
|
.activity-item-copy
|
|
27
30
|
display none
|
|
28
31
|
&:hover .activity-item-copy
|
|
29
|
-
display inline
|
|
32
|
+
display inline
|
|
33
|
+
.info-panel-wrap-pin
|
|
34
|
+
.toggle-info-panel-wrap
|
|
35
|
+
color success
|
package/client/store/common.js
CHANGED
|
@@ -8,8 +8,11 @@ import postMessage from '../common/post-msg'
|
|
|
8
8
|
import {
|
|
9
9
|
commonActions,
|
|
10
10
|
tabActions,
|
|
11
|
-
modals
|
|
11
|
+
modals,
|
|
12
|
+
leftSidebarWidthKey,
|
|
13
|
+
rightSidebarWidthKey
|
|
12
14
|
} from '../common/constants'
|
|
15
|
+
import * as ls from '../common/safe-local-storage'
|
|
13
16
|
|
|
14
17
|
export default Store => {
|
|
15
18
|
Store.prototype.storeAssign = function (updates) {
|
|
@@ -137,4 +140,14 @@ export default Store => {
|
|
|
137
140
|
...update
|
|
138
141
|
})
|
|
139
142
|
}
|
|
143
|
+
|
|
144
|
+
Store.prototype.setLeftSidePanelWidth = function (v) {
|
|
145
|
+
ls.setItem(leftSidebarWidthKey, v)
|
|
146
|
+
window.store.leftSidebarWidth = v
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
Store.prototype.setRightSidePanelWidth = function (v) {
|
|
150
|
+
ls.setItem(rightSidebarWidthKey, v)
|
|
151
|
+
window.store.rightSidebarWidth = v
|
|
152
|
+
}
|
|
140
153
|
}
|
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
batchInputLsKey,
|
|
16
16
|
expandedKeysLsKey,
|
|
17
17
|
checkedKeysLsKey,
|
|
18
|
-
localAddrBookmarkLsKey
|
|
18
|
+
localAddrBookmarkLsKey,
|
|
19
|
+
leftSidebarWidthKey,
|
|
20
|
+
rightSidebarWidthKey
|
|
19
21
|
} from '../common/constants'
|
|
20
22
|
import { buildDefaultThemes, buildNewTheme } from '../common/terminal-theme'
|
|
21
23
|
import * as ls from '../common/safe-local-storage'
|
|
@@ -141,6 +143,8 @@ export default () => {
|
|
|
141
143
|
|
|
142
144
|
// sidebar
|
|
143
145
|
openedSideBar: ls.getItem(openedSidebarKey),
|
|
146
|
+
leftSidebarWidth: parseInt(ls.getItem(leftSidebarWidthKey), 10) || 300,
|
|
147
|
+
rightSidebarWidth: parseInt(ls.getItem(rightSidebarWidthKey), 10) || 500,
|
|
144
148
|
menuOpened: false,
|
|
145
149
|
pinned: ls.getItem(sidebarPinnedKey) === 'true',
|
|
146
150
|
|
package/client/store/setting.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* setting modal
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { find, isEqual, pick, without
|
|
5
|
+
import { find, isEqual, pick, without } from 'lodash-es'
|
|
6
6
|
import {
|
|
7
7
|
message
|
|
8
8
|
} from 'antd'
|
|
@@ -113,14 +113,8 @@ export default Store => {
|
|
|
113
113
|
pick(j, without(keysj, 'id'))
|
|
114
114
|
)
|
|
115
115
|
})
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
} else {
|
|
119
|
-
const index = findIndex(history, f => f.id === existItem.id)
|
|
120
|
-
history.splice(index, 1)
|
|
121
|
-
history.unshift(existItem)
|
|
122
|
-
store.setItems('history', history)
|
|
123
|
-
}
|
|
116
|
+
history.unshift(existItem)
|
|
117
|
+
store.setItems('history', history)
|
|
124
118
|
}
|
|
125
119
|
|
|
126
120
|
Store.prototype.openSetting = function () {
|