| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  | {{define "component/sortableTableTrigger"}} | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | <a-icon type="drag" class="sortable-icon" style="cursor: move;" @mouseup="mouseUpHandler" @mousedown="mouseDownHandler" | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   @click="clickHandler" /> | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  | {{end}} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-17 11:26:07 +00:00
										 |  |  | {{define "component/aTableSortable"}} | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  | <script> | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   const DRAGGABLE_ROW_CLASS = 'draggable-row'; | 
					
						
							|  |  |  |   const findParentRowElement = (el) => { | 
					
						
							|  |  |  |     if (!el || !el.tagName) { | 
					
						
							|  |  |  |       return null; | 
					
						
							|  |  |  |     } else if (el.classList.contains(DRAGGABLE_ROW_CLASS)) { | 
					
						
							|  |  |  |       return el; | 
					
						
							|  |  |  |     } else if (el.parentNode) { | 
					
						
							|  |  |  |       return findParentRowElement(el.parentNode); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return null; | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   Vue.component('a-table-sortable', { | 
					
						
							|  |  |  |     data() { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         sortingElementIndex: null, | 
					
						
							|  |  |  |         newElementIndex: null, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  |     props: { | 
					
						
							|  |  |  |       'data-source': { | 
					
						
							|  |  |  |         type: undefined, | 
					
						
							|  |  |  |         required: false, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       'customRow': { | 
					
						
							|  |  |  |         type: undefined, | 
					
						
							|  |  |  |         required: false, | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |     inheritAttrs: false, | 
					
						
							|  |  |  |     provide() { | 
					
						
							|  |  |  |       const sortable = {} | 
					
						
							|  |  |  |       Object.defineProperty(sortable, "setSortableIndex", { | 
					
						
							|  |  |  |         enumerable: true, | 
					
						
							|  |  |  |         get: () => this.setCurrentSortableIndex, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       Object.defineProperty(sortable, "resetSortableIndex", { | 
					
						
							|  |  |  |         enumerable: true, | 
					
						
							|  |  |  |         get: () => this.resetSortableIndex, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         sortable, | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  |     render: function (createElement) { | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |       return createElement('a-table', { | 
					
						
							|  |  |  |         class: { | 
					
						
							|  |  |  |           'ant-table-is-sorting': this.isDragging(), | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         props: { | 
					
						
							|  |  |  |           ...this.$attrs, | 
					
						
							|  |  |  |           'data-source': this.records, | 
					
						
							|  |  |  |           customRow: (record, index) => this.customRowRender(record, index), | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         on: this.$listeners, | 
					
						
							|  |  |  |         nativeOn: { | 
					
						
							|  |  |  |           drop: (e) => this.dropHandler(e), | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         scopedSlots: this.$scopedSlots, | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  |       }, this.$slots.default,) | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     created() { | 
					
						
							|  |  |  |       this.$memoSort = {}; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     methods: { | 
					
						
							|  |  |  |       isDragging() { | 
					
						
							|  |  |  |         const currentIndex = this.sortingElementIndex; | 
					
						
							|  |  |  |         return currentIndex !== null && currentIndex !== undefined; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       resetSortableIndex(e, index) { | 
					
						
							|  |  |  |         this.sortingElementIndex = null; | 
					
						
							|  |  |  |         this.newElementIndex = null; | 
					
						
							|  |  |  |         this.$memoSort = {}; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       setCurrentSortableIndex(e, index) { | 
					
						
							|  |  |  |         this.sortingElementIndex = index; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       dragStartHandler(e, index) { | 
					
						
							|  |  |  |         if (!this.isDragging()) { | 
					
						
							|  |  |  |           e.preventDefault(); | 
					
						
							|  |  |  |           return; | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         const hideDragImage = this.$el.cloneNode(true); | 
					
						
							|  |  |  |         hideDragImage.id = "hideDragImage-hide"; | 
					
						
							|  |  |  |         hideDragImage.style.opacity = 0; | 
					
						
							|  |  |  |         e.dataTransfer.setDragImage(hideDragImage, 0, 0); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       dragStopHandler(e, index) { | 
					
						
							|  |  |  |         const hideDragImage = document.getElementById('hideDragImage-hide'); | 
					
						
							|  |  |  |         if (hideDragImage) hideDragImage.remove(); | 
					
						
							|  |  |  |         this.resetSortableIndex(e, index); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       dragOverHandler(e, index) { | 
					
						
							|  |  |  |         if (!this.isDragging()) { | 
					
						
							|  |  |  |           return; | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         e.preventDefault(); | 
					
						
							|  |  |  |         const currentIndex = this.sortingElementIndex; | 
					
						
							|  |  |  |         if (index === currentIndex) { | 
					
						
							|  |  |  |           this.newElementIndex = null; | 
					
						
							|  |  |  |           return; | 
					
						
							| 
									
										
										
										
											2024-02-28 15:45:44 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |         const row = findParentRowElement(e.target); | 
					
						
							|  |  |  |         if (!row) { | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const rect = row.getBoundingClientRect(); | 
					
						
							|  |  |  |         const offsetTop = e.pageY - rect.top; | 
					
						
							|  |  |  |         if (offsetTop < rect.height / 2) { | 
					
						
							|  |  |  |           this.newElementIndex = Math.max(index - 1, 0); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           this.newElementIndex = index; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       dropHandler(e) { | 
					
						
							|  |  |  |         if (this.isDragging()) { | 
					
						
							|  |  |  |           this.$emit('onsort', this.sortingElementIndex, this.newElementIndex); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       customRowRender(record, index) { | 
					
						
							|  |  |  |         const parentMethodResult = this.customRow?.(record, index) || {}; | 
					
						
							|  |  |  |         const newIndex = this.newElementIndex; | 
					
						
							|  |  |  |         const currentIndex = this.sortingElementIndex; | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           ...parentMethodResult, | 
					
						
							|  |  |  |           attrs: { | 
					
						
							|  |  |  |             ...(parentMethodResult?.attrs || {}), | 
					
						
							|  |  |  |             draggable: true, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           on: { | 
					
						
							|  |  |  |             ...(parentMethodResult?.on || {}), | 
					
						
							|  |  |  |             dragstart: (e) => this.dragStartHandler(e, index), | 
					
						
							|  |  |  |             dragend: (e) => this.dragStopHandler(e, index), | 
					
						
							|  |  |  |             dragover: (e) => this.dragOverHandler(e, index), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           class: { | 
					
						
							|  |  |  |             ...(parentMethodResult?.class || {}), | 
					
						
							|  |  |  |             [DRAGGABLE_ROW_CLASS]: true, | 
					
						
							|  |  |  |             ['dragging']: this.isDragging() ? (newIndex === null ? index === currentIndex : index === newIndex) : false, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     computed: { | 
					
						
							|  |  |  |       records() { | 
					
						
							|  |  |  |         const newIndex = this.newElementIndex; | 
					
						
							|  |  |  |         const currentIndex = this.sortingElementIndex; | 
					
						
							|  |  |  |         if (!this.isDragging() || newIndex === null || currentIndex === newIndex) { | 
					
						
							|  |  |  |           return this.dataSource; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this.$memoSort.newIndex === newIndex) { | 
					
						
							|  |  |  |           return this.$memoSort.list; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         let list = [...this.dataSource]; | 
					
						
							|  |  |  |         list.splice(newIndex, 0, list.splice(currentIndex, 1)[0]); | 
					
						
							|  |  |  |         this.$memoSort = { | 
					
						
							|  |  |  |           newIndex, | 
					
						
							|  |  |  |           list, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         return list; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-02-28 15:45:44 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  |   Vue.component('a-table-sort-trigger', { | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |     template: `{{template "component/sortableTableTrigger"}}`, | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  |     props: { | 
					
						
							|  |  |  |       'item-index': { | 
					
						
							|  |  |  |         type: undefined, | 
					
						
							|  |  |  |         required: false | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |     inject: ['sortable'], | 
					
						
							|  |  |  |     methods: { | 
					
						
							|  |  |  |       mouseDownHandler(e) { | 
					
						
							|  |  |  |         if (this.sortable) { | 
					
						
							|  |  |  |           this.sortable.setSortableIndex(e, this.itemIndex); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       mouseUpHandler(e) { | 
					
						
							|  |  |  |         if (this.sortable) { | 
					
						
							|  |  |  |           this.sortable.resetSortableIndex(e, this.itemIndex); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       clickHandler(e) { | 
					
						
							|  |  |  |         e.preventDefault(); | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   }) | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  |   @media only screen and (max-width: 767px) { | 
					
						
							|  |  |  |     .sortable-icon { | 
					
						
							|  |  |  |       display: none; | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .ant-table-is-sorting .draggable-row td { | 
					
						
							|  |  |  |     background-color: #ffffff !important; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .dark .ant-table-is-sorting .draggable-row td { | 
					
						
							|  |  |  |     background-color: var(--dark-color-surface-100) !important; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .ant-table-is-sorting .dragging td { | 
					
						
							|  |  |  |     background-color: rgb(232 244 242) !important; | 
					
						
							|  |  |  |     color: rgba(0, 0, 0, 0.3); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .dark .ant-table-is-sorting .dragging td { | 
					
						
							|  |  |  |     background-color: var(--dark-color-table-hover) !important; | 
					
						
							|  |  |  |     color: rgba(255, 255, 255, 0.3); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .ant-table-is-sorting .dragging { | 
					
						
							|  |  |  |     opacity: 1; | 
					
						
							|  |  |  |     box-shadow: 1px -2px 2px #008771; | 
					
						
							|  |  |  |     transition: all 0.2s; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 18:45:36 +00:00
										 |  |  |   .ant-table-is-sorting .dragging .ant-table-row-index { | 
					
						
							|  |  |  |     opacity: 0.3; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-02-27 11:48:29 +00:00
										 |  |  | </style> | 
					
						
							| 
									
										
										
										
											2025-03-08 15:41:27 +00:00
										 |  |  | {{end}} |