mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-03-01 01:20:49 +03:00

* UI Improvements Better Table Update QR Code Modal Better Info Modal Compression HTML files Better Dropdown Menu Better Calendar and more .. Remove files Minor Fixes
217 lines
6.2 KiB
HTML
217 lines
6.2 KiB
HTML
{{define "component/sortableTableTrigger"}}
|
|
<a-icon type="drag"
|
|
class="sortable-icon"
|
|
style="cursor: move;"
|
|
@mouseup="mouseUpHandler"
|
|
@mousedown="mouseDownHandler"
|
|
@click="clickHandler" />
|
|
{{end}}
|
|
|
|
{{define "component/sortableTable"}}
|
|
<script>
|
|
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;
|
|
}
|
|
}
|
|
Vue.component('a-table-sortable', {
|
|
data() {
|
|
return {
|
|
sortingElementIndex: null,
|
|
newElementIndex: null,
|
|
};
|
|
},
|
|
props: ['data-source', 'customRow'],
|
|
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,
|
|
}
|
|
},
|
|
render: function(createElement) {
|
|
return createElement('a-table', {
|
|
class: {
|
|
'ant-table-is-sorting': this.isDragging(),
|
|
},
|
|
props: {
|
|
...this.$attrs,
|
|
'data-source': this.records,
|
|
customRow: (record, index) => this.customRowRender(record, index),
|
|
},
|
|
on: this.$listeners,
|
|
nativeOn: {
|
|
drop: (e) => this.dropHandler(e),
|
|
},
|
|
scopedSlots: this.$scopedSlots,
|
|
}, this.$slots.default, )
|
|
},
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
e.preventDefault();
|
|
const currentIndex = this.sortingElementIndex;
|
|
if (index === currentIndex) {
|
|
this.newElementIndex = null;
|
|
return;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
});
|
|
Vue.component('table-sort-trigger', {
|
|
template: `{{template "component/sortableTableTrigger"}}`,
|
|
props: ['item-index'],
|
|
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();
|
|
},
|
|
}
|
|
})
|
|
</script>
|
|
<style>
|
|
@media only screen and (max-width: 767px) {
|
|
.sortable-icon {
|
|
display: none;
|
|
}
|
|
}
|
|
.ant-table-is-sorting .draggable-row td {
|
|
background-color: #ffffff !important;
|
|
}
|
|
.dark .ant-table-is-sorting .draggable-row td {
|
|
background-color: var(--dark-color-surface-100) !important;
|
|
}
|
|
.ant-table-is-sorting .dragging td {
|
|
background-color: rgb(232 244 242) !important;
|
|
color: rgba(0, 0, 0, 0.3);
|
|
}
|
|
.dark .ant-table-is-sorting .dragging td {
|
|
background-color: var(--dark-color-table-hover) !important;
|
|
color: rgba(255, 255, 255, 0.3);
|
|
}
|
|
.ant-table-is-sorting .dragging {
|
|
opacity: 1;
|
|
box-shadow: 1px -2px 2px #008771;
|
|
transition: all 0.2s;
|
|
}
|
|
.ant-table-is-sorting .dragging .ant-table-row-index {
|
|
opacity: 0.3;
|
|
}
|
|
</style>
|
|
{{end}}
|