@electerm/electerm-react 1.39.35 → 1.39.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/bookmark-form/bookmark-group-tree-format.js +25 -24
- package/client/components/bookmark-form/form-ssh-common.jsx +10 -0
- package/client/components/bookmark-form/render-connection-hopping.jsx +21 -20
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +4 -3
- package/client/components/bookmark-form/ssh-form.jsx +2 -1
- package/client/components/bookmark-form/vnc-form-ui.jsx +42 -3
- package/client/components/main/main.jsx +1 -1
- package/client/components/profile/profile-form-elem.jsx +0 -1
- package/client/components/quick-commands/quick-command-transport-mod.jsx +1 -1
- package/client/components/setting-panel/bookmark-tree-list.jsx +1 -1
- package/client/components/setting-panel/start-session-select.jsx +4 -3
- package/client/components/sftp/file-item.jsx +3 -3
- package/client/components/sidebar/bookmark-select.jsx +1 -1
- package/client/components/tabs/index.jsx +1 -1
- package/client/components/tabs/tabs.styl +2 -2
- package/client/components/terminal/index.jsx +1 -1
- package/client/components/tree-list/tree-expander.jsx +36 -0
- package/client/components/tree-list/tree-list-item.jsx +263 -0
- package/client/components/{setting-panel → tree-list}/tree-list.jsx +397 -324
- package/client/components/{setting-panel → tree-list}/tree-list.styl +26 -6
- package/client/store/common.js +15 -1
- package/client/store/index.js +24 -0
- package/package.json +1 -1
- /package/client/components/{setting-panel → tree-list}/bookmark-transport.jsx +0 -0
|
@@ -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
|
|
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
|
|
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.
|
|
238
|
+
const id = this.state.parentId
|
|
229
239
|
this.setState({
|
|
230
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
311
|
-
{
|
|
312
|
-
node
|
|
313
|
-
}
|
|
321
|
+
e
|
|
314
322
|
) => {
|
|
315
|
-
const
|
|
316
|
-
|
|
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
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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:
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
|
|
529
|
-
|
|
530
|
-
|
|
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
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
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
|
-
(
|
|
545
|
-
|
|
578
|
+
(idDragged === 'default' &&
|
|
579
|
+
pidDrop !== '') ||
|
|
580
|
+
(
|
|
581
|
+
pidDrop &&
|
|
582
|
+
pidDrags !== pidDrops &&
|
|
583
|
+
pidDrops.includes(idDragged)
|
|
584
|
+
)
|
|
546
585
|
) {
|
|
547
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
562
|
-
|
|
717
|
+
isGroupDrag &&
|
|
718
|
+
pidDrop &&
|
|
719
|
+
!pidDragged
|
|
563
720
|
) {
|
|
564
|
-
|
|
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
|
-
|
|
567
|
-
|
|
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
|
-
|
|
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
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
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
|
-
<
|
|
831
|
-
|
|
832
|
-
|
|
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
|
-
|
|
883
|
-
const
|
|
884
|
-
|
|
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
|
-
<
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
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
|
-
|
|
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.
|
|
982
|
-
|
|
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
|
)
|