@electerm/electerm-react 1.39.31 → 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.
Files changed (28) hide show
  1. package/client/common/create-title.jsx +1 -1
  2. package/client/common/default-setting.js +2 -1
  3. package/client/components/bookmark-form/bookmark-group-tree-format.js +25 -24
  4. package/client/components/bookmark-form/form-ssh-common.jsx +10 -0
  5. package/client/components/bookmark-form/render-connection-hopping.jsx +21 -20
  6. package/client/components/bookmark-form/render-ssh-tunnel.jsx +4 -3
  7. package/client/components/bookmark-form/ssh-form.jsx +2 -1
  8. package/client/components/bookmark-form/vnc-form-ui.jsx +42 -3
  9. package/client/components/main/main.jsx +1 -1
  10. package/client/components/profile/profile-form-elem.jsx +0 -1
  11. package/client/components/quick-commands/quick-command-transport-mod.jsx +1 -1
  12. package/client/components/setting-panel/bookmark-tree-list.jsx +1 -1
  13. package/client/components/setting-panel/setting-common.jsx +1 -0
  14. package/client/components/setting-panel/setting-modal.jsx +1 -1
  15. package/client/components/setting-panel/start-session-select.jsx +4 -3
  16. package/client/components/sftp/file-item.jsx +3 -3
  17. package/client/components/sidebar/bookmark-select.jsx +1 -1
  18. package/client/components/tabs/index.jsx +1 -1
  19. package/client/components/tabs/tabs.styl +2 -2
  20. package/client/components/terminal/index.jsx +1 -1
  21. package/client/components/tree-list/tree-expander.jsx +36 -0
  22. package/client/components/tree-list/tree-list-item.jsx +263 -0
  23. package/client/components/{setting-panel → tree-list}/tree-list.jsx +397 -324
  24. package/client/components/{setting-panel → tree-list}/tree-list.styl +26 -6
  25. package/client/store/common.js +15 -1
  26. package/client/store/index.js +24 -0
  27. package/package.json +1 -1
  28. /package/client/components/{setting-panel → tree-list}/bookmark-transport.jsx +0 -0
@@ -7,12 +7,7 @@ import {
7
7
  BookOutlined,
8
8
  CheckOutlined,
9
9
  CloseOutlined,
10
- CopyOutlined,
11
- EditOutlined,
12
- FolderAddOutlined,
13
10
  FolderOutlined,
14
- FolderOpenOutlined,
15
- SettingOutlined,
16
11
  LoadingOutlined
17
12
  } from '@ant-design/icons'
18
13
  import {
@@ -21,16 +16,12 @@ import {
21
16
  hasBookmarkOrGroupInClipboardText
22
17
  } from '../../common/clipboard'
23
18
  import {
24
- Popconfirm,
25
- Tree,
26
19
  Button,
27
- Tooltip,
28
20
  Space
29
21
  } from 'antd'
30
- import createName, { createTitleTag } from '../../common/create-title'
31
- import classnames from 'classnames'
22
+ import createName from '../../common/create-title'
32
23
  import InputAutoFocus from '../common/input-auto-focus'
33
- import { find, uniq, findIndex, isEqual, filter } from 'lodash-es'
24
+ import { find, uniq, findIndex, isEqual, filter, pick } from 'lodash-es'
34
25
  import {
35
26
  maxBookmarkGroupTitleLength,
36
27
  defaultBookmarkGroupId,
@@ -39,9 +30,8 @@ import {
39
30
  copyBookmarkItemPrefix,
40
31
  copyBookmarkGroupItemPrefix
41
32
  } from '../../common/constants'
42
- import highlight from '../common/highlight'
33
+ import findParentBySel from '../../common/find-parent'
43
34
  import copy from 'json-deep-copy'
44
- import onDrop from './on-tree-drop'
45
35
  import Search from '../common/search'
46
36
  import Btns from './bookmark-transport'
47
37
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
@@ -49,8 +39,9 @@ import getInitItem from '../../common/init-setting-item'
49
39
  import uid from '../../common/uid'
50
40
  import deepEqual from 'fast-deep-equal'
51
41
  import './tree-list.styl'
42
+ import TreeExpander from './tree-expander'
43
+ import TreeListItem from './tree-list-item'
52
44
 
53
- const { TreeNode } = Tree
54
45
  const { prefix } = window
55
46
  const e = prefix('menu')
56
47
  const c = prefix('common')
@@ -62,12 +53,11 @@ export default class ItemListTree extends Component {
62
53
  this.state = {
63
54
  ready: false,
64
55
  keyword: '',
56
+ parentId: '',
65
57
  showNewBookmarkGroupForm: false,
66
58
  bookmarkGroupTitle: '',
67
59
  categoryTitle: '',
68
60
  categoryId: '',
69
- bookmarkGroupTitleSub: '',
70
- bookmarkGroupSubParentId: '',
71
61
  expandedKeys: window.store.expandedKeys
72
62
  }
73
63
  }
@@ -96,6 +86,37 @@ export default class ItemListTree extends Component {
96
86
  window.removeEventListener('message', this.onContextAction)
97
87
  }
98
88
 
89
+ filter = list => {
90
+ const { keyword } = this.state
91
+ return keyword
92
+ ? list.filter(item => {
93
+ return createName(item).toLowerCase().includes(keyword.toLowerCase())
94
+ })
95
+ : list
96
+ }
97
+
98
+ getBookmarkTree = () => {
99
+ return this.filter(this.props.bookmarks).reduce((tree, bookmark) => {
100
+ tree[bookmark.id] = bookmark
101
+ return tree
102
+ }, {})
103
+ }
104
+
105
+ onExpandKey = group => {
106
+ const nkeys = [
107
+ ...this.state.expandedKeys,
108
+ group.id
109
+ ]
110
+ this.onExpand(nkeys)
111
+ }
112
+
113
+ onUnExpandKey = group => {
114
+ const nkeys = this.state.expandedKeys.filter(
115
+ d => d !== group.id
116
+ )
117
+ this.onExpand(nkeys)
118
+ }
119
+
99
120
  handleChange = e => {
100
121
  this.setState({
101
122
  keyword: e.target.value
@@ -167,10 +188,6 @@ export default class ItemListTree extends Component {
167
188
  }])
168
189
  }
169
190
 
170
- onDrop = (info) => {
171
- onDrop(info, this.props)
172
- }
173
-
174
191
  onClick = () => {
175
192
 
176
193
  }
@@ -189,16 +206,6 @@ export default class ItemListTree extends Component {
189
206
  })
190
207
  }
191
208
 
192
- handleChangeBookmarkGroupTitleSub = e => {
193
- let { value } = e.target
194
- if (value.length > maxBookmarkGroupTitleLength) {
195
- value = value.slice(0, maxBookmarkGroupTitleLength)
196
- }
197
- this.setState({
198
- bookmarkGroupTitleSub: value
199
- })
200
- }
201
-
202
209
  handleNewBookmark = () => {
203
210
  this.props.onClickItem(getInitItem([], settingMap.bookmarks))
204
211
  }
@@ -207,6 +214,9 @@ export default class ItemListTree extends Component {
207
214
  if (this.onSubmit) {
208
215
  return
209
216
  }
217
+ if (this.state.parentId) {
218
+ return this.handleSubmitSub()
219
+ }
210
220
  this.onSubmit = true
211
221
  this.setState({
212
222
  showNewBookmarkGroupForm: false
@@ -225,9 +235,10 @@ export default class ItemListTree extends Component {
225
235
  return
226
236
  }
227
237
  this.onSubmit = true
228
- const id = this.state.bookmarkGroupSubParentId
238
+ const id = this.state.parentId
229
239
  this.setState({
230
- bookmarkGroupSubParentId: ''
240
+ showNewBookmarkGroupForm: false,
241
+ parentId: ''
231
242
  }, () => {
232
243
  this.onSubmit = false
233
244
  let bookmarkGroups = copy(
@@ -235,7 +246,7 @@ export default class ItemListTree extends Component {
235
246
  )
236
247
  const newCat = {
237
248
  id: uid(),
238
- title: this.state.bookmarkGroupTitleSub,
249
+ title: this.state.bookmarkGroupTitle,
239
250
  level: 2,
240
251
  bookmarkIds: []
241
252
  }
@@ -276,7 +287,7 @@ export default class ItemListTree extends Component {
276
287
  this.setState({
277
288
  showNewBookmarkGroupForm: true,
278
289
  bookmarkGroupTitle: '',
279
- bookmarkGroupSubParentId: ''
290
+ parentId: ''
280
291
  })
281
292
  }
282
293
 
@@ -292,7 +303,7 @@ export default class ItemListTree extends Component {
292
303
  closeNewGroupForm = () => {
293
304
  this.setState({
294
305
  showNewBookmarkGroupForm: false,
295
- bookmarkGroupSubParentId: ''
306
+ parentId: ''
296
307
  })
297
308
  }
298
309
 
@@ -307,13 +318,11 @@ export default class ItemListTree extends Component {
307
318
  }
308
319
 
309
320
  onSelect = (
310
- selectedKeys,
311
- {
312
- node
313
- }
321
+ e
314
322
  ) => {
315
- const [id] = selectedKeys
316
- if (!node.isLeaf) {
323
+ const id = e.target.getAttribute('data-item-id')
324
+ const isGroup = e.target.getAttribute('data-is-group') === 'true'
325
+ if (isGroup) {
317
326
  this.props.store.storeAssign({
318
327
  currentBookmarkGroupId: id
319
328
  })
@@ -321,14 +330,14 @@ export default class ItemListTree extends Component {
321
330
  this.props.store.storeAssign({
322
331
  currentBookmarkGroupId: findBookmarkGroupId(this.props.store.bookmarkGroups, id)
323
332
  })
324
- }
325
- const bookmarks = copy(this.props.bookmarks)
326
- const bookmark = find(
327
- bookmarks,
328
- d => d.id === id
329
- )
330
- if (bookmark) {
331
- this.props.onClickItem(bookmark)
333
+ const { bookmarks } = this.props
334
+ const bookmark = find(
335
+ bookmarks,
336
+ d => d.id === id
337
+ )
338
+ if (bookmark) {
339
+ this.props.onClickItem(bookmark)
340
+ }
332
341
  }
333
342
  }
334
343
 
@@ -343,35 +352,6 @@ export default class ItemListTree extends Component {
343
352
  )
344
353
  }
345
354
 
346
- renderDelBtn = item => {
347
- if (item.id === defaultBookmarkGroupId || this.props.staticList) {
348
- return null
349
- }
350
- return (
351
- <Popconfirm
352
- title={e('del') + '?'}
353
- onConfirm={e => this.del(item, e)}
354
- okText={e('del')}
355
- cancelText={c('cancel')}
356
- placement='top'
357
- >
358
- <CloseOutlined title={e('del')} className='pointer tree-control-btn' />
359
- </Popconfirm>
360
- )
361
- }
362
-
363
- renderOperationBtn = (item, isGroup) => {
364
- if (this.props.staticList) {
365
- return null
366
- }
367
- return (
368
- <SettingOutlined
369
- className='pointer tree-control-btn'
370
- onClick={e => this.onContextMenu(e, item, isGroup)}
371
- />
372
- )
373
- }
374
-
375
355
  onCut = (item, isGroup) => {
376
356
  const str = isGroup
377
357
  ? copyBookmarkGroupItemPrefix
@@ -503,7 +483,7 @@ export default class ItemListTree extends Component {
503
483
  if (isGroup) {
504
484
  this.setState({
505
485
  categoryTitle: '' + item.title,
506
- categoryId: item.id + '',
486
+ categoryId: item.id,
507
487
  bookmarkGroupSubParentId: ''
508
488
  })
509
489
  } else {
@@ -514,9 +494,9 @@ export default class ItemListTree extends Component {
514
494
  addSubCat = (e, item) => {
515
495
  this.setState(old => {
516
496
  return {
517
- showNewBookmarkGroupForm: false,
518
- bookmarkGroupTitleSub: '',
519
- bookmarkGroupSubParentId: item.id,
497
+ showNewBookmarkGroupForm: true,
498
+ parentId: item.id,
499
+ bookmarkGroupTitle: '',
520
500
  expandedKeys: uniq([
521
501
  ...old.expandedKeys,
522
502
  item.id
@@ -525,53 +505,235 @@ export default class ItemListTree extends Component {
525
505
  })
526
506
  }
527
507
 
528
- renderAddNewSubGroupBtn = item => {
529
- if (this.props.staticList || item.level === 2) {
530
- return null
508
+ openAll = (item) => {
509
+ this.props.store.openAllBookmarkInCategory(this.props.item)
510
+ }
511
+
512
+ onDragStart = e => {
513
+ let {
514
+ target
515
+ } = e
516
+ const tar = findParentBySel(target, '.tree-item')
517
+ if (tar) {
518
+ target = tar
531
519
  }
532
- return (
533
- <FolderAddOutlined
534
- key='new-tree'
535
- title={`${s('new')} ${c('bookmarkCategory')}`}
536
- onClick={(e) => this.addSubCat(e, item)}
537
- className='pointer tree-control-btn'
538
- />
539
- )
520
+ const id = target.getAttribute('data-item-id')
521
+ const pid = target.getAttribute('data-parent-id')
522
+ const isGroup = target.getAttribute('data-is-group')
523
+ e.dataTransfer
524
+ .setData(
525
+ 'idDragged', `${id}@${pid}@${isGroup}`
526
+ )
540
527
  }
541
528
 
542
- renderEditBtn = (item, isGroup) => {
529
+ onDragLeave = e => {
530
+ e.preventDefault()
531
+ let {
532
+ target
533
+ } = e
534
+ const tar = findParentBySel(target, '.tree-item')
535
+ if (tar) {
536
+ target = tar
537
+ }
538
+ target.classList.remove('item-dragover')
539
+ }
540
+
541
+ onDragOver = e => {
542
+ let {
543
+ target
544
+ } = e
545
+ const tar = findParentBySel(target, '.tree-item')
546
+ if (tar) {
547
+ target = tar
548
+ }
549
+ target.classList.add('item-dragover')
550
+ }
551
+
552
+ onDrop = e => {
553
+ e.preventDefault()
554
+ const elems = document.querySelectorAll('.tree-item.item-dragover')
555
+ elems.forEach(elem => {
556
+ elem.classList.remove('item-dragover')
557
+ })
558
+ let {
559
+ target
560
+ } = e
561
+ const tar = findParentBySel(target, '.tree-item')
562
+ if (tar) {
563
+ target = tar
564
+ }
565
+ const dataDragged = e.dataTransfer.getData('idDragged')
566
+ const [idDragged, pidDrags, isGroupDragged] = dataDragged.split('@')
567
+ const isGroupDrag = isGroupDragged === 'true'
568
+ const pidDragsArr = pidDrags.split('#')
569
+ const pidDragged = pidDragsArr[pidDragsArr.length - 1]
570
+ const idDrop = target.getAttribute('data-item-id')
571
+ const isGroupDrop = target.getAttribute('data-is-group') === 'true'
572
+ const pidDrops = target.getAttribute('data-parent-id') || ''
573
+ const pidDropsArr = pidDrops.split('#')
574
+ const pidDrop = pidDropsArr[pidDropsArr.length - 1]
575
+
576
+ // can not drag item to its own children
543
577
  if (
544
- (this.props.staticList && isGroup) ||
545
- (!this.props.staticList && !isGroup)
578
+ (idDragged === 'default' &&
579
+ pidDrop !== '') ||
580
+ (
581
+ pidDrop &&
582
+ pidDrags !== pidDrops &&
583
+ pidDrops.includes(idDragged)
584
+ )
546
585
  ) {
547
- return null
586
+ return
548
587
  }
549
- return (
550
- <EditOutlined
551
- title={e('edit')}
552
- key='edit-tree'
553
- onClick={(e) => this.editItem(e, item, isGroup)}
554
- className='pointer edit-icon tree-control-btn'
555
- />
556
- )
557
- }
558
588
 
559
- renderOpenAll = (item, isGroup) => {
589
+ const {
590
+ bookmarkGroups
591
+ } = window.store
592
+
593
+ if (!pidDragged && !pidDrop) {
594
+ const indexDrag = findIndex(bookmarkGroups, item => item.id === idDragged)
595
+ if (indexDrag < 0) {
596
+ return
597
+ }
598
+ const dragItem = bookmarkGroups.splice(indexDrag, 1)[0]
599
+ dragItem.level = 1
600
+ const indexDrop = findIndex(bookmarkGroups, item => item.id === idDrop)
601
+ if (indexDrop < 0) {
602
+ return
603
+ }
604
+ bookmarkGroups.splice(
605
+ indexDrop,
606
+ 0,
607
+ dragItem
608
+ )
609
+ return window.store.setState('bookmarkGroups', bookmarkGroups)
610
+ }
611
+ const updates = []
612
+ if (isGroupDrag) {
613
+ const parentDrag = pidDragged
614
+ ? bookmarkGroups.find(
615
+ item => item.id === pidDragged
616
+ )
617
+ : false
618
+ if (parentDrag) {
619
+ parentDrag.bookmarkGroupIds = (parentDrag.bookmarkGroupIds || []).filter(
620
+ id => id !== idDragged
621
+ )
622
+ updates.push({
623
+ upsert: false,
624
+ id: parentDrag.id,
625
+ update: {
626
+ bookmarkGroupIds: parentDrag.bookmarkGroupIds
627
+ },
628
+ db: 'bookmarkGroups'
629
+ })
630
+ }
631
+ const parentDrop = pidDrop
632
+ ? bookmarkGroups.find(
633
+ item => item.id === pidDrop
634
+ )
635
+ : bookmarkGroups.find(
636
+ item => item.id === idDrop
637
+ )
638
+ if (!parentDrop) {
639
+ return
640
+ }
641
+ if (!pidDrop) {
642
+ parentDrop.bookmarkGroupIds = uniq(
643
+ [
644
+ ...(parentDrop.bookmarkGroupIds || []),
645
+ idDragged
646
+ ]
647
+ )
648
+ } else {
649
+ const arr = parentDrop.bookmarkGroupIds || []
650
+ let index = findIndex(arr, item => item === idDrop)
651
+ if (index < 0) {
652
+ index = 0
653
+ }
654
+ arr.splice(index, 0, idDragged)
655
+ }
656
+ updates.push({
657
+ upsert: false,
658
+ id: parentDrop.id,
659
+ update: {
660
+ bookmarkGroupIds: parentDrop.bookmarkGroupIds
661
+ },
662
+ db: 'bookmarkGroups'
663
+ })
664
+ } else {
665
+ const parentDrag = bookmarkGroups.find(
666
+ item => item.id === pidDragged
667
+ )
668
+ if (!parentDrag) {
669
+ return
670
+ }
671
+ parentDrag.bookmarkIds = (parentDrag.bookmarkIds || []).filter(
672
+ id => id !== idDragged
673
+ )
674
+ updates.push({
675
+ upsert: false,
676
+ id: parentDrag.id,
677
+ update: {
678
+ bookmarkIds: parentDrag.bookmarkIds
679
+ },
680
+ db: 'bookmarkGroups'
681
+ })
682
+ const parentDrop = isGroupDrop
683
+ ? bookmarkGroups.find(
684
+ item => item.id === idDrop
685
+ )
686
+ : bookmarkGroups.find(
687
+ item => item.id === pidDrop
688
+ )
689
+ if (!parentDrop) {
690
+ return
691
+ }
692
+ if (isGroupDrop) {
693
+ parentDrop.bookmarkIds = uniq(
694
+ [
695
+ ...(parentDrop.bookmarkIds || []),
696
+ idDragged
697
+ ]
698
+ )
699
+ } else {
700
+ const arr = parentDrop.bookmarkIds || []
701
+ let index = findIndex(arr, item => item === idDrop)
702
+ if (index < 0) {
703
+ index = 0
704
+ }
705
+ arr.splice(index, 0, idDragged)
706
+ }
707
+ updates.push({
708
+ upsert: false,
709
+ id: parentDrop.id,
710
+ update: {
711
+ bookmarkIds: parentDrop.bookmarkIds
712
+ },
713
+ db: 'bookmarkGroups'
714
+ })
715
+ }
560
716
  if (
561
- (this.props.staticList && isGroup) ||
562
- (!this.props.staticList && !isGroup)
717
+ isGroupDrag &&
718
+ pidDrop &&
719
+ !pidDragged
563
720
  ) {
564
- return null
721
+ const i = findIndex(bookmarkGroups, item => item.id === idDragged)
722
+ if (i >= 0) {
723
+ const item = bookmarkGroups[i]
724
+ item.level = 2
725
+ updates.push({
726
+ upsert: false,
727
+ id: item.id,
728
+ update: {
729
+ level: item.level
730
+ },
731
+ db: 'bookmarkGroups'
732
+ })
733
+ }
565
734
  }
566
- return (
567
- <Tooltip title={s('openAll')}>
568
- <FolderOpenOutlined
569
- key='open-all-tree'
570
- onClick={(e) => this.props.store.openAllBookmarkInCategory(item)}
571
- className='pointer open-all-icon tree-control-btn'
572
- />
573
- </Tooltip>
574
- )
735
+ window.store.batchDbUpdate(updates)
736
+ return window.store.setState('bookmarkGroups', bookmarkGroups)
575
737
  }
576
738
 
577
739
  editCategory = () => {
@@ -590,7 +752,6 @@ export default class ItemListTree extends Component {
590
752
  onChange={this.handleChangeEdit}
591
753
  onPressEnter={this.handleSubmitEdit}
592
754
  addonAfter={confirm}
593
- type='native'
594
755
  />
595
756
  )
596
757
  }
@@ -688,173 +849,53 @@ export default class ItemListTree extends Component {
688
849
  })
689
850
  }
690
851
 
691
- renderDuplicateBtn = (item, isGroup) => {
692
- if (!item.id || this.props.staticList) {
693
- return null
694
- }
695
- const icon = (
696
- <CopyOutlined
697
- title={e('duplicate')}
698
- className='pointer tree-control-btn'
699
- onClick={(e) => this.duplicateItem(e, item)}
700
- />
701
- )
702
- return icon
703
- }
704
-
705
- renderItemTitle = (item, isGroup) => {
852
+ renderItemTitle = (item, isGroup, parentId) => {
706
853
  if (isGroup && item.id === this.state.categoryId) {
707
854
  return this.editCategory(item)
708
855
  }
709
- const cls = classnames(
710
- 'tree-item elli',
711
- {
712
- 'is-category': isGroup,
713
- level2: item.level === 2
714
- }
715
- )
716
- const tag = isGroup ? '' : createTitleTag(item)
717
- const title = isGroup
718
- ? item.title
719
- : createName(item)
720
- const titleAll = title + (item.description ? ' - ' + item.description : '')
721
- const titleHighlight = isGroup
722
- ? item.title || 'no title'
723
- : highlight(
724
- title,
725
- this.state.keyword
726
- )
727
- const propsAll = {
728
- className: cls,
729
- title: titleAll,
730
- onContextMenu: e => this.onContextMenu(e, item, isGroup)
731
- }
732
- const titleProps = {
733
- className: 'tree-item-title elli',
734
- style: this.props.staticList
735
- ? { maxWidth: (this.props.store.leftSidebarWidth - 110) + 'px' }
736
- : undefined
737
- }
738
- const key = item.id || uid()
739
- return (
740
- <div
741
- {...propsAll}
742
- key={key}
743
- >
744
- <div
745
- {...titleProps}
746
- >
747
- {tag}{titleHighlight}
748
- </div>
749
- {
750
- isGroup
751
- ? this.renderGroupBtns(item)
752
- : null
753
- }
754
- {
755
- !isGroup
756
- ? this.renderDuplicateBtn(item)
757
- : null
758
- }
759
- {this.renderOperationBtn(item, isGroup)}
760
- {this.renderDelBtn(item)}
761
- {this.renderEditBtn(item, isGroup)}
762
- </div>
763
- )
764
- }
765
-
766
- renderGroupBtns = (item) => {
767
- return [
768
- this.renderAddNewSubGroupBtn(item),
769
- this.renderEditBtn(item),
770
- this.renderOpenAll(item)
771
- ]
772
- }
773
-
774
- renderChildNodes = bookmarkIds => {
775
- const bookmarks = this.filter(
776
- this.props.bookmarks
777
- )
778
- const map = bookmarks.reduce((p, b) => {
779
- return {
780
- ...p,
781
- [b.id]: b
782
- }
783
- }, {})
784
- const nodes = bookmarkIds.reduce((prev, id) => {
785
- return map[id]
786
- ? [
787
- ...prev,
788
- map[id]
789
- ]
790
- : prev
791
- }, [])
792
- return nodes.map((node, i) => {
793
- return (
794
- <TreeNode
795
- key={node.id}
796
- isLeaf
797
- title={this.renderItemTitle(node)}
798
- />
799
- )
800
- })
801
- }
802
-
803
- renderGroupChildNodes = bookmarkGroupIds => {
804
- const bookmarkGroups = bookmarkGroupIds.map(id => {
805
- return find(this.props.bookmarkGroups, d => d.id === id)
806
- }).filter(d => d)
807
- return bookmarkGroups.map((node, i) => {
808
- const { bookmarkIds = [], id } = node
809
- return (
810
- <TreeNode
811
- key={id}
812
- title={this.renderItemTitle(node, true)}
813
- >
814
- {
815
- bookmarkIds.length
816
- ? this.renderChildNodes(bookmarkIds)
817
- : null
818
- }
819
- </TreeNode>
856
+ const itemProps = {
857
+ item,
858
+ isGroup,
859
+ parentId,
860
+ leftSidebarWidth: this.props.store.leftSidebarWidth,
861
+ staticList: this.props.staticList,
862
+ selectedItemId: this.props.activeItemId,
863
+ ...pick(
864
+ this,
865
+ [
866
+ 'del',
867
+ 'openAll',
868
+ 'onContextMenu',
869
+ 'editItem',
870
+ 'addSubCat',
871
+ 'onSelect',
872
+ 'duplicateItem',
873
+ 'onDragStart',
874
+ 'onDrop',
875
+ 'onDragLeave',
876
+ 'onDragOver'
877
+ ]
878
+ ),
879
+ ...pick(
880
+ this.state,
881
+ [
882
+ 'keyword',
883
+ 'openAll',
884
+ 'onContextMenu',
885
+ 'editItem',
886
+ 'addSubCat',
887
+ 'onSelect',
888
+ 'duplicateItem'
889
+ ]
820
890
  )
821
- })
822
- }
823
-
824
- renderItem = (item, i) => {
825
- const {
826
- bookmarkIds = [],
827
- bookmarkGroupIds = []
828
- } = item
891
+ }
829
892
  return (
830
- <TreeNode
831
- key={item.id}
832
- title={this.renderItemTitle(item, true)}
833
- >
834
- {this.renderNewSubBookmarkGroup(item)}
835
- {
836
- bookmarkGroupIds.length
837
- ? this.renderGroupChildNodes(bookmarkGroupIds)
838
- : null
839
- }
840
- {
841
- bookmarkIds.length
842
- ? this.renderChildNodes(bookmarkIds)
843
- : null
844
- }
845
- </TreeNode>
893
+ <TreeListItem
894
+ {...itemProps}
895
+ />
846
896
  )
847
897
  }
848
898
 
849
- filter = list => {
850
- const { keyword } = this.state
851
- return keyword
852
- ? list.filter(item => {
853
- return createName(item).toLowerCase().includes(keyword.toLowerCase())
854
- })
855
- : list
856
- }
857
-
858
899
  renderNewButtons = () => {
859
900
  return (
860
901
  <div className='pd1b pd2r'>
@@ -879,43 +920,36 @@ export default class ItemListTree extends Component {
879
920
  )
880
921
  }
881
922
 
882
- renderNewSubBookmarkGroup = item => {
883
- const {
884
- bookmarkGroupTitleSub,
885
- bookmarkGroupSubParentId
886
- } = this.state
887
- if (!bookmarkGroupSubParentId || item.id !== bookmarkGroupSubParentId) {
888
- return null
889
- }
890
- const confirm = (
891
- <span>
892
- <CheckOutlined className='pointer' onClick={this.handleSubmitSub} />
893
- <CloseOutlined className='mg1l pointer' onClick={this.handleCancelNewSub} />
894
- </span>
895
- )
923
+ renderGroup = (group, index, parentId) => {
924
+ const pids = typeof parentId === 'string' ? parentId : ''
925
+ const pid = pids + '#' + group.id
896
926
  return (
897
- <TreeNode
898
- key={bookmarkGroupSubParentId}
899
- isLeaf
900
- title={(
901
- <InputAutoFocus
902
- value={bookmarkGroupTitleSub}
903
- onPressEnter={this.handleSubmitSub}
904
- onChange={this.handleChangeBookmarkGroupTitleSub}
905
- addonAfter={confirm}
906
- type='native'
907
- />
908
- )}
909
- />
927
+ <div key={group.id} className='group-container'>
928
+ {
929
+ this.renderExpander(group, pid)
930
+ }
931
+ {
932
+ this.renderGroupTitle(group, pids)
933
+ }
934
+ <div className='group-container-sub'>
935
+ {
936
+ this.renderNewCat(group, pid)
937
+ }
938
+ {
939
+ this.renderGroupChildren(group, pid)
940
+ }
941
+ </div>
942
+ </div>
910
943
  )
911
944
  }
912
945
 
913
- renderNewBookmarkGroup = () => {
946
+ renderNewCat = (group) => {
914
947
  const {
915
948
  bookmarkGroupTitle,
949
+ parentId,
916
950
  showNewBookmarkGroupForm
917
951
  } = this.state
918
- if (!showNewBookmarkGroupForm) {
952
+ if (!showNewBookmarkGroupForm || group.id !== parentId) {
919
953
  return null
920
954
  }
921
955
  const confirm = (
@@ -937,6 +971,59 @@ export default class ItemListTree extends Component {
937
971
  )
938
972
  }
939
973
 
974
+ renderExpander = (group, level) => {
975
+ const expProps = {
976
+ level,
977
+ group,
978
+ keyword: this.state.keyword,
979
+ expandedKeys: this.state.expandedKeys,
980
+ onExpand: this.onExpandKey,
981
+ onUnExpand: this.onUnExpandKey
982
+ }
983
+ return (
984
+ <TreeExpander
985
+ {...expProps}
986
+ />
987
+ )
988
+ }
989
+
990
+ renderGroupTitle = (group, parentId) => {
991
+ return this.renderItemTitle(group, true, parentId)
992
+ }
993
+
994
+ renderGroupChildren = (group, parentId) => {
995
+ const {
996
+ bookmarkIds = [],
997
+ bookmarkGroupIds = [],
998
+ id
999
+ } = group
1000
+ if (!this.state.expandedKeys.includes(id)) {
1001
+ return null
1002
+ }
1003
+ return [
1004
+ ...this.renderSubGroup(bookmarkGroupIds, parentId),
1005
+ ...this.renderChilds(bookmarkIds, parentId)
1006
+ ]
1007
+ }
1008
+
1009
+ renderSubGroup = (bookmarkGroupIds, parentId) => {
1010
+ const bookmarkGroups = bookmarkGroupIds.map(id => {
1011
+ return window.store.bookmarkGroupTree[id]
1012
+ }).filter(d => d)
1013
+ return bookmarkGroups.map((node, i) => {
1014
+ return this.renderGroup(node, i, parentId)
1015
+ })
1016
+ }
1017
+
1018
+ renderChilds = (bookmarkIds, pid) => {
1019
+ const bookmarks = bookmarkIds.map(id => {
1020
+ return this.getBookmarkTree()[id]
1021
+ }).filter(d => d)
1022
+ return bookmarks.map((node) => {
1023
+ return this.renderItemTitle(node, false, pid)
1024
+ })
1025
+ }
1026
+
940
1027
  render () {
941
1028
  const { ready } = this.state
942
1029
  if (!ready) {
@@ -949,24 +1036,14 @@ export default class ItemListTree extends Component {
949
1036
  const {
950
1037
  bookmarkGroups,
951
1038
  type,
952
- activeItemId,
953
1039
  staticList,
954
1040
  listStyle = {}
955
1041
  } = this.props
956
- const { keyword, expandedKeys } = this.state
957
1042
  const level1Bookgroups = ready
958
1043
  ? bookmarkGroups.filter(
959
1044
  d => !d.level || d.level < 2
960
1045
  )
961
1046
  : []
962
- const treeProps = {
963
- onExpand: this.onExpand,
964
- expandedKeys: keyword ? bookmarkGroups.map(f => f.id) : expandedKeys,
965
- onSelect: this.onSelect,
966
- draggable: staticList ? false : { icon: false },
967
- selectedKeys: [activeItemId],
968
- onDrop: this.onDrop
969
- }
970
1047
  return (
971
1048
  <div className={`tree-list item-type-${type}`}>
972
1049
  {
@@ -978,12 +1055,8 @@ export default class ItemListTree extends Component {
978
1055
  this.renderSearch()
979
1056
  }
980
1057
  <div className='item-list-wrap' style={listStyle}>
981
- {this.renderNewBookmarkGroup()}
982
- <Tree
983
- {...treeProps}
984
- >
985
- {level1Bookgroups.map(this.renderItem)}
986
- </Tree>
1058
+ {this.renderNewCat({ id: '' })}
1059
+ {level1Bookgroups.map(this.renderGroup)}
987
1060
  </div>
988
1061
  </div>
989
1062
  )