Explorar el Código

feat(AdvancedTable): added filterTypes, allowed multiple queries of the same property at the same time

Kristian Vos hace 3 años
padre
commit
1fcce2120c

+ 12 - 14
backend/logic/songs.js

@@ -223,31 +223,29 @@ class _SongsModule extends CoreClass {
 
 			console.log("GET_DATA", payload);
 
-			const regexFilter = {};
-			queries.forEach(query => {
-				const { data, filter } = query;
-				if (filter.type === "regex") {
-					let q;
-					if (data.length > 2 && data.indexOf("/") === 0 && data.lastIndexOf("/") === data.length - 1) {
-						q = data.slice(1, data.length - 1);
-					} else {
-						q = data.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
-					}
-					regexFilter[filter.name] = new RegExp(`${q}`, "i");
+			const newQueries = queries.map(query => {
+				const { data, filter, filterType } = query;
+				const newQuery = {};
+				if (filterType === "regex") {
+					newQuery[filter.property] = new RegExp(`${data.splice(1, data.length - 1)}`, "i");
+				} else if (filterType === "contains") {
+					newQuery[filter.property] = new RegExp(`${data.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i");
+				} else if (filterType === "exact") {
+					newQuery[filter.property] = data.toString();
 				}
+				return newQuery;
 			});
-			console.log(regexFilter);
 
 			async.waterfall(
 				[
 					next => {
-						SongsModule.SongModel.find({ ...regexFilter }).count((err, count) => {
+						SongsModule.SongModel.find({ $and: newQueries }).count((err, count) => {
 							next(err, count);
 						});
 					},
 
 					(count, next) => {
-						SongsModule.SongModel.find({ ...regexFilter })
+						SongsModule.SongModel.find({ $and: newQueries })
 							.sort(sort)
 							.skip(pageSize * (page - 1))
 							.limit(pageSize)

+ 55 - 15
frontend/src/components/AdvancedTable.vue

@@ -25,13 +25,33 @@
 						class="advanced-query"
 					>
 						<div class="control select">
-							<select v-model="query.filter">
+							<select
+								v-model="query.filter"
+								@change="changeQueryFilter(index)"
+							>
+								<option
+									v-for="filter in filters"
+									:key="filter.name"
+									:value="filter"
+								>
+									{{ filter.displayName }}
+								</option>
+							</select>
+						</div>
+						<div class="control select">
+							<select v-model="query.filterType">
 								<option
-									v-for="f in filters"
-									:key="f.name"
-									:value="f"
+									v-for="filterType in filterTypes(
+										query.filter
+									)"
+									:key="filterType.name"
+									:value="filterType.name"
+									:selected="
+										query.filter.defaultFilterType ===
+										filterType.name
+									"
 								>
-									{{ f.displayName }}
+									{{ filterType.displayName }}
 								</option>
 							</select>
 						</div>
@@ -42,7 +62,7 @@
 								type="text"
 								placeholder="Search value"
 								@keyup.enter="getData()"
-								:disabled="!query.filter.type"
+								:disabled="!query.filterType"
 							/>
 						</p>
 						<div class="control">
@@ -369,7 +389,6 @@ export default {
 			data: [],
 			count: 0, // TODO Rename
 			sort: {},
-			filter: {},
 			orderedColumns: [],
 			shownColumns: [],
 			columnDragOptions() {
@@ -383,7 +402,21 @@ export default {
 				};
 			},
 			advancedQuery: [],
-			resizing: {}
+			resizing: {},
+			allFilterTypes: {
+				contains: {
+					name: "contains",
+					displayName: "Contains"
+				},
+				exact: {
+					name: "exact",
+					displayName: "Exact"
+				},
+				regex: {
+					name: "regex",
+					displayName: "Regex"
+				}
+			}
 		};
 	},
 	computed: {
@@ -410,11 +443,6 @@ export default {
 		lastSelectedItemIndex() {
 			return this.data.findIndex(item => item.highlighted);
 		},
-		filterTypes() {
-			return this.filters
-				.map(filter => filter.type)
-				.filter((f, index, self) => self.indexOf(f) === index);
-		},
 		...mapGetters({
 			socket: "websockets/getSocket"
 		})
@@ -447,7 +475,8 @@ export default {
 		if (this.filters.length > 0)
 			this.advancedQuery.push({
 				data: "",
-				filter: {}
+				filter: {},
+				filterType: ""
 			});
 
 		ws.onConnect(this.init);
@@ -564,7 +593,8 @@ export default {
 			if (this.filters.length > 0)
 				this.advancedQuery.push({
 					data: "",
-					filter: {}
+					filter: {},
+					filterType: ""
 				});
 		},
 		removeQueryItem(index) {
@@ -617,6 +647,16 @@ export default {
 		columnResetWidth(column) {
 			// eslint-disable-next-line no-param-reassign
 			column.minWidth = column.maxWidth = "";
+		},
+		filterTypes(filter) {
+			if (!filter || !filter.filterTypes) return [];
+			return filter.filterTypes.map(
+				filterType => this.allFilterTypes[filterType]
+			);
+		},
+		changeQueryFilter(index) {
+			this.advancedQuery[index].filterType =
+				this.advancedQuery[index].filter.defaultFilterType;
 		}
 	}
 };

+ 23 - 9
frontend/src/pages/Admin/tabs/Test.vue

@@ -145,37 +145,51 @@ export default {
 				{
 					name: "_id",
 					displayName: "Musare ID",
-					type: "regex"
+					property: "_id",
+					filterTypes: ["exact"],
+					defaultFilterType: "exact"
 				},
 				{
 					name: "youtubeId",
 					displayName: "YouTube ID",
-					type: "regex"
+					property: "youtubeId",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				},
 				{
 					name: "title",
 					displayName: "Title",
-					type: "regex"
+					property: "title",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				},
 				{
 					name: "artists",
 					displayName: "Artists",
-					type: "regex"
+					property: "artists",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				},
 				{
 					name: "genres",
 					displayName: "Genres",
-					type: "regex"
+					property: "genres",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				},
 				{
-					name: "thumbnailUrl",
-					displayName: "Thumbnail (URL)",
-					type: "regex"
+					name: "thumbnail",
+					displayName: "Thumbnail",
+					property: "thumbnail",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				},
 				{
 					name: "requestedBy",
 					displayName: "Requested By",
-					type: "regex"
+					property: "requestedBy",
+					filterTypes: ["contains", "exact", "regex"],
+					defaultFilterType: "contains"
 				}
 			]
 		};