@electerm/electerm-react 1.40.20 → 1.50.21

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.
Files changed (96) hide show
  1. package/client/common/constants.js +57 -7
  2. package/client/common/new-terminal.js +2 -2
  3. package/client/components/auth/login.jsx +34 -57
  4. package/client/components/batch-op/batch-op.jsx +12 -11
  5. package/client/components/bookmark-form/index.jsx +2 -2
  6. package/client/components/bookmark-form/ssh-form.jsx +4 -1
  7. package/client/components/bookmark-form/tree-delete.jsx +5 -5
  8. package/client/components/context-menu/boomarks.jsx +8 -12
  9. package/client/components/context-menu/context-menu.jsx +10 -10
  10. package/client/components/context-menu/history.jsx +21 -24
  11. package/client/components/context-menu/menu-btn.jsx +11 -11
  12. package/client/components/context-menu/tabs.jsx +15 -19
  13. package/client/components/context-menu/zoom.jsx +25 -29
  14. package/client/components/footer/footer-entry.jsx +56 -56
  15. package/client/components/icons/split-icons.jsx +77 -0
  16. package/client/components/layout/layout-alg.js +260 -0
  17. package/client/components/layout/layout-item.jsx +26 -0
  18. package/client/components/layout/layout.jsx +167 -0
  19. package/client/components/layout/layout.styl +5 -0
  20. package/client/components/layout/layouts.jsx +71 -0
  21. package/client/components/layout/session-size-alg.js +31 -0
  22. package/client/components/main/main.jsx +183 -109
  23. package/client/components/main/wrapper.styl +2 -4
  24. package/client/components/profile/profile-list.jsx +1 -3
  25. package/client/components/profile/profile-transport-mod.jsx +1 -1
  26. package/client/components/profile/profile-transport.jsx +6 -9
  27. package/client/components/quick-commands/quick-command-transport.jsx +6 -9
  28. package/client/components/quick-commands/quick-commands-box.jsx +144 -153
  29. package/client/components/quick-commands/quick-commands-select.jsx +10 -3
  30. package/client/components/rdp/rdp-session.jsx +3 -23
  31. package/client/components/rdp/resolution-edit.jsx +40 -42
  32. package/client/components/session/session.jsx +62 -317
  33. package/client/components/session/session.styl +1 -5
  34. package/client/components/session/sessions.jsx +99 -105
  35. package/client/components/setting-panel/bookmark-tree-list.jsx +1 -1
  36. package/client/components/setting-panel/setting-common.jsx +6 -4
  37. package/client/components/setting-panel/setting-modal.jsx +31 -31
  38. package/client/components/setting-panel/start-session-select.jsx +4 -4
  39. package/client/components/setting-panel/tab-settings.jsx +27 -5
  40. package/client/components/setting-sync/data-import.jsx +36 -39
  41. package/client/components/setting-sync/setting-sync-form.jsx +9 -9
  42. package/client/components/setting-sync/setting-sync.jsx +50 -52
  43. package/client/components/sftp/address-bookmark.jsx +57 -58
  44. package/client/components/sftp/confirm-modal-store.jsx +34 -40
  45. package/client/components/sftp/file-item.jsx +14 -3
  46. package/client/components/sftp/file-mode-modal.jsx +3 -0
  47. package/client/components/sftp/list-table-ui.jsx +4 -4
  48. package/client/components/sftp/sftp-entry.jsx +2 -2
  49. package/client/components/sftp/transfer-conflict-store.jsx +13 -17
  50. package/client/components/sftp/transport-action-store.jsx +38 -31
  51. package/client/components/sftp/transports-action-store.jsx +3 -3
  52. package/client/components/sftp/transports-ui-store.jsx +18 -23
  53. package/client/components/shortcuts/shortcut-handler.js +1 -0
  54. package/client/components/shortcuts/shortcuts.jsx +9 -12
  55. package/client/components/side-panel-r/right-side-panel.styl +40 -0
  56. package/client/components/side-panel-r/side-panel-r.jsx +102 -0
  57. package/client/components/sidebar/bookmark-select.jsx +40 -40
  58. package/client/components/sidebar/bookmark.jsx +63 -65
  59. package/client/components/sidebar/history.jsx +53 -50
  60. package/client/components/sidebar/index.jsx +195 -184
  61. package/client/components/sidebar/info-modal.jsx +202 -202
  62. package/client/components/sidebar/sidebar.styl +8 -2
  63. package/client/components/sidebar/transfer-history-modal.jsx +95 -100
  64. package/client/components/sidebar/transfer-list-control.jsx +2 -2
  65. package/client/components/sidebar/transfer-list.jsx +45 -42
  66. package/client/components/sidebar/transfer-modal.jsx +49 -52
  67. package/client/components/sidebar/transport-ui.jsx +1 -1
  68. package/client/components/tabs/index.jsx +261 -49
  69. package/client/components/tabs/tab.jsx +60 -65
  70. package/client/components/tabs/tabs.styl +6 -1
  71. package/client/components/tabs/window-control.jsx +46 -48
  72. package/client/components/terminal/index.jsx +101 -104
  73. package/client/components/terminal/term-search.jsx +26 -24
  74. package/client/components/terminal-info/run-cmd.jsx +0 -25
  75. package/client/components/terminal-info/terminal-info.jsx +60 -0
  76. package/client/components/terminal-info/terminal-info.styl +1 -1
  77. package/client/components/tree-list/bookmark-transport.jsx +8 -9
  78. package/client/components/tree-list/tree-list.jsx +36 -26
  79. package/client/components/vnc/vnc-session.jsx +1 -6
  80. package/client/store/common.js +1 -1
  81. package/client/store/event.js +2 -2
  82. package/client/store/index.js +21 -32
  83. package/client/store/init-state.js +15 -3
  84. package/client/store/load-data.js +1 -1
  85. package/client/store/quick-command.js +4 -4
  86. package/client/store/session.js +1 -1
  87. package/client/store/setting.js +9 -5
  88. package/client/store/system-menu.js +1 -10
  89. package/client/store/tab.js +66 -1
  90. package/client/store/transfer-list.js +5 -6
  91. package/client/store/watch.js +11 -6
  92. package/package.json +1 -1
  93. package/client/components/common/react-subx.jsx +0 -1
  94. package/client/components/common/resize-wrap.jsx +0 -222
  95. package/client/components/common/resize-wrap.styl +0 -9
  96. package/client/components/terminal-info/content.jsx +0 -152
@@ -7,91 +7,43 @@ import Sftp from '../sftp/sftp-entry'
7
7
  import RdpSession from '../rdp/rdp-session'
8
8
  import VncSession from '../vnc/vnc-session'
9
9
  import {
10
- BorderVerticleOutlined,
11
- BorderHorizontalOutlined,
12
- CloseSquareFilled,
13
10
  SearchOutlined,
14
11
  FullscreenOutlined,
15
12
  PaperClipOutlined,
16
- CloseOutlined,
17
- QuestionCircleOutlined
13
+ CloseOutlined
18
14
  } from '@ant-design/icons'
19
15
  import {
20
16
  Tooltip
21
17
  } from 'antd'
22
- import { last, findIndex, pick } from 'lodash-es'
18
+ import { pick } from 'lodash-es'
23
19
  import generate from '../../common/uid'
24
20
  import copy from 'json-deep-copy'
25
21
  import classnames from 'classnames'
26
22
  import {
27
- quickCommandBoxHeight,
28
- terminalSplitDirectionMap,
29
23
  termControlHeight,
30
24
  paneMap,
31
- footerHeight,
32
25
  terminalActions,
33
26
  connectionMap,
34
27
  terminalRdpType,
35
28
  terminalVncType
36
29
  } from '../../common/constants'
37
- import ResizeWrap from '../common/resize-wrap'
38
30
  import safeName from '../../common/safe-name'
39
- import TerminalInfoContent from '../terminal-info/content'
40
- import uid from '../../common/id-with-stamp'
41
- import Link from '../common/external-link'
42
31
  import postMessage from '../../common/post-msg'
43
32
  import './session.styl'
44
33
 
45
- const rebuildPosition = terminals => {
46
- const indexs = terminals.map(t => t.position).sort((a, b) => a - b)
47
- const indexMap = indexs.reduce((prev, pos, index) => {
48
- return {
49
- ...prev,
50
- [pos]: index * 10
51
- }
52
- }, {})
53
- return terminals.map(t => {
54
- return {
55
- ...t,
56
- position: indexMap[t.position]
57
- }
58
- })
59
- }
60
-
61
- const getPrevTerminal = terminals => {
62
- return last(terminals)
63
- }
64
-
65
34
  const e = window.translate
66
35
 
67
36
  export default class SessionWrapper extends Component {
68
37
  constructor (props) {
69
38
  super(props)
70
- const id = uid()
71
- const {
72
- terminals = [
73
- {
74
- id,
75
- position: 0
76
- }
77
- ]
78
- } = props.tab
79
- const activeSplitId = terminals[0].id
80
39
  this.state = {
81
- pid: null,
82
40
  enableSftp: false,
83
41
  cwd: '',
84
42
  sftpPathFollowSsh: !!props.config.sftpPathFollowSsh,
85
- splitDirection: terminalSplitDirectionMap.horizontal,
86
- activeSplitId,
87
- infoPanelPinned: false,
88
43
  key: Math.random(),
89
44
  sessionOptions: null,
90
45
  sessionId: generate(),
91
- terminals: terminals.slice(0, 1),
92
- delKeyPressed: false,
93
- showInfo: false,
94
- infoPanelProps: {}
46
+ delKeyPressed: false
95
47
  }
96
48
  }
97
49
 
@@ -125,33 +77,9 @@ export default class SessionWrapper extends Component {
125
77
  window.store.dismissDelKeyTip()
126
78
  }
127
79
 
128
- setCwd = (cwd, tid) => {
129
- this.setState(old => {
130
- return {
131
- cwd,
132
- terminals: old.terminals.map(t => {
133
- if (t.id === tid) {
134
- return {
135
- ...t,
136
- cwd
137
- }
138
- }
139
- return t
140
- })
141
- }
142
- })
143
- }
144
-
145
- handleShowInfo = (infoPanelProps) => {
80
+ setCwd = (cwd) => {
146
81
  this.setState({
147
- showInfo: true,
148
- infoPanelProps
149
- })
150
- }
151
-
152
- toggleInfoPinned = () => {
153
- this.setState({
154
- infoPanelPinned: !this.state.infoPanelPinned
82
+ cwd
155
83
  })
156
84
  }
157
85
 
@@ -161,22 +89,13 @@ export default class SessionWrapper extends Component {
161
89
  })
162
90
  }
163
91
 
164
- hideInfoPanel = () => {
165
- this.setState({
166
- showInfo: false
167
- })
168
- }
169
-
170
92
  computeHeight = () => {
171
93
  const {
172
- pinnedQuickCommandBar,
173
94
  tabsHeight
174
95
  } = this.props
175
96
  return this.props.height -
176
97
  tabsHeight -
177
- footerHeight -
178
- termControlHeight -
179
- (pinnedQuickCommandBar ? quickCommandBoxHeight : 0)
98
+ termControlHeight
180
99
  }
181
100
 
182
101
  editTab = (up) => {
@@ -202,124 +121,35 @@ export default class SessionWrapper extends Component {
202
121
  this.editTab(update)
203
122
  }
204
123
 
205
- setSessionState = data => {
206
- this.setState(data)
207
- if (data.pid) {
208
- this.editTab({
209
- pid: data.pid
210
- })
211
- }
212
- }
213
-
214
- handleSplit = (e, id) => {
215
- let terminals = copy(this.state.terminals)
216
- let index = findIndex(terminals, t => t.id === id)
217
- if (index === -1) {
218
- index = terminals.length
219
- } else {
220
- index = index + 1
221
- }
222
- terminals.push({
223
- id: uid(),
224
- position: terminals[index - 1].position + 5
225
- })
226
- terminals = rebuildPosition(terminals)
227
- this.setState({
228
- terminals
229
- }, this.updateTab)
230
- }
231
-
232
124
  updateTab = () => {
233
- const terminals = copy(this.state.terminals)
234
125
  this.editTab(
235
126
  {
236
- sessionId: this.state.sessionId,
237
- terminals
127
+ sessionId: this.state.sessionId
238
128
  }
239
129
  )
240
130
  }
241
131
 
242
- delSplit = (splitId = this.state.activeSplitId) => {
243
- const { terminals } = this.state
244
- let newTerms = terminals.filter(t => t.id !== splitId)
245
- if (!newTerms.length) {
246
- return this.props.delTab(
247
- this.props.tab.id
248
- )
249
- }
250
- newTerms = rebuildPosition(newTerms)
251
- const newActiveId = getPrevTerminal(newTerms).id
252
- this.setState({
253
- terminals: newTerms,
254
- activeSplitId: newActiveId
255
- }, this.updateTab)
256
- window.store.focus()
257
- }
258
-
259
- handleChangeDirection = () => {
260
- const { splitDirection } = this.state
261
- this.setState({
262
- splitDirection: splitDirection === terminalSplitDirectionMap.horizontal
263
- ? terminalSplitDirectionMap.vertical
264
- : terminalSplitDirectionMap.horizontal
265
- })
266
- }
267
-
268
- setActive = activeSplitId => {
269
- const up = {
270
- activeSplitId
271
- }
272
- this.setState(up)
273
- }
274
-
275
132
  computePosition = (index) => {
276
- const len = this.state.terminals.length || 1
277
133
  const windowWidth = this.getWidth()
278
- const { splitDirection } = this.state
279
- const isHori = splitDirection === terminalSplitDirectionMap.horizontal
280
134
  const heightAll = this.computeHeight()
281
- const width = isHori
282
- ? windowWidth / len
283
- : windowWidth
284
- const height = isHori
285
- ? heightAll
286
- : heightAll / len
287
- const left = isHori
288
- ? index * width
289
- : 0
290
- const top = isHori
291
- ? 0
292
- : index * height
293
135
  return {
294
- height,
295
- width,
296
- left,
297
- top
136
+ height: heightAll,
137
+ width: windowWidth,
138
+ left: 0,
139
+ top: 0
298
140
  }
299
141
  }
300
142
 
301
143
  getWidth = () => {
302
- const {
303
- infoPanelPinned,
304
- showInfo
305
- } = this.state
306
- const { rightSidebarWidth, width, leftSidebarWidth, pinned, openedSideBar } = this.props
307
- const rt = infoPanelPinned && showInfo ? rightSidebarWidth : 0
308
- const lt = pinned && openedSideBar ? leftSidebarWidth : 0
309
- return width - rt - lt - 42
144
+ return this.props.width
310
145
  }
311
146
 
312
147
  getWidthSftp = () => {
313
- const { width, leftSidebarWidth, pinned, openedSideBar } = this.props
314
- const lt = pinned && openedSideBar ? leftSidebarWidth : 0
315
- return width - lt - 42
148
+ return this.props.width
316
149
  }
317
150
 
318
151
  renderTerminals = () => {
319
152
  const {
320
- terminals,
321
- activeSplitId,
322
- splitDirection,
323
153
  sessionOptions,
324
154
  sessionId,
325
155
  sftpPathFollowSsh
@@ -347,8 +177,7 @@ export default class SessionWrapper extends Component {
347
177
  ...pick(
348
178
  this,
349
179
  [
350
- 'fullscreenIcon',
351
- 'setSessionState'
180
+ 'fullscreenIcon'
352
181
  ])
353
182
  }
354
183
  if (type === terminalVncType) {
@@ -371,6 +200,21 @@ export default class SessionWrapper extends Component {
371
200
  const { tab } = this.props
372
201
  const width = this.getWidth()
373
202
  const themeConfig = copy(window.store.getThemeConfig())
203
+ const logName = safeName(`${tab.title ? tab.title + '_' : ''}${tab.host ? tab.host + '_' : ''}${tab.id}`)
204
+ const pops = {
205
+ ...this.props,
206
+ sftpPathFollowSsh,
207
+ themeConfig,
208
+ pane,
209
+ ...pick(
210
+ this,
211
+ [
212
+ 'onChangePane',
213
+ 'setCwd',
214
+ 'onDelKeyPressed'
215
+ ]),
216
+ ...this.computePosition()
217
+ }
374
218
  return (
375
219
  <div
376
220
  className={cls}
@@ -379,48 +223,13 @@ export default class SessionWrapper extends Component {
379
223
  height
380
224
  }}
381
225
  >
382
- <ResizeWrap
383
- direction={splitDirection}
384
- tab={tab}
385
- >
386
- {
387
- terminals.map((t, index) => {
388
- const logName = safeName(`${tab.title ? tab.title + '_' : ''}${tab.host ? tab.host + '_' : ''}${t.id}`)
389
- const pops = {
390
- ...this.props,
391
- ...t,
392
- activeSplitId,
393
- sftpPathFollowSsh,
394
- themeConfig,
395
- pane,
396
- ...pick(
397
- this,
398
- [
399
- 'setActive',
400
- 'handleSplit',
401
- 'delSplit',
402
- 'setSessionState',
403
- 'handleShowInfo',
404
- 'onChangePane',
405
- 'hideInfoPanel',
406
- 'setCwd',
407
- 'onDelKeyPressed'
408
- ]),
409
- ...this.computePosition(t.position / 10)
410
- }
411
- return (
412
- <Term
413
- key={t.id}
414
- logName={logName}
415
- sessionId={sessionId}
416
- terminalIndex={index}
417
- sessionOptions={sessionOptions}
418
- {...pops}
419
- />
420
- )
421
- })
422
- }
423
- </ResizeWrap>
226
+ <Term
227
+ key={tab.id}
228
+ logName={logName}
229
+ sessionId={sessionId}
230
+ sessionOptions={sessionOptions}
231
+ {...pops}
232
+ />
424
233
  </div>
425
234
  )
426
235
  }
@@ -429,29 +238,28 @@ export default class SessionWrapper extends Component {
429
238
  const {
430
239
  sessionOptions,
431
240
  sessionId,
432
- pid,
433
241
  enableSftp,
434
242
  sftpPathFollowSsh,
435
243
  cwd
436
244
  } = this.state
437
- const { pane, type } = this.props.tab
245
+ const { pane, type, id } = this.props.tab
438
246
  if (type === terminalRdpType) {
439
247
  return null
440
248
  }
441
- const height = this.computeHeight()
249
+ const height = this.computeHeight(pane)
442
250
  const cls = pane === paneMap.terminal
443
251
  ? 'hide'
444
252
  : ''
445
253
  const exts = {
254
+ ...this.props,
446
255
  sftpPathFollowSsh,
447
256
  cwd,
448
- pid,
257
+ pid: id,
449
258
  enableSftp,
450
259
  sessionOptions,
451
260
  height,
452
261
  sessionId,
453
262
  pane,
454
- ...this.props,
455
263
  width: this.getWidthSftp()
456
264
  }
457
265
  return (
@@ -470,7 +278,7 @@ export default class SessionWrapper extends Component {
470
278
  handleOpenSearch = () => {
471
279
  postMessage({
472
280
  action: terminalActions.openTerminalSearch,
473
- activeSplitId: this.state.activeSplitId
281
+ currentTabId: this.props.tab.id
474
282
  })
475
283
  }
476
284
 
@@ -513,8 +321,22 @@ export default class SessionWrapper extends Component {
513
321
  )
514
322
  }
515
323
 
324
+ renderTermControls = () => {
325
+ const { props } = this
326
+ const { pane } = props.tab
327
+ if (pane !== paneMap.terminal) {
328
+ return null
329
+ }
330
+ return (
331
+ <div className='fright term-controls'>
332
+ {this.fullscreenIcon()}
333
+ {this.renderSearchIcon()}
334
+ </div>
335
+ )
336
+ }
337
+
516
338
  renderControl = () => {
517
- const { splitDirection, terminals, sftpPathFollowSsh } = this.state
339
+ const { sftpPathFollowSsh } = this.state
518
340
  const { props } = this
519
341
  const { pane, enableSsh, type } = props.tab
520
342
  if (type === terminalRdpType || type === terminalVncType) {
@@ -523,16 +345,6 @@ export default class SessionWrapper extends Component {
523
345
  const termType = props.tab?.type
524
346
  const isSsh = props.tab.authType
525
347
  const isLocal = !isSsh && (termType === connectionMap.local || !termType)
526
- const isHori = splitDirection === terminalSplitDirectionMap.horizontal
527
- const cls1 = 'mg1r icon-split pointer iblock spliter'
528
- const cls2 = 'icon-direction pointer iblock spliter'
529
- const Icon1 = isHori
530
- ? BorderHorizontalOutlined
531
- : BorderVerticleOutlined
532
- const Icon2 = !isHori
533
- ? BorderHorizontalOutlined
534
- : BorderVerticleOutlined
535
- const hide = terminals.length < 2
536
348
  const types = [
537
349
  paneMap.terminal,
538
350
  paneMap.fileManager
@@ -543,18 +355,7 @@ export default class SessionWrapper extends Component {
543
355
  if (isSsh || isLocal) {
544
356
  controls.push(isSsh ? paneMap.sftp : paneMap.fileManager)
545
357
  }
546
- const checkTxt = (
547
- <div>
548
- <span>{e('sftpPathFollowSsh')}</span>
549
- <span className='mg1l color-red'>[Beta]</span>
550
- <Link
551
- to='https://github.com/electerm/electerm/wiki/Warning-about-sftp-follow-ssh-path-function'
552
- className='mg1l'
553
- >
554
- Wiki <QuestionCircleOutlined />
555
- </Link>
556
- </div>
557
- )
358
+ const checkTxt = e('sftpPathFollowSsh') + ' [Beta]'
558
359
  const checkProps = {
559
360
  onClick: this.toggleCheckSftpPathFollowSsh,
560
361
  className: classnames(
@@ -600,7 +401,7 @@ export default class SessionWrapper extends Component {
600
401
  }
601
402
  </div>
602
403
  {
603
- (isSsh && enableSsh !== false) || isLocal
404
+ (isSsh && enableSsh) || isLocal
604
405
  ? (
605
406
  <Tooltip title={checkTxt}>
606
407
  <span {...checkProps}>
@@ -613,69 +414,16 @@ export default class SessionWrapper extends Component {
613
414
  {
614
415
  this.renderDelTip(pane === paneMap.terminal)
615
416
  }
616
- {
617
- pane === paneMap.terminal
618
- ? (
619
- <div className='fright term-controls'>
620
- {this.fullscreenIcon()}
621
- {this.renderSearchIcon()}
622
- {
623
- hide
624
- ? null
625
- : (
626
- <CloseSquareFilled
627
- className='mg1r icon-trash font16 iblock pointer spliter'
628
- onClick={() => this.delSplit()}
629
- title={e('del')}
630
- />
631
- )
632
- }
633
- <Tooltip
634
- title={`${e('split')}`}
635
- placement='bottomLeft'
636
- >
637
- <Icon1
638
- className={cls1}
639
- onClick={this.handleSplit}
640
- />
641
- </Tooltip>
642
- <Tooltip
643
- title={e('changeDirection')}
644
- placement='bottomLeft'
645
- >
646
- <Icon2
647
- className={cls2}
648
- onClick={this.handleChangeDirection}
649
- />
650
- </Tooltip>
651
- </div>
652
- )
653
- : null
654
- }
417
+ {this.renderTermControls()}
655
418
  </div>
656
419
  )
657
420
  }
658
421
 
659
422
  render () {
660
423
  const {
661
- splitDirection,
662
- infoPanelProps,
663
- showInfo,
664
- infoPanelPinned
424
+ splitDirection
665
425
  } = this.state
666
- const { pane } = this.props.tab
667
- const infoProps = {
668
- infoPanelPinned,
669
- ...pick(this.props.config, ['host', 'port', 'saveTerminalLogToFile', 'terminalInfos']),
670
- ...infoPanelProps,
671
- appPath: this.props.appPath,
672
- rightSidebarWidth: this.props.rightSidebarWidth,
673
- showInfo,
674
- tabsHeight: this.props.tabsHeight,
675
- topMenuHeight: this.props.topMenuHeight,
676
- toggleInfoPinned: this.toggleInfoPinned,
677
- hideInfoPanel: this.hideInfoPanel
678
- }
426
+ const { pane, id } = this.props.tab
679
427
  const cls = classnames(
680
428
  'term-sftp-box',
681
429
  pane,
@@ -690,14 +438,11 @@ export default class SessionWrapper extends Component {
690
438
  return (
691
439
  <div
692
440
  className={cls}
693
- id={`is-${this.props.tab.id}`}
441
+ id={`is-${id}`}
694
442
  >
695
443
  {this.renderControl()}
696
444
  {this.renderTerminals()}
697
445
  {this.renderSftp()}
698
- <TerminalInfoContent
699
- {...infoProps}
700
- />
701
446
  </div>
702
447
  )
703
448
  }
@@ -32,11 +32,7 @@
32
32
  &.active
33
33
  .type-tab-line
34
34
  display inline-block
35
- #container
36
- .sftp-follow-ssh-icon
37
- &:hover
38
- &.active
39
- color red
35
+
40
36
  .is-transporting
41
37
  .type-tab.sftp
42
38
  .type-tab-line