@electerm/electerm-react 1.60.18 → 1.60.32

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 (106) hide show
  1. package/client/common/clipboard.js +1 -14
  2. package/client/common/constants.js +0 -43
  3. package/client/common/data-compare.js +55 -0
  4. package/client/common/default-setting.js +2 -10
  5. package/client/common/resolve.js +18 -22
  6. package/client/common/sftp.js +0 -3
  7. package/client/components/ai/ai-chat.jsx +30 -6
  8. package/client/components/ai/ai-config.jsx +17 -6
  9. package/client/components/batch-op/batch-op.jsx +3 -24
  10. package/client/components/bookmark-form/bookmark-group-tree-format.js +7 -9
  11. package/client/components/bookmark-form/form-ssh-common.jsx +0 -2
  12. package/client/components/bookmark-form/ssh-form.jsx +8 -41
  13. package/client/components/bookmark-form/tree-delete.jsx +1 -13
  14. package/client/components/common/animate-text.jsx +3 -4
  15. package/client/components/common/drag-handle.jsx +59 -45
  16. package/client/components/common/drag-handle.styl +2 -1
  17. package/client/components/common/input-auto-focus.jsx +29 -63
  18. package/client/components/common/ref.js +24 -0
  19. package/client/components/footer/batch-input.jsx +1 -6
  20. package/client/components/footer/footer-entry.jsx +13 -16
  21. package/client/components/footer/footer.styl +0 -5
  22. package/client/components/icons/ai-icon.jsx +17 -0
  23. package/client/components/icons/ai-icon.styl +3 -0
  24. package/client/components/layout/layout-item.jsx +14 -0
  25. package/client/components/main/main.jsx +8 -19
  26. package/client/components/main/upgrade.jsx +13 -25
  27. package/client/components/profile/profile-form-elem.jsx +1 -2
  28. package/client/components/quick-commands/on-drop.js +1 -12
  29. package/client/components/quick-commands/quick-command-transport-mod.jsx +3 -13
  30. package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -2
  31. package/client/components/rdp/rdp-session.jsx +4 -4
  32. package/client/components/session/session.jsx +9 -11
  33. package/client/components/setting-panel/on-tree-drop.js +4 -35
  34. package/client/components/setting-panel/setting-common.jsx +4 -1
  35. package/client/components/setting-panel/setting-modal.jsx +7 -5
  36. package/client/components/setting-panel/tab-settings.jsx +0 -1
  37. package/client/components/setting-sync/setting-sync.jsx +0 -1
  38. package/client/components/sftp/address-bookmark-item.jsx +1 -15
  39. package/client/components/sftp/confirm-modal-store.jsx +2 -2
  40. package/client/components/sftp/{file-mode-modal.jsx → file-info-modal.jsx} +137 -37
  41. package/client/components/sftp/file-item.jsx +156 -192
  42. package/client/components/sftp/file-table-header.jsx +98 -0
  43. package/client/components/sftp/list-table-ui.jsx +125 -416
  44. package/client/components/sftp/sftp-entry.jsx +102 -128
  45. package/client/components/sftp/sftp.styl +6 -22
  46. package/client/components/sftp/transfer-conflict-store.jsx +8 -12
  47. package/client/components/sftp/transport-action-store.jsx +7 -15
  48. package/client/components/shortcuts/shortcut-control.jsx +72 -3
  49. package/client/components/shortcuts/shortcut-handler.js +0 -1
  50. package/client/components/side-panel-r/side-panel-r.jsx +7 -4
  51. package/client/components/sidebar/bookmark-select.jsx +5 -3
  52. package/client/components/sidebar/history.jsx +3 -0
  53. package/client/components/sidebar/index.jsx +1 -1
  54. package/client/components/sidebar/info-modal.jsx +3 -0
  55. package/client/components/sidebar/side-panel.jsx +7 -4
  56. package/client/components/sidebar/sidebar-panel.jsx +1 -1
  57. package/client/components/sidebar/sidebar.styl +3 -3
  58. package/client/components/sys-menu/icons-map.jsx +52 -0
  59. package/client/components/{context-menu → sys-menu}/menu-btn.jsx +33 -45
  60. package/client/components/sys-menu/sys-menu.jsx +163 -0
  61. package/client/components/{context-menu/context-menu.styl → sys-menu/sys-menu.styl} +2 -11
  62. package/client/components/tabs/index.jsx +5 -97
  63. package/client/components/tabs/tab.jsx +121 -73
  64. package/client/components/tabs/tabs.styl +4 -1
  65. package/client/components/terminal/term-search.jsx +16 -28
  66. package/client/components/terminal/terminal-interactive.jsx +0 -2
  67. package/client/components/terminal/{index.jsx → terminal.jsx} +110 -240
  68. package/client/components/terminal-info/base.jsx +21 -46
  69. package/client/components/terminal-info/terminal-info.jsx +3 -0
  70. package/client/components/text-editor/text-editor.jsx +38 -53
  71. package/client/components/theme/theme-form.jsx +0 -2
  72. package/client/components/tree-list/bookmark-toolbar.jsx +23 -47
  73. package/client/components/tree-list/bookmark-transport.jsx +2 -90
  74. package/client/components/tree-list/move-item-modal.jsx +101 -0
  75. package/client/components/tree-list/tree-expander.jsx +2 -3
  76. package/client/components/tree-list/tree-list-item.jsx +8 -11
  77. package/client/components/tree-list/tree-list.jsx +75 -296
  78. package/client/components/vnc/vnc-session.jsx +5 -3
  79. package/client/store/app-upgrade.js +2 -5
  80. package/client/store/bookmark-group.js +116 -51
  81. package/client/store/common.js +36 -54
  82. package/client/store/event.js +4 -37
  83. package/client/store/init-state.js +9 -12
  84. package/client/store/item.js +34 -39
  85. package/client/store/load-data.js +5 -1
  86. package/client/store/quick-command.js +2 -12
  87. package/client/store/session.js +6 -7
  88. package/client/store/setting.js +3 -7
  89. package/client/store/sidebar.js +2 -8
  90. package/client/store/store.js +0 -20
  91. package/client/store/system-menu.js +1 -2
  92. package/client/store/tab.js +29 -1
  93. package/client/store/terminal-theme.js +0 -4
  94. package/client/store/watch.js +26 -4
  95. package/package.json +1 -1
  96. package/client/common/post-msg.js +0 -3
  97. package/client/components/common/native-input.jsx +0 -30
  98. package/client/components/context-menu/context-menu.jsx +0 -339
  99. package/client/components/sftp/file-props-modal.jsx +0 -210
  100. package/client/store/context-menu.js +0 -23
  101. /package/client/components/{context-menu → sys-menu}/boomarks.jsx +0 -0
  102. /package/client/components/{context-menu → sys-menu}/history.jsx +0 -0
  103. /package/client/components/{context-menu → sys-menu}/icon-holder.jsx +0 -0
  104. /package/client/components/{context-menu → sys-menu}/sub-tab-menu.jsx +0 -0
  105. /package/client/components/{context-menu → sys-menu}/tabs.jsx +0 -0
  106. /package/client/components/{context-menu → sys-menu}/zoom.jsx +0 -0
@@ -1,163 +1,45 @@
1
1
  /**
2
2
  * file list table
3
- * features:
4
- * - drag to resize table
5
- * - context menu to set props to show
6
- * - click header to sort
7
3
  */
8
4
 
9
- import { PureComponent } from 'react'
5
+ import { Component } from 'react'
10
6
  import classnames from 'classnames'
11
- import { isEqual, pick, find, isNull, isArray, isUndefined } from 'lodash-es'
12
- import generate from '../../common/uid'
13
- import parseInt10 from '../../common/parse-int10'
7
+ import { find } from 'lodash-es'
14
8
  import {
15
- splitDraggerWidth,
16
- filePropMinWidth,
17
- maxDragMove,
18
- sftpControlHeight,
19
- eventTypes,
20
- paneMap
9
+ sftpControlHeight
21
10
  } from '../../common/constants'
22
- import copy from 'json-deep-copy'
23
11
  import FileSection from './file-item'
24
12
  import PagedList from './paged-list'
13
+ import FileListTableHeader from './file-table-header'
25
14
  import {
26
- DownOutlined,
27
- UpOutlined,
28
15
  CheckOutlined
29
16
  } from '@ant-design/icons'
30
- import IconHolder from '../context-menu/icon-holder'
17
+ import IconHolder from '../sys-menu/icon-holder'
31
18
 
32
19
  const e = window.translate
33
20
 
34
- export default class FileListTable extends PureComponent {
21
+ export default class FileListTable extends Component {
35
22
  constructor (props) {
36
23
  super(props)
37
- this.state = {
38
- ...this.initFromProps(),
39
- showContextMenu: false,
40
- contextMenuPos: {
41
- left: 0,
42
- top: 0
43
- }
44
- }
45
- }
46
-
47
- componentDidMount () {
48
- this.saveOldStyle()
49
- window.addEventListener('message', this.onMsg)
50
- }
51
-
52
- componentDidUpdate (prevProps, prevState) {
53
- if (this.state.properties.length < 2) {
54
- return
55
- }
56
- if (
57
- !isEqual(prevState.properties, this.state.properties) ||
58
- (
59
- this.toVisible(prevProps, this.props) &&
60
- !this.inited
61
- )
62
- ) {
63
- if (!this.inited) {
64
- this.inited = true
65
- }
66
- this.saveOldStyle()
67
- }
68
- }
69
-
70
- componentWillUnmount () {
71
- window.removeEventListener('message', this.onMsg)
72
- }
73
-
74
- setOnCloseEvent = () => {
75
- const dom = document
76
- .querySelector('.ant-drawer')
77
- if (dom) {
78
- dom.addEventListener('click', this.onTriggerClose)
79
- }
80
- document
81
- .getElementById('outside-context')
82
- .addEventListener('click', this.onTriggerClose)
83
- }
84
-
85
- onTriggerClose = (e) => {
86
- if (e.target.closest('.context-menu')) {
87
- return null
88
- }
89
- this.setState({
90
- showContextMenu: false
91
- })
92
- const dom = document
93
- .querySelector('.ant-drawer')
94
- if (dom) {
95
- dom.removeEventListener('click', this.onTriggerClose)
96
- }
97
- document
98
- .getElementById('outside-context')
99
- .removeEventListener('click', this.onTriggerClose)
100
- }
101
-
102
- toVisible = (prevProps, props) => {
103
- return (
104
- prevProps.pane === paneMap.ssh ||
105
- prevProps.pane === paneMap.terminal
106
- ) &&
107
- (
108
- props.pane === paneMap.sftp ||
109
- props.pane === paneMap.fileManager
110
- )
111
- }
112
-
113
- onMsg = e => {
114
- const { type, data } = e.data || {}
115
- if (
116
- type === eventTypes.resetFileListTable &&
117
- data.id === this.props.id
118
- ) {
119
- this.resetWidth()
120
- }
24
+ this.state = this.initFromProps()
121
25
  }
122
26
 
123
27
  initFromProps = (pps = this.getPropsDefault()) => {
124
28
  const { length } = pps
125
- const { width } = this.props
126
- const padding = 5
127
- const w = (width - padding * 2) / length
29
+ const size = (100 / length)
30
+ const max = (100 - length * 2)
31
+ const min = 2
128
32
  const properties = pps.map((name, i) => {
129
33
  return {
130
- name,
131
- id: generate(),
132
- style: {
133
- width: w + 'px',
134
- left: (w * i) + 'px',
135
- zIndex: 3 + i * 2
136
- }
34
+ id: name,
35
+ max,
36
+ min,
37
+ size
137
38
  }
138
39
  })
139
- const splitHandles = properties.reduce((prev, { name }, i) => {
140
- if (i === length - 1) {
141
- return prev
142
- }
143
- return [
144
- ...prev,
145
- {
146
- id: generate(),
147
- prevProp: name,
148
- nextProp: properties[i + 1].name,
149
- style: {
150
- left: (w * (i + 1) - (splitDraggerWidth / 2)) + 'px',
151
- width: splitDraggerWidth + 'px',
152
- zIndex: 4 + i * 2
153
- }
154
- }
155
- ]
156
- }, [])
157
40
  return {
158
41
  pageSize: 100,
159
- properties,
160
- splitHandles
42
+ properties
161
43
  }
162
44
  }
163
45
 
@@ -189,76 +71,35 @@ export default class FileListTable extends PureComponent {
189
71
  : this.props.directions[0]
190
72
  }
191
73
 
192
- renderTableHeader = () => {
193
- const { properties, splitHandles } = this.state
194
- const arr = properties.reduce((prev, p, i) => {
195
- return [
196
- ...prev,
197
- p,
198
- splitHandles[i]
199
- ]
200
- }, []).filter(d => d)
201
- return (
202
- <div
203
- className='sftp-file-table-header relative'
204
- onContextMenu={this.handleContextMenu}
205
- >
206
- {
207
- arr.map(this.renderHeaderItem)
74
+ onResize = size => {
75
+ this.setState(old => {
76
+ const { properties } = old
77
+ const total = size.reduce((a, b) => a + b, 0)
78
+ const newProps = properties.map((d, i) => {
79
+ return {
80
+ ...d,
81
+ size: size[i] * 100 / total
208
82
  }
209
- </div>
210
- )
83
+ })
84
+ return {
85
+ properties: newProps
86
+ }
87
+ })
211
88
  }
212
89
 
213
- renderHeaderItem = (item) => {
214
- const {
215
- name,
216
- id,
217
- style
218
- } = item
219
- const isHandle = !name
220
- const { sortDirection, sortProp } = this.props
221
- const isSorting = !isHandle && sortProp === name
222
- const cls = classnames(
223
- 'sftp-header-item',
224
- isHandle ? `shi-${id}` : `sftp-header-box shi-${name}`,
225
- {
226
- 'sftp-header-handle': isHandle
227
- },
228
- {
229
- 'sftp-header-name': !isHandle
230
- },
231
- {
232
- 'is-sorting': isSorting
233
- },
234
- isSorting ? sortDirection : ''
235
- )
236
- const props = isHandle
237
- ? pick(this, [
238
- 'onDoubleClick',
239
- 'onDrag',
240
- 'onDragStart',
241
- 'onDragEnd'
242
- ])
243
- : {
244
- onClick: this.onClickName
245
- }
246
- const text = e(name || '')
247
- const directionIcon = isSorting
248
- ? (sortDirection === 'asc' ? <DownOutlined /> : <UpOutlined />)
249
- : null
90
+ renderTableHeader = () => {
91
+ const headerProps = {
92
+ renderContextMenu: this.renderContextMenu,
93
+ onContextMenu: this.onContextMenu,
94
+ onClickName: this.onClickName,
95
+ onResize: this.onResize,
96
+ properties: this.state.properties,
97
+ sortDirection: this.props.sortDirection,
98
+ sortProp: this.props.sortProp,
99
+ maxWidth: this.props.width
100
+ }
250
101
  return (
251
- <div
252
- className={cls}
253
- style={style}
254
- id={id}
255
- key={id}
256
- draggable={isHandle}
257
- {...props}
258
- title={text}
259
- >
260
- {directionIcon} {text}
261
- </div>
102
+ <FileListTableHeader {...headerProps} />
262
103
  )
263
104
  }
264
105
 
@@ -268,7 +109,7 @@ export default class FileListTable extends PureComponent {
268
109
 
269
110
  onToggleProp = name => {
270
111
  const { properties } = this.state
271
- const names = properties.map(d => d.name)
112
+ const names = properties.map(d => d.id)
272
113
  const all = this.getPropsAll()
273
114
  const newProps = names.includes(name)
274
115
  ? names.filter(d => d !== name)
@@ -281,20 +122,8 @@ export default class FileListTable extends PureComponent {
281
122
  this.setState(update)
282
123
  }
283
124
 
284
- handleContextMenu = e => {
285
- e && e.preventDefault()
286
- const pos = e
287
- ? this.computePos(e)
288
- : this.pos
289
- this.setState({
290
- contextMenuPos: pos,
291
- showContextMenu: true
292
- })
293
- this.setOnCloseEvent()
294
- }
295
-
296
125
  onClickName = (e) => {
297
- const id = e.target.getAttribute('id')
126
+ const id = e.target.getAttribute('data-id')
298
127
  const { properties } = this.state
299
128
  const propObj = find(
300
129
  properties,
@@ -303,7 +132,7 @@ export default class FileListTable extends PureComponent {
303
132
  if (!propObj) {
304
133
  return
305
134
  }
306
- const { name } = propObj
135
+ const { id: name } = propObj
307
136
  const { sortDirection, sortProp } = this.props
308
137
  const sortDirectionNew = sortProp === name
309
138
  ? this.otherDirection(sortDirection)
@@ -322,31 +151,20 @@ export default class FileListTable extends PureComponent {
322
151
  })
323
152
  }
324
153
 
325
- renderContext = () => {
154
+ renderContextMenu = () => {
326
155
  const { properties } = this.state
327
156
  const all = this.getPropsAll()
328
- const selectedNames = properties.map(d => d.name)
157
+ const selectedNames = properties.map(d => d.id)
329
158
  return all.map((p, i) => {
330
159
  const selected = selectedNames.includes(p)
331
160
  const disabled = !i
332
- const cls = classnames(
333
- 'context-item',
334
- { selected },
335
- { unselected: !selected }
336
- )
337
161
  const icon = disabled || selected ? <CheckOutlined /> : <IconHolder />
338
- const obj = {
339
- className: cls,
340
- onClick: () => this.onToggleProp(p)
162
+ return {
163
+ key: p,
164
+ label: e(p),
165
+ disabled,
166
+ icon
341
167
  }
342
- return (
343
- <div
344
- {...obj}
345
- key={p}
346
- >
347
- {icon} {e(p)}
348
- </div>
349
- )
350
168
  })
351
169
  }
352
170
 
@@ -355,124 +173,56 @@ export default class FileListTable extends PureComponent {
355
173
  'left'
356
174
  ]
357
175
 
358
- saveOldStyle = () => {
359
- const { properties, splitHandles } = this.state
360
- const ids = [
361
- ...properties,
362
- ...splitHandles
363
- ]
364
- const { type, id } = this.props
365
- const parentWidth = document.querySelector(
366
- `#id-${id} .tw-${type} .sftp-table`
367
- ).clientWidth
368
- this.oldStyles = ids.reduce((prev, { id, name }) => {
369
- const sel = `.session-current .tw-${type} .sftp-file-table-header .shi-${name || id}`
370
- return {
371
- ...prev,
372
- [name || id]: {
373
- style: pick(
374
- document.querySelector(sel)?.style || {},
375
- this.positionProps
376
- ),
377
- parentWidth
378
- }
379
- }
380
- }, {})
381
- }
382
-
383
- onDrag = (e) => {
384
- if (isNull(e.pageX)) {
385
- return
386
- }
387
- const dom = e.target
388
- const { splitHandles } = this.state
389
- const { type } = this.props
390
- const id = dom.getAttribute('id')
391
- const splitHandle = find(
392
- splitHandles,
393
- s => s.id === id
394
- )
395
- const {
396
- prevProp,
397
- nextProp
398
- } = splitHandle
399
- const selPrev = `.session-current .tw-${type} .shi-${prevProp}`
400
- const selNext = `.session-current .tw-${type} .shi-${nextProp}`
401
- const prev = Array.from(document.querySelectorAll(selPrev))
402
- const next = Array.from(document.querySelectorAll(selNext))
403
- const { startPosition } = this
404
- const currentPosition = {
405
- x: e.pageX
406
- }
407
-
408
- const types = ['dom', 'prev', 'next']
409
- const doms = [dom, prev, next]
410
- const styles = doms.map(d => {
411
- const dd = isArray(d) ? d[0] : d
412
- const { style } = dd
413
- const rect = dd.getBoundingClientRect()
414
- const obj = pick(style, this.positionProps)
415
- const res = Object.keys(obj).reduce((prev, k) => {
416
- const v = obj[k]
417
- return {
418
- ...prev,
419
- [k]: isUndefined(v)
420
- ? v
421
- : parseInt10(obj[k].replace('px', ''))
422
- }
423
- }, {})
424
- res.width = rect.right - rect.left
425
- return res
426
- })
427
- let xDiff = currentPosition.x - startPosition.x
428
- if (Math.abs(xDiff) > maxDragMove) {
429
- return
430
- }
431
- const prevStyle = styles[1]
432
- const nextStyle = styles[2]
433
- const minW = filePropMinWidth
434
- if (xDiff > 0 && xDiff > nextStyle.width - minW) {
435
- xDiff = nextStyle.width - minW
436
- } else if (xDiff < 0 && xDiff < -(prevStyle.width - minW)) {
437
- xDiff = -(prevStyle.width - minW)
438
- }
439
- doms.forEach((d, i) => {
440
- this.changePosition(d, xDiff, types[i], styles[i])
441
- })
442
- this.startPosition = currentPosition
443
- }
444
-
445
- onDragStart = (e) => {
446
- this.startPosition = {
447
- x: e.pageX
448
- }
449
- }
450
-
451
- changePosition = (
452
- dom,
453
- xDiff,
454
- type,
455
- style
456
- ) => {
457
- const realWidth = style.width
458
- const realLeft = style.left
459
- if (type === 'prev') {
460
- dom.forEach(d => {
461
- d.style.width = (realWidth + xDiff) + 'px'
462
- })
463
- } else if (type === 'dom') {
464
- dom.style.left = (realLeft + xDiff) + 'px'
465
- } else {
466
- dom.forEach(d => {
467
- d.style.width = (realWidth - xDiff) + 'px'
468
- d.style.left = (realLeft + xDiff) + 'px'
469
- })
470
- }
471
- }
176
+ // saveOldStyle = () => {
177
+ // const { properties } = this.state
178
+ // const ids = [
179
+ // ...properties,
180
+ // ...splitHandles
181
+ // ]
182
+ // const { type, id } = this.props
183
+ // const parentWidth = document.querySelector(
184
+ // `#id-${id} .tw-${type} .sftp-table`
185
+ // ).clientWidth
186
+ // this.oldStyles = ids.reduce((prev, { id, name }) => {
187
+ // const sel = `.session-current .tw-${type} .sftp-file-table-header .shi-${name || id}`
188
+ // return {
189
+ // ...prev,
190
+ // [name || id]: {
191
+ // style: pick(
192
+ // document.querySelector(sel)?.style || {},
193
+ // this.positionProps
194
+ // ),
195
+ // parentWidth
196
+ // }
197
+ // }
198
+ // }, {})
199
+ // }
200
+
201
+ // changePosition = (
202
+ // dom,
203
+ // xDiff,
204
+ // type,
205
+ // style
206
+ // ) => {
207
+ // const realWidth = style.width
208
+ // const realLeft = style.left
209
+ // if (type === 'prev') {
210
+ // dom.forEach(d => {
211
+ // d.style.width = (realWidth + xDiff) + 'px'
212
+ // })
213
+ // } else if (type === 'dom') {
214
+ // dom.style.left = (realLeft + xDiff) + 'px'
215
+ // } else {
216
+ // dom.forEach(d => {
217
+ // d.style.width = (realWidth - xDiff) + 'px'
218
+ // d.style.left = (realLeft + xDiff) + 'px'
219
+ // })
220
+ // }
221
+ // }
472
222
 
473
223
  // onDragEnd = () => {}
474
224
 
475
- onDoubleClick = () => this.resetWidth()
225
+ // onDoubleClick = () => this.resetWidth()
476
226
 
477
227
  hasPager = () => {
478
228
  const {
@@ -485,89 +235,47 @@ export default class FileListTable extends PureComponent {
485
235
  return len > pageSize
486
236
  }
487
237
 
488
- rebuildStyle = (name) => {
489
- let { style, parentWidth } = this.oldStyles[name]
490
- style = copy(style)
491
- const {
492
- type,
493
- id
494
- } = this.props
495
- const currentParentWidth = document.querySelector(
496
- `#id-${id} .tw-${type} .sftp-table`
497
- ).clientWidth
498
- style.width = (parseFloat(style.width) * currentParentWidth / parentWidth) + 'px'
499
- style.left = (parseFloat(style.left) * currentParentWidth / parentWidth) + 'px'
500
- return style
501
- }
238
+ // rebuildStyle = (name) => {
239
+ // let { style, parentWidth } = this.oldStyles[name]
240
+ // style = copy(style)
241
+ // const {
242
+ // type,
243
+ // id
244
+ // } = this.props
245
+ // const currentParentWidth = document.querySelector(
246
+ // `#id-${id} .tw-${type} .sftp-table`
247
+ // ).clientWidth
248
+ // style.width = (parseFloat(style.width) * currentParentWidth / parentWidth) + 'px'
249
+ // style.left = (parseFloat(style.left) * currentParentWidth / parentWidth) + 'px'
250
+ // return style
251
+ // }
502
252
 
503
253
  // reset
504
254
  resetWidth = () => {
505
- const { properties, splitHandles } = this.state
506
- const ids = [
507
- ...properties,
508
- ...splitHandles
509
- ]
510
- const { type } = this.props
511
- ids.forEach(({ id, name }) => {
512
- const sel = `.session-current .tw-${type} .shi-${name || id}`
513
- const arr = Array.from(
514
- document.querySelectorAll(sel)
515
- )
516
- arr.forEach(d => {
517
- Object.assign(
518
- d.style,
519
- this.rebuildStyle(
520
- name || id
521
- )
522
- )
523
- })
524
- })
255
+ this.setState(this.initFromProps())
525
256
  }
526
257
 
527
258
  renderItem = (item, i) => {
528
259
  const { type } = this.props
260
+ const cls = item.isParent ? 'parent-file-item' : 'real-file-item'
261
+ const key = i + '*f*' + item.id
529
262
  return (
530
263
  <FileSection
531
264
  {...this.props.getFileProps(item, type)}
532
- key={i + '*f*' + item.id}
533
- cls='real-file-item'
265
+ key={key}
266
+ cls={cls}
534
267
  properties={this.state.properties}
535
268
  />
536
269
  )
537
270
  }
538
271
 
539
- renderContextMenu = () => {
540
- const {
541
- showContextMenu
542
- } = this.state
543
- if (!showContextMenu) {
544
- return null
545
- }
546
- const {
547
- left,
548
- top
549
- } = this.state.contextMenuPos
550
- const outerProps = {
551
- className: 'context-menu file-header-context-menu',
552
- style: {
553
- left: left + 'px',
554
- top: top + 'px'
555
- }
556
- }
557
- const innerProps = {
558
- className: 'context-menu-inner'
559
- }
560
- return (
561
- <div
562
- {...outerProps}
563
- >
564
- <div
565
- {...innerProps}
566
- >
567
- {this.renderContext()}
568
- </div>
569
- </div>
570
- )
272
+ onContextMenu = ({ key }) => {
273
+ this.onToggleProp(key)
274
+ }
275
+
276
+ renderParent = (type) => {
277
+ const { parentItem } = this.props
278
+ return parentItem ? this.renderItem(parentItem) : null
571
279
  }
572
280
 
573
281
  render () {
@@ -587,14 +295,15 @@ export default class FileListTable extends PureComponent {
587
295
  'sftp-has-pager': hasPager
588
296
  }
589
297
  )
298
+
590
299
  return (
591
300
  <div className={cls}>
592
301
  {this.renderTableHeader()}
593
- {this.renderContextMenu()}
594
302
  <div
595
303
  {...props}
596
304
  >
597
305
  {this.props.renderEmptyFile(type)}
306
+ {this.renderParent(type)}
598
307
  <PagedList
599
308
  list={fileList}
600
309
  renderItem={this.renderItem}