Browse Source

refactor: Long jobs and floating box improvements

Owen Diffey 2 years ago
parent
commit
775e0a79c3

+ 61 - 33
frontend/src/components/FloatingBox.vue

@@ -19,7 +19,9 @@
 			<span class="drag material-icons" @dblclick="resetBoxPosition()"
 				>drag_indicator</span
 			>
-			<span v-if="title" class="box-title">{{ title }}</span>
+			<span v-if="title" class="box-title" :title="title">{{
+				title
+			}}</span>
 			<span
 				v-if="!persist"
 				class="delete material-icons"
@@ -51,7 +53,8 @@ export default {
 	},
 	data() {
 		return {
-			shown: false
+			shown: false,
+			debounceTimeout: null
 		};
 	},
 	mounted() {
@@ -68,44 +71,53 @@ export default {
 		} else {
 			initial.top =
 				this.initial === "align-bottom"
-					? document.body.clientHeight - 10 - initial.height
+					? Math.max(
+							document.body.clientHeight - 10 - initial.height,
+							0
+					  )
 					: 10;
 		}
 		this.setInitialBox(initial, true);
+
+		this.$nextTick(() => {
+			this.onWindowResize();
+			window.addEventListener("resize", this.onWindowResize);
+		});
+	},
+	unmounted() {
+		window.removeEventListener("resize", this.onWindowResize);
+		if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
 	},
 	methods: {
+		setBoxDimensions(width, height) {
+			this.dragBox.height = Math.min(
+				Math.max(height, this.minHeight),
+				this.maxHeight,
+				document.body.clientHeight
+			);
+
+			this.dragBox.width = Math.min(
+				Math.max(width, this.minWidth),
+				this.maxWidth,
+				document.body.clientWidth
+			);
+		},
 		onResizeBox(e) {
 			if (e.target !== this.$refs.box) return;
 
 			document.onmouseup = () => {
 				document.onmouseup = null;
 
-				const { height, width } = e.target.style;
-
-				this.dragBox.height = Math.min(
-					Math.max(
-						Number(
-							height
-								.split("")
-								.splice(0, height.length - 2)
-								.join("")
-						),
-						this.minHeight
-					),
-					this.maxHeight
-				);
-
-				this.dragBox.width = Math.min(
-					Math.max(
-						Number(
-							width
-								.split("")
-								.splice(0, width.length - 2)
-								.join("")
-						),
-						this.minWidth
-					),
-					this.maxWidth
+				const { width, height } = e.target.style;
+				this.setBoxDimensions(
+					width
+						.split("")
+						.splice(0, width.length - 2)
+						.join(""),
+					height
+						.split("")
+						.splice(0, height.length - 2)
+						.join("")
 				);
 
 				this.saveBox();
@@ -116,8 +128,7 @@ export default {
 			this.saveBox();
 		},
 		resetBoxDimensions() {
-			this.dragBox.width = 200;
-			this.dragBox.height = 200;
+			this.setBoxDimensions(200, 200);
 			this.saveBox();
 		},
 		saveBox() {
@@ -135,13 +146,27 @@ export default {
 			this.setInitialBox({
 				top:
 					this.initial === "align-bottom"
-						? document.body.clientHeight - 10 - this.dragBox.height
+						? Math.max(
+								document.body.clientHeight -
+									10 -
+									this.dragBox.height,
+								0
+						  )
 						: 10,
 				left: 10
 			});
 		},
 		onDragBoxUpdate() {
-			this.saveBox();
+			this.onWindowResize();
+		},
+		onWindowResize() {
+			if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
+
+			this.debounceTimeout = setTimeout(() => {
+				const { width, height } = this.dragBox;
+				this.setBoxDimensions(width + 0, height + 0);
+				this.saveBox();
+			}, 50);
 		}
 	}
 };
@@ -182,6 +207,9 @@ export default {
 			font-weight: 600;
 			line-height: 30px;
 			margin-right: 5px;
+			text-overflow: ellipsis;
+			white-space: nowrap;
+			overflow: hidden;
 		}
 
 		.material-icons {

+ 109 - 54
frontend/src/components/LongJobs.vue

@@ -17,47 +17,66 @@
 					:key="`activeJob-${job.id}`"
 					class="active-job"
 				>
+					<i
+						v-if="
+							job.status === 'started' || job.status === 'update'
+						"
+						class="material-icons"
+						content="In Progress"
+						v-tippy="{ theme: 'info', placement: 'right' }"
+					>
+						pending
+					</i>
+					<i
+						v-else-if="job.status === 'success'"
+						class="material-icons success"
+						content="Complete"
+						v-tippy="{ theme: 'info', placement: 'right' }"
+					>
+						check_circle
+					</i>
+					<i
+						v-else
+						class="material-icons error"
+						content="Failed"
+						v-tippy="{ theme: 'info', placement: 'right' }"
+					>
+						error
+					</i>
 					<div class="name" :title="job.name">{{ job.name }}</div>
 					<div class="actions">
-						<i
-							v-if="
-								job.status === 'started' ||
-								job.status === 'update'
-							"
-							class="material-icons"
-							content="In Progress"
-							v-tippy="{ theme: 'info' }"
-						>
-							pending
-						</i>
-						<i
-							v-else-if="job.status === 'success'"
-							class="material-icons success"
-							content="Complete"
-							v-tippy="{ theme: 'info' }"
-						>
-							check_circle
-						</i>
-						<i
-							v-else
-							class="material-icons error"
-							content="Failed"
-							v-tippy="{ theme: 'info' }"
-						>
-							error
-						</i>
-						<i class="material-icons" content="View Log" v-tippy>
-							description
-						</i>
 						<i
 							class="material-icons clear"
-							:class="{ disabled: job.status !== 'success' }"
+							:class="{
+								disabled: !(
+									job.status === 'success' ||
+									job.status === 'error'
+								)
+							}"
 							content="Clear"
-							v-tippy
+							v-tippy="{ placement: 'left' }"
 							@click="remove(job)"
 						>
 							remove_circle
 						</i>
+						<tippy
+							:touch="true"
+							:interactive="true"
+							placement="left"
+							ref="longJobMessage"
+							:append-to="body"
+						>
+							<i class="material-icons">chat</i>
+
+							<template #content>
+								<div class="long-job-message">
+									<strong>Latest Update:</strong>
+									<span :title="job.message">{{
+										job.message
+									}}</span>
+								</div>
+							</template>
+						</tippy>
 					</div>
 				</div>
 			</div>
@@ -76,7 +95,8 @@ export default {
 	},
 	data() {
 		return {
-			minimise: true
+			minimise: true,
+			body: document.body
 		};
 	},
 	computed: {
@@ -95,13 +115,19 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.night-mode #longJobs {
-	.active-jobs {
-		.active-job {
-			background-color: var(--dark-grey);
-			border: 0;
+.night-mode {
+	#longJobs {
+		.active-jobs {
+			.active-job {
+				background-color: var(--dark-grey);
+				border: 0;
+			}
 		}
 	}
+
+	.long-job-message {
+		color: var(--black);
+	}
 }
 
 #longJobs {
@@ -133,31 +159,60 @@ export default {
 				margin-right: auto;
 			}
 
+			.material-icons {
+				font-size: 20px;
+				color: var(--primary-color);
+				margin: auto 5px auto 0;
+				cursor: pointer;
+
+				&.success {
+					color: var(--green);
+				}
+
+				&.error,
+				&.clear {
+					color: var(--red);
+				}
+
+				&.disabled {
+					color: var(--light-grey-3);
+					cursor: not-allowed;
+				}
+			}
+
 			.actions {
 				display: flex;
 
 				.material-icons {
-					font-size: 20px;
-					color: var(--primary-color);
 					margin: auto 0 auto 5px;
-					cursor: pointer;
-
-					&.success {
-						color: var(--green);
-					}
-
-					&.error,
-					&.clear {
-						color: var(--red);
-					}
+				}
 
-					&.disabled {
-						color: var(--light-grey-3);
-						cursor: not-allowed;
-					}
+				& > span {
+					display: flex;
+					padding: 0;
 				}
 			}
 		}
 	}
 }
+
+.long-job-message {
+	display: flex;
+	flex-direction: column;
+
+	strong {
+		font-size: 12px;
+	}
+
+	span {
+		display: -webkit-inline-box;
+		text-overflow: ellipsis;
+		white-space: normal;
+		-webkit-box-orient: vertical;
+		-webkit-line-clamp: 3;
+		overflow: hidden;
+		max-width: 200px;
+		font-size: 12px;
+	}
+}
 </style>

+ 6 - 1
frontend/src/components/modals/EditSong/index.vue

@@ -679,7 +679,12 @@
 				</div>
 			</template>
 		</modal>
-		<floating-box id="genreHelper" ref="genreHelper" :column="false">
+		<floating-box
+			id="genreHelper"
+			ref="genreHelper"
+			:column="false"
+			title="Song Genres List"
+		>
 			<template #body>
 				<span
 					v-for="item in autosuggest.allItems.genres"

+ 4 - 4
frontend/src/mixins/DragBox.vue

@@ -87,20 +87,20 @@ export default {
 				this.dragBox.top -= this.dragBox.pos2;
 				this.dragBox.left -= this.dragBox.pos1;
 
-				if (this.dragBox.top < 0) this.dragBox.top = 0;
 				if (
 					this.dragBox.top >
 					document.body.clientHeight - this.dragBox.height
 				)
 					this.dragBox.top =
 						document.body.clientHeight - this.dragBox.height;
-				if (this.dragBox.left < 0) this.dragBox.left = 0;
+				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 = () => {
@@ -131,20 +131,20 @@ export default {
 				)
 					this.resetBoxPosition();
 				else {
-					if (this.dragBox.top < 0) this.dragBox.top = 0;
 					if (
 						this.dragBox.top >
 						document.body.clientHeight - this.dragBox.height
 					)
 						this.dragBox.top =
 							document.body.clientHeight - this.dragBox.height;
-					if (this.dragBox.left < 0) this.dragBox.left = 0;
+					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();

+ 1 - 0
frontend/src/pages/Admin/index.vue

@@ -258,6 +258,7 @@
 		<floating-box
 			id="keyboardShortcutsHelper"
 			ref="keyboardShortcutsHelper"
+			title="Admin Keyboard Shortcuts"
 		>
 			<template #body>
 				<div>

+ 6 - 1
frontend/src/pages/Station/index.vue

@@ -559,7 +559,11 @@
 			<main-footer />
 		</div>
 
-		<floating-box id="player-debug-box" ref="playerDebugBox">
+		<floating-box
+			id="player-debug-box"
+			ref="playerDebugBox"
+			title="Station Debug"
+		>
 			<template #body>
 				<span><b>No song</b>: {{ noSong }}</span>
 				<span><b>Song id</b>: {{ currentSong._id }}</span>
@@ -645,6 +649,7 @@
 		<floating-box
 			id="keyboardShortcutsHelper"
 			ref="keyboardShortcutsHelper"
+			title="Station Keyboard Shortcuts"
 		>
 			<template #body>
 				<div>

+ 4 - 5
frontend/src/store/modules/longJobs.js

@@ -6,7 +6,7 @@ const state = {
 			id: 1,
 			name: "test",
 			status: "success",
-			log: [{ status: "success", message: "test" }]
+			message: "test"
 		}
 	]
 };
@@ -24,17 +24,16 @@ const mutations = {
 			state.activeJobs.push({
 				id,
 				name,
-				status,
-				log: [{ status, message }]
+				status
 			});
 		else
 			state.activeJobs.forEach((activeJob, index) => {
 				if (activeJob.id === id) {
 					state.activeJobs[index] = {
 						...state.activeJobs[index],
-						status
+						status,
+						message
 					};
-					state.activeJobs[index].log.push({ status, message });
 				}
 			});
 	},