|
1 | | -import Component from '@glimmer/component'; |
| 1 | +import {RestrictToVerticalAxis} from '@dnd-kit/abstract/modifiers'; |
| 2 | +import {DragDropManager} from '@dnd-kit/dom'; |
| 3 | +import {isSortable,Sortable} from '@dnd-kit/dom/sortable'; |
2 | 4 | import { action } from '@ember/object'; |
3 | | -import { service } from '@ember/service'; |
| 5 | +import { guidFor } from '@ember/object/internals'; |
| 6 | +import { schedule } from '@ember/runloop'; |
| 7 | +import Component from '@glimmer/component'; |
4 | 8 | import { tracked } from '@glimmer/tracking'; |
5 | | -import {DragDropManager} from '@dnd-kit/dom'; |
6 | | -import {RestrictToVerticalAxis} from '@dnd-kit/abstract/modifiers'; |
7 | | -import {Sortable} from '@dnd-kit/dom/sortable'; |
8 | 9 |
|
9 | 10 | export default class ReorderTable extends Component { |
10 | 11 | @tracked isReordering = false; |
11 | 12 |
|
12 | | - constructor(owner, args) { |
| 13 | + constructor() { |
13 | 14 | super(...arguments); |
| 15 | + this.setupDomSorting(); |
| 16 | + } |
14 | 17 |
|
15 | | - // this.addObserver('args.collection', this, () => { |
16 | | - // console.info('COLLECTION CHANGES'); |
17 | | - // }); |
| 18 | + willDestroy() { |
| 19 | + super.willDestroy(...arguments); |
| 20 | + this.destroyDomSorting(); |
18 | 21 | } |
19 | 22 |
|
20 | 23 | get isReorderable() { |
21 | | - console.info('isReorderable'); |
22 | 24 | const length = this.args.collection.length; |
| 25 | + this.handleCollectionChange(); |
23 | 26 | return (length > 1); |
24 | 27 | } |
25 | 28 |
|
26 | | - @action |
27 | | - toggleReordering() { |
28 | | - this.isReordering = !this.isReordering; |
29 | | - console.info('toggleReordering'); |
30 | | - const length = this.args.collection.length; |
31 | | - console.info('length: ', length); |
32 | | - |
| 29 | + get container() { |
| 30 | + const container = document.getElementById(this.args.tableId); |
| 31 | + return container; |
| 32 | + } |
33 | 33 |
|
34 | | - const observer = new MutationObserver((mutationList) => { |
35 | | - console.info('MUTATION: ', mutationList); |
36 | | - console.info('MUTATION: ', mutationList[0]); |
37 | | - }); |
38 | | - observer.observe(document.querySelector(`#${this.args.tableId} tbody`), { |
39 | | - childList: true, |
| 34 | + handleCollectionChange() { |
| 35 | + schedule('afterRender', this, function() { |
| 36 | + this.setupDomSorting(); |
40 | 37 | }); |
| 38 | + } |
41 | 39 |
|
42 | | - this.makeSortable(); |
| 40 | + @action |
| 41 | + toggleReordering() { |
| 42 | + this.isReordering = !this.isReordering; |
| 43 | + this.setupDomSorting(); |
43 | 44 | } |
44 | 45 |
|
45 | | - makeSortable() { |
46 | | - const container = document.getElementById(this.args.tableId); |
| 46 | + setupDomSorting() { |
| 47 | + this.destroyDomSorting(); |
47 | 48 |
|
48 | | - if (this.isReordering) { |
49 | | - container.classList.add('reorder-active'); |
| 49 | + if(!this.container) { |
| 50 | + console.error('tableId doesn not exist: ', this.args.tableId); |
| 51 | + return; |
| 52 | + } |
| 53 | + |
| 54 | + if(this.isReordering) { |
| 55 | + this.container.classList.add('reorder-active'); |
50 | 56 | } else { |
51 | | - container.classList.remove('reorder-active'); |
| 57 | + this.container.classList.remove('reorder-active'); |
52 | 58 | } |
53 | 59 |
|
54 | | - const manager = new DragDropManager({ |
| 60 | + this.manager = new DragDropManager({ |
55 | 61 | modifiers: (defaults) => [...defaults, RestrictToVerticalAxis], |
56 | 62 | }); |
57 | | - const tableRowEls = container.querySelectorAll('tbody tr'); |
58 | | - for (const [index, tableRowEl] of tableRowEls.entries()) { |
59 | | - console.info(tableRowEl); |
60 | | - const sortable = new Sortable({ |
| 63 | + |
| 64 | + this.sortables = []; |
| 65 | + const tableRowEls = this.container.querySelectorAll('tbody tr'); |
| 66 | + for(const [index, tableRowEl] of tableRowEls.entries()) { |
| 67 | + this.sortables.push(new Sortable({ |
61 | 68 | id: tableRowEl.dataset.guid, |
62 | 69 | index, |
63 | 70 | element: tableRowEl, |
64 | 71 | handle: tableRowEl.querySelector('.reorder-handle'), |
65 | | - }, manager); |
| 72 | + }, this.manager)); |
| 73 | + } |
| 74 | + |
| 75 | + this.manager.monitor.addEventListener('dragend', this.handleDragEnd.bind(this)); |
| 76 | + } |
| 77 | + |
| 78 | + destroyDomSorting() { |
| 79 | + if(this.manager) { |
| 80 | + this.manager.destroy(); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + handleDragEnd(event) { |
| 85 | + if(event.canceled || !isSortable(event.operation.source)) { |
| 86 | + return; |
| 87 | + } |
| 88 | + |
| 89 | + const indexes = {}; |
| 90 | + for(const sortable of this.sortables) { |
| 91 | + indexes[sortable.id] = sortable.index; |
| 92 | + } |
| 93 | + |
| 94 | + this.updateCollectionSortOrders(indexes); |
| 95 | + } |
| 96 | + |
| 97 | + updateCollectionSortOrders(indexes) { |
| 98 | + for(const record of this.args.collection) { |
| 99 | + const index = indexes[guidFor(record)]; |
| 100 | + record.set('sortOrder', index + 1); |
66 | 101 | } |
67 | 102 | } |
68 | 103 | } |
0 commit comments