Преглед на файлове

refactor: Continued converting advanced table and queue to composition api

Owen Diffey преди 2 години
родител
ревизия
cf9ba3c0b3
променени са 3 файла, в които са добавени 54 реда и са изтрити 203 реда
  1. 50 43
      frontend/src/components/AdvancedTable.vue
  2. 4 4
      frontend/src/components/Queue.vue
  3. 0 156
      frontend/src/mixins/DragBox.vue

+ 50 - 43
frontend/src/components/AdvancedTable.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
 <script setup lang="ts">
-// TODO
 import { useStore } from "vuex";
 import { useStore } from "vuex";
 import {
 import {
 	defineAsyncComponent,
 	defineAsyncComponent,
@@ -149,17 +148,20 @@ const allFilterTypes = ref({
 		displayName: "Special"
 		displayName: "Special"
 	}
 	}
 });
 });
-const addFilterValue = ref(null);
+const addFilterValue = ref();
 const showFiltersDropdown = ref(false);
 const showFiltersDropdown = ref(false);
 const showColumnsDropdown = ref(false);
 const showColumnsDropdown = ref(false);
-const lastColumnResizerTapped = ref(null);
+const lastColumnResizerTapped = ref();
 const lastColumnResizerTappedDate = ref(0);
 const lastColumnResizerTappedDate = ref(0);
 const autosuggest = ref({
 const autosuggest = ref({
 	allItems: {}
 	allItems: {}
 });
 });
-const storeTableSettingsDebounceTimeout = ref(null);
-const windowResizeDebounceTimeout = ref(null);
+const storeTableSettingsDebounceTimeout = ref();
+const windowResizeDebounceTimeout = ref();
+const columnOrderChangedDebounceTimeout = ref();
 const lastSelectedItemIndex = ref(0);
 const lastSelectedItemIndex = ref(0);
+const bulkPopup = ref();
+const rowElements = ref([]);
 
 
 const lastPage = computed(() => Math.ceil(count.value / pageSize.value));
 const lastPage = computed(() => Math.ceil(count.value / pageSize.value));
 const sortedFilteredColumns = computed(() =>
 const sortedFilteredColumns = computed(() =>
@@ -453,17 +455,16 @@ const toggleAllRows = () => {
 };
 };
 
 
 const highlightRow = async itemIndex => {
 const highlightRow = async itemIndex => {
-	// TODO
-	// const rowElement = this.$refs[`row-${itemIndex}`]
-	// 	? this.$refs[`row-${itemIndex}`][0]
-	// 	: null;
+	const rowElement = rowElements.value[`row-${itemIndex}`]
+		? rowElements.value[`row-${itemIndex}`][0]
+		: null;
 	// Set the last clicked item to no longer be highlighted, if it exists
 	// Set the last clicked item to no longer be highlighted, if it exists
 	if (lastSelectedItemIndex.value >= 0)
 	if (lastSelectedItemIndex.value >= 0)
 		rows.value[lastSelectedItemIndex.value].highlighted = false;
 		rows.value[lastSelectedItemIndex.value].highlighted = false;
-	// if (rowElement) {
-	// 	await nextTick();
-	// 	rowElement.focus();
-	// }
+	if (rowElement) {
+		await nextTick();
+		rowElement.focus();
+	}
 	// Set the item to be highlighted
 	// Set the item to be highlighted
 	rows.value[itemIndex].highlighted = true;
 	rows.value[itemIndex].highlighted = true;
 };
 };
@@ -481,14 +482,13 @@ const highlightDown = itemIndex => {
 };
 };
 
 
 const unhighlightRow = async itemIndex => {
 const unhighlightRow = async itemIndex => {
-	// TODO
-	// const rowElement = this.$refs[`row-${itemIndex}`]
-	// 	? this.$refs[`row-${itemIndex}`][0]
-	// 	: null;
-	// if (rowElement) {
-	// 	await nextTick();
-	// 	rowElement.blur();
-	// }
+	const rowElement = rowElements.value[`row-${itemIndex}`]
+		? rowElements.value[`row-${itemIndex}`][0]
+		: null;
+	if (rowElement) {
+		await nextTick();
+		rowElement.blur();
+	}
 	// Set the item to no longer be highlighted
 	// Set the item to no longer be highlighted
 	rows.value[itemIndex].highlighted = false;
 	rows.value[itemIndex].highlighted = false;
 };
 };
@@ -649,8 +649,19 @@ const applyFilterAndGetData = () => {
 	storeTableSettings();
 	storeTableSettings();
 };
 };
 
 
-const columnOrderChanged = () => {
-	storeTableSettings();
+const columnOrderChanged = ({ oldIndex, newIndex }) => {
+	if (columnOrderChangedDebounceTimeout.value)
+		clearTimeout(columnOrderChangedDebounceTimeout.value);
+
+	columnOrderChangedDebounceTimeout.value = setTimeout(() => {
+		if (oldIndex === newIndex) return;
+		orderedColumns.value.splice(
+			newIndex,
+			0,
+			orderedColumns.value.splice(oldIndex, 1)[0]
+		);
+		storeTableSettings();
+	}, 100);
 };
 };
 
 
 const getTableSettings = () => {
 const getTableSettings = () => {
@@ -1059,14 +1070,11 @@ onMounted(async () => {
 					preventDefault: true,
 					preventDefault: true,
 					handler: () => {
 					handler: () => {
 						// Execute popup action 1-9
 						// Execute popup action 1-9
-						// if (aModalIsOpen.value) return;
-						// if (selectedRows.value.length === 0) return;
-						// TODO
-						// const bulkActionsElement =
-						// 	this.$refs["bulk-popup"].querySelector(
-						// 		".bulk-actions"
-						// 	);
-						// bulkActionsElement.children[i - 1].click();
+						if (aModalIsOpen.value) return;
+						if (selectedRows.value.length === 0) return;
+						const bulkActionsElement =
+							bulkPopup.value.querySelector(".bulk-actions");
+						bulkActionsElement.children[i - 1].click();
 					}
 					}
 				}
 				}
 			);
 			);
@@ -1078,16 +1086,13 @@ onMounted(async () => {
 			preventDefault: true,
 			preventDefault: true,
 			handler: () => {
 			handler: () => {
 				// Select popup action 0
 				// Select popup action 0
-				// if (aModalIsOpen.value) return;
-				// if (selectedRows.value.length === 0) return;
-				// TODO
-				// const bulkActionsElement =
-				// 	this.$refs["bulk-popup"].querySelector(
-				// 		".bulk-actions"
-				// 	);
-				// bulkActionsElement.children[
-				// 	bulkActionsElement.children.length - 1
-				// ].focus();
+				if (aModalIsOpen.value) return;
+				if (selectedRows.value.length === 0) return;
+				const bulkActionsElement =
+					bulkPopup.value.querySelector(".bulk-actions");
+				bulkActionsElement.children[
+					bulkActionsElement.children.length - 1
+				].focus();
 			}
 			}
 		});
 		});
 	}
 	}
@@ -1104,6 +1109,8 @@ onUnmounted(() => {
 		clearTimeout(storeTableSettingsDebounceTimeout.value);
 		clearTimeout(storeTableSettingsDebounceTimeout.value);
 	if (windowResizeDebounceTimeout.value)
 	if (windowResizeDebounceTimeout.value)
 		clearTimeout(windowResizeDebounceTimeout.value);
 		clearTimeout(windowResizeDebounceTimeout.value);
+	if (columnOrderChangedDebounceTimeout.value)
+		clearTimeout(columnOrderChangedDebounceTimeout.value);
 
 
 	if (props.keyboardShortcuts) {
 	if (props.keyboardShortcuts) {
 		const shortcutNames = [
 		const shortcutNames = [
@@ -1675,7 +1682,7 @@ watch(
 								updated: item.updated,
 								updated: item.updated,
 								removed: item.removed
 								removed: item.removed
 							}"
 							}"
-							:ref="`row-${itemIndex}`"
+							:ref="el => (rowElements[`row-${itemIndex}`] = el)"
 							tabindex="0"
 							tabindex="0"
 							@blur="unhighlightRow(itemIndex)"
 							@blur="unhighlightRow(itemIndex)"
 							@keydown.up.prevent
 							@keydown.up.prevent
@@ -1855,7 +1862,7 @@ watch(
 				width: dragBox.width + 'px',
 				width: dragBox.width + 'px',
 				height: dragBox.height + 'px'
 				height: dragBox.height + 'px'
 			}"
 			}"
-			ref="bulk-popup"
+			ref="bulkPopup"
 		>
 		>
 			<button
 			<button
 				class="button is-primary"
 				class="button is-primary"

+ 4 - 4
frontend/src/components/Queue.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
 <script setup lang="ts">
-// TODO
 import { useStore } from "vuex";
 import { useStore } from "vuex";
 import { defineAsyncComponent, ref, computed, onUpdated } from "vue";
 import { defineAsyncComponent, ref, computed, onUpdated } from "vue";
 import { Sortable } from "sortablejs-vue3";
 import { Sortable } from "sortablejs-vue3";
@@ -34,6 +33,7 @@ const repositionSongInList = payload => {
 
 
 const actionableButtonVisible = ref(false);
 const actionableButtonVisible = ref(false);
 const drag = ref(false);
 const drag = ref(false);
+const songItems = ref([]);
 
 
 const station = computed({
 const station = computed({
 	get: () => {
 	get: () => {
@@ -116,7 +116,7 @@ const repositionSongInQueue = ({ oldIndex, newIndex }) => {
 };
 };
 
 
 const moveSongToTop = index => {
 const moveSongToTop = index => {
-	// this.$refs[`song-item-${index}`].$refs.songActions.tippy.hide();
+	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide();
 
 
 	repositionSongInQueue({
 	repositionSongInQueue({
 		oldIndex: index,
 		oldIndex: index,
@@ -125,7 +125,7 @@ const moveSongToTop = index => {
 };
 };
 
 
 const moveSongToBottom = index => {
 const moveSongToBottom = index => {
-	// this.$refs[`song-item-${index}`].$refs.songActions.tippy.hide();
+	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide();
 
 
 	repositionSongInQueue({
 	repositionSongInQueue({
 		oldIndex: index,
 		oldIndex: index,
@@ -170,7 +170,7 @@ onUpdated(() => {
 							'item-draggable': isAdminOnly() || isOwnerOnly()
 							'item-draggable': isAdminOnly() || isOwnerOnly()
 						}"
 						}"
 						:disabled-actions="[]"
 						:disabled-actions="[]"
-						:ref="`song-item-${index}`"
+						:ref="el => (songItems[`song-item-${index}`] = el)"
 					>
 					>
 						<template
 						<template
 							v-if="isAdminOnly() || isOwnerOnly()"
 							v-if="isAdminOnly() || isOwnerOnly()"

+ 0 - 156
frontend/src/mixins/DragBox.vue

@@ -1,156 +0,0 @@
-<script>
-export default {
-	data() {
-		return {
-			dragBox: {
-				top: 0,
-				left: 0,
-				pos1: 0,
-				pos2: 0,
-				pos3: 0,
-				pos4: 0,
-				width: 400,
-				height: 50,
-				initial: {
-					top: 0,
-					left: 0
-				},
-				latest: {
-					top: null,
-					left: null
-				},
-				debounceTimeout: null,
-				lastTappedDate: 0
-			}
-		};
-	},
-	mounted() {
-		this.resetBoxPosition(true);
-
-		this.$nextTick(() => {
-			this.onWindowResizeDragBox();
-			window.addEventListener("resize", this.onWindowResizeDragBox);
-		});
-	},
-	unmounted() {
-		window.removeEventListener("resize", this.onWindowResizeDragBox);
-		if (this.dragBox.debounceTimeout)
-			clearTimeout(this.dragBox.debounceTimeout);
-	},
-	methods: {
-		setInitialBox(initial, reset) {
-			this.dragBox.initial = initial || this.dragBox.initial;
-			if (reset)
-				this.dragBox = { ...this.dragBox, ...this.dragBox.initial };
-		},
-		onDragBox(e) {
-			const e1 = e || window.event;
-			const e1IsTouch = e1.type === "touchstart";
-			e1.preventDefault();
-
-			if (e1IsTouch) {
-				// Handle double click from touch (if this method is twice in a row within one second)
-				if (Date.now() - this.dragBox.lastTappedDate <= 1000) {
-					this.resetBoxPosition();
-					this.dragBox.lastTappedDate = 0;
-					return;
-				}
-				this.dragBox.lastTappedDate = Date.now();
-			}
-
-			this.dragBox.pos3 = e1IsTouch
-				? e1.changedTouches[0].clientX
-				: e1.clientX;
-			this.dragBox.pos4 = e1IsTouch
-				? e1.changedTouches[0].clientY
-				: e1.clientY;
-
-			document.onmousemove = document.ontouchmove = e => {
-				const e2 = e || window.event;
-				const e2IsTouch = e2.type === "touchmove";
-				if (!e2IsTouch) e2.preventDefault();
-
-				// Get the clientX and clientY
-				const e2ClientX = e2IsTouch
-					? e2.changedTouches[0].clientX
-					: e2.clientX;
-				const e2ClientY = e2IsTouch
-					? e2.changedTouches[0].clientY
-					: e2.clientY;
-
-				// calculate the new cursor position:
-				this.dragBox.pos1 = this.dragBox.pos3 - e2ClientX;
-				this.dragBox.pos2 = this.dragBox.pos4 - e2ClientY;
-				this.dragBox.pos3 = e2ClientX;
-				this.dragBox.pos4 = e2ClientY;
-				// set the element's new position:
-				this.dragBox.top -= this.dragBox.pos2;
-				this.dragBox.left -= this.dragBox.pos1;
-
-				if (
-					this.dragBox.top >
-					document.body.clientHeight - this.dragBox.height
-				)
-					this.dragBox.top =
-						document.body.clientHeight - this.dragBox.height;
-				if (this.dragBox.top < 0) this.dragBox.top = 0;
-				if (
-					this.dragBox.left >
-					document.body.clientWidth - this.dragBox.width
-				)
-					this.dragBox.left =
-						document.body.clientWidth - this.dragBox.width;
-				if (this.dragBox.left < 0) this.dragBox.left = 0;
-			};
-
-			document.onmouseup = document.ontouchend = () => {
-				document.onmouseup = null;
-				document.ontouchend = null;
-				document.onmousemove = null;
-				document.ontouchmove = null;
-
-				if (typeof this.onDragBoxUpdate === "function")
-					this.onDragBoxUpdate();
-			};
-		},
-		resetBoxPosition(preventUpdate) {
-			this.setInitialBox(null, true);
-			this.dragBox.latest.top = this.dragBox.top;
-			this.dragBox.latest.left = this.dragBox.left;
-			if (!preventUpdate && typeof this.onDragBoxUpdate === "function")
-				this.onDragBoxUpdate();
-		},
-		onWindowResizeDragBox() {
-			if (this.dragBox.debounceTimeout)
-				clearTimeout(this.dragBox.debounceTimeout);
-
-			this.dragBox.debounceTimeout = setTimeout(() => {
-				if (
-					this.dragBox.top === this.dragBox.latest.top &&
-					this.dragBox.left === this.dragBox.latest.left
-				)
-					this.resetBoxPosition();
-				else {
-					if (
-						this.dragBox.top >
-						document.body.clientHeight - this.dragBox.height
-					)
-						this.dragBox.top =
-							document.body.clientHeight - this.dragBox.height;
-					if (this.dragBox.top < 0) this.dragBox.top = 0;
-					if (
-						this.dragBox.left >
-						document.body.clientWidth - this.dragBox.width
-					)
-						this.dragBox.left =
-							document.body.clientWidth - this.dragBox.width;
-					if (this.dragBox.left < 0) this.dragBox.left = 0;
-
-					if (typeof this.onDragBoxUpdate === "function")
-						this.onDragBoxUpdate();
-				}
-			}, 50);
-		}
-	}
-};
-</script>