Browse Source

refactor(Reports): Show unresolved reports and allow toggling resolution

TODO: Report update events for advanced table, toggle button removed from admin/songs/reports until this is done
Owen Diffey 3 years ago
parent
commit
5628f2ed34

+ 15 - 8
backend/logic/actions/reports.js

@@ -25,10 +25,10 @@ CacheModule.runJob("SUB", {
 
 CacheModule.runJob("SUB", {
 	channel: "report.resolve",
-	cb: ({ reportId, songId }) =>
+	cb: ({ reportId, songId, resolved }) =>
 		WSModule.runJob("EMIT_TO_ROOMS", {
 			rooms: ["admin.reports", `edit-song.${songId}`, `view-report.${reportId}`],
-			args: ["event:admin.report.resolved", { data: { reportId } }]
+			args: ["event:admin.report.resolved", { data: { reportId, resolved } }]
 		})
 });
 
@@ -358,9 +358,10 @@ export default {
 	 *
 	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} reportId - the id of the report that is getting resolved
+	 * @param {boolean} resolved - whether to set to resolved to true or false
 	 * @param {Function} cb - gets called with the result
 	 */
-	resolve: isAdminRequired(async function resolve(session, reportId, cb) {
+	resolve: isAdminRequired(async function resolve(session, reportId, resolved, cb) {
 		const reportModel = await DBModule.runJob("GET_MODEL", { modelName: "report" }, this);
 
 		async.waterfall(
@@ -372,7 +373,7 @@ export default {
 				(report, next) => {
 					if (!report) return next("Report not found.");
 
-					report.resolved = true;
+					report.resolved = resolved;
 
 					return report.save(err => {
 						if (err) return next(err.message);
@@ -386,21 +387,27 @@ export default {
 					this.log(
 						"ERROR",
 						"REPORTS_RESOLVE",
-						`Resolving report "${reportId}" failed by user "${session.userId}". "${err}"`
+						`${resolved ? "R" : "Unr"}esolving report "${reportId}" failed by user "${
+							session.userId
+						}". "${err}"`
 					);
 					return cb({ status: "error", message: err });
 				}
 
 				CacheModule.runJob("PUB", {
 					channel: "report.resolve",
-					value: { reportId, songId }
+					value: { reportId, songId, resolved }
 				});
 
-				this.log("SUCCESS", "REPORTS_RESOLVE", `User "${session.userId}" resolved report "${reportId}".`);
+				this.log(
+					"SUCCESS",
+					"REPORTS_RESOLVE",
+					`User "${session.userId}" ${resolved ? "" : "un"}resolved report "${reportId}".`
+				);
 
 				return cb({
 					status: "success",
-					message: "Successfully resolved Report"
+					message: `Successfully ${resolved ? "" : "un"}resolved Report`
 				});
 			}
 		);

+ 2 - 2
frontend/src/api/admin/reports.js

@@ -4,9 +4,9 @@ import Toast from "toasters";
 import ws from "@/ws";
 
 export default {
-	resolve(reportId) {
+	resolve({ reportId, value }) {
 		return new Promise((resolve, reject) => {
-			ws.socket.dispatch("reports.resolve", reportId, res => {
+			ws.socket.dispatch("reports.resolve", reportId, value, res => {
 				new Toast(res.message);
 				if (res.status === "success")
 					return resolve({ status: "success" });

+ 30 - 22
frontend/src/components/modals/ViewReport.vue

@@ -73,25 +73,31 @@
 			</div>
 		</template>
 		<template #footer v-if="report && report._id">
-			<a class="button is-primary" @click="openSong()">
-				<i
-					class="material-icons icon-with-button"
-					content="Edit Song"
-					v-tippy
-				>
-					edit
-				</i>
-				Edit Song
+			<a
+				class="button is-primary material-icons icon-with-button"
+				@click="openSong()"
+				content="Edit Song"
+				v-tippy
+			>
+				edit
 			</a>
-			<button class="button is-success" @click="resolve()">
-				<i
-					class="material-icons icon-with-button"
-					content="Resolve"
-					v-tippy
-				>
-					done_all
-				</i>
-				Resolve
+			<button
+				v-if="report.resolved"
+				class="button is-danger material-icons icon-with-button"
+				@click="resolve(false)"
+				content="Unresolve"
+				v-tippy
+			>
+				remove_done
+			</button>
+			<button
+				v-else
+				class="button is-success material-icons icon-with-button"
+				@click="resolve(true)"
+				content="Resolve"
+				v-tippy
+			>
+				done_all
 			</button>
 			<div class="right">
 				<quick-confirm @confirm="remove()">
@@ -150,7 +156,9 @@ export default {
 
 		this.socket.on(
 			"event:admin.report.resolved",
-			() => this.closeModal("viewReport"),
+			res => {
+				this.report.resolved = res.data.resolved;
+			},
 			{ modal: "viewReport" }
 		);
 
@@ -210,10 +218,10 @@ export default {
 				}
 			});
 		},
-		resolve() {
-			return this.resolveReport(this.reportId)
+		resolve(value) {
+			return this.resolveReport({ reportId: this.reportId, value })
 				.then(res => {
-					if (res.status === "success") this.closeModal("viewReport");
+					if (res.status !== "success") new Toast(res.message);
 				})
 				.catch(err => new Toast(err.message));
 		},

+ 20 - 11
frontend/src/pages/Admin/Songs/Reports.vue

@@ -22,15 +22,6 @@
 						>
 							open_in_full
 						</button>
-						<button
-							class="button is-success icon-with-button material-icons"
-							@click="resolve(slotProps.item._id)"
-							:disabled="slotProps.item.removed"
-							content="Resolve Report"
-							v-tippy
-						>
-							done_all
-						</button>
 					</div>
 				</template>
 				<template #column-_id="slotProps">
@@ -54,6 +45,11 @@
 						{{ slotProps.item.song.youtubeId }}
 					</a>
 				</template>
+				<template #column-resolved="slotProps">
+					<span :title="slotProps.item.resolved">{{
+						slotProps.item.resolved
+					}}</span>
+				</template>
 				<template #column-categories="slotProps">
 					<span
 						:title="
@@ -134,8 +130,8 @@ export default {
 					sortable: false,
 					hidable: false,
 					resizable: false,
-					minWidth: 85,
-					defaultWidth: 85
+					minWidth: 76,
+					defaultWidth: 76
 				},
 				{
 					name: "_id",
@@ -161,6 +157,12 @@ export default {
 					minWidth: 165,
 					defaultWidth: 165
 				},
+				{
+					name: "resolved",
+					displayName: "Resolved",
+					properties: ["resolved"],
+					sortProperty: "resolved"
+				},
 				{
 					name: "categories",
 					displayName: "Categories",
@@ -204,6 +206,13 @@ export default {
 					filterTypes: ["contains", "exact", "regex"],
 					defaultFilterType: "contains"
 				},
+				{
+					name: "resolved",
+					displayName: "Resolved",
+					property: "resolved",
+					filterTypes: ["boolean"],
+					defaultFilterType: "boolean"
+				},
 				{
 					name: "categories",
 					displayName: "Categories",

+ 2 - 2
frontend/src/store/modules/admin.js

@@ -24,10 +24,10 @@ const modules = {
 		getters: {},
 		actions: {
 			/* eslint-disable-next-line no-unused-vars */
-			resolveReport: ({ commit }, reportId) =>
+			resolveReport: ({ commit }, { reportId, value }) =>
 				new Promise((resolve, reject) => {
 					admin.reports
-						.resolve(reportId)
+						.resolve({ reportId, value })
 						.then(res => resolve(res))
 						.catch(err => reject(new Error(err.message)));
 				}),