Просмотр исходного кода

SelectFilter update to allow no-select all and simplify API, update SQL, hook up to backend

sbkwgh 7 лет назад
Родитель
Сommit
8f89fd5215

+ 18 - 45
frontend/src/components/SelectFilter.vue

@@ -11,34 +11,26 @@
 		</button>
 
 		<template slot='menu'>
-			<fancy-input
-				class='select_filter__search'
-
-				v-if='searchPlaceholder'
-				:placeholder='searchPlaceholder'
-				width='100%'
-				v-model='search'
-			></fancy-input>
-
 			<div
 				class='select_filter__item select_filter__item--select_all'
+				v-if='selectAll'
 				@click='toggleSelectAll'
 			>
 				<div
 					class='select_filter__checkbox'
-					:class='{ "select_filter__checkbox--selected": selected.length === options.length }'
+					:class='{ "select_filter__checkbox--selected": value.length === options.length }'
 				></div>
 				<span>Select all</span>
 			</div>
 
 			<div
 				class='select_filter__item'
-				v-for='(item, $index) in options'
-				@click='toggledSelectItem($index)'
+				v-for='item in options'
+				@click='toggledSelectItem(item.value)'
 			>
 				<div
 					class='select_filter__checkbox'
-					:class='{ "select_filter__checkbox--selected": selected.includes($index) }'
+					:class='{ "select_filter__checkbox--selected": value.includes(item.value) }'
 				></div>
 				<span>{{item.name}}</span>
 			</div>
@@ -52,51 +44,32 @@
 
 	export default {
 		name: 'SelectFilter',
-		props: ['name', 'options', 'value', 'search-placeholder'],
-		components: {
-			FancyInput,
-			MenuTooltip
-		},
+		props: ['name', 'options', 'value', 'selectAll'],
+		components: { MenuTooltip },
 		data () {
 			return {
-				menuOpen: false,
-				search: '',
-				selected: []
+				menuOpen: false
 			}
 		},
 		methods: {
 			toggleSelectAll () {
 				//If everything is selected
-				if(this.selected.length === this.options.length) {
-					this.selected = [];
+				if(this.value.length === this.options.length) {
+					this.$emit('input', []);
 				} else {
-					this.selected = this.options.map((_, i) => i);
+					this.$emit('input', this.options.map(i => i.value));
 				}
 			},
-			toggledSelectItem (itemIndex) {
-				let selectedArrIndex = this.selected.indexOf(itemIndex);
-
-				if(selectedArrIndex === -1) {
-					this.selected.push(itemIndex);
+			toggledSelectItem (item) {
+				if(this.value.includes(item)) {
+					//If no select all, then do not allow to unselect all items
+					if(this.selectAll || (!this.selectAll && this.value.length > 1)) {
+						this.$emit('input', this.value.filter(i => i !== item));
+					}
 				} else {
-					this.selected.splice(selectedArrIndex, 1);
+					this.$emit('input', [...this.value, item]);
 				}
 			}
-		},
-		watch: {
-			selected () {
-				let selectedItems = this.options.filter((item, index) => {
-					return this.selected.includes(index);
-				});
-
-				this.$emit('value', selectedItems);
-			},
-			search () {
-				this.$emit('search', this.search);
-			}
-		},
-		mounted () {
-			this.toggleSelectAll();
 		}
 	}
 </script>

+ 23 - 23
frontend/src/components/routes/AdminUsers.vue

@@ -4,13 +4,6 @@
 		<div class='category_widget__box'>
 			<div class='category_widget__text__title'>Filter users</div>
 			<div class='admin_users__filters'>
-				<select-filter
-					name='Username'
-					:options='usernameOptions'
-					v-model='usernameSelected'
-					search-placeholder='Filter users'
-				>
-				</select-filter>
 				<select-filter
 					name='Role'
 					:options='roleOptions'
@@ -32,10 +25,10 @@
 						<sort-menu v-model='tableSort' column='createdAt' display='Account created at'></sort-menu>
 					</th>
 					<th>
-						<sort-menu v-model='tableSort' column='posts' display='Posts count'></sort-menu>
+						<sort-menu v-model='tableSort' column='postCount' display='Posts count'></sort-menu>
 					</th>
 					<th>
-						<sort-menu v-model='tableSort' column='threads' display='Threads count'></sort-menu>
+						<sort-menu v-model='tableSort' column='threadCount' display='Threads count'></sort-menu>
 					</th>
 				</tr>
 				<tr v-for='user in users'>
@@ -73,14 +66,7 @@
 					{ name: 'Admins', value: 'admin' },
 					{ name: 'Users', value: 'user' }
 				],
-				roleSelected: null,
-
-				usernameOptions: [
-					{ name: 'User1', value: 'admin' },
-					{ name: 'User1', value: 'admin' },
-					{ name: 'User1', value: 'admin' },
-				],
-				usernameSelected: null,
+				roleSelected: ['admin', 'user'],
 
 				tableSort: {
 					column: 'username',
@@ -88,13 +74,27 @@
 				}
 			}
 		},
+		methods: {
+			fetchData () {
+				let url = `/api/v1/user?sort=${this.tableSort.column}&order=${this.tableSort.sort}`;
+				if(this.roleSelected.length === 1) {
+					url += '&role=' + this.roleSelected[0];
+				}
+
+				this.axios
+					.get(url)
+					.then(res => {
+						this.users = res.data;
+					})
+					.catch(AjaxErrorHandler(this.$store))
+			}
+		},
 		mounted () {
-			this.axios
-				.get('/api/v1/user')
-				.then(res => {
-					this.users = res.data;
-				})
-				.catch(AjaxErrorHandler(this.$store))
+			this.fetchData();
+		},
+		watch: {
+			tableSort: 'fetchData',
+			roleSelected: 'fetchData'
 		}
 	}
 </script>

+ 7 - 6
routes/user.js

@@ -295,9 +295,10 @@ router.all('*', (req, res, next) => {
 router.get('/', async (req, res, next) => {
 	try {
 		let sortFields = {
-			id: 'id',
-			username: 'username',
-			date: 'createdAt'
+			createdAt: 'X.id',
+			username: 'X.username',
+			threadCount: 'threadCount',
+			postCount: 'postCount'
 		};
 		let offset = Number.isInteger(+req.query.offset) ? +req.query.offset : 0;
 		let havingClause;
@@ -318,13 +319,13 @@ router.get('/', async (req, res, next) => {
 				ON Users.id = Posts.UserId
 				GROUP BY Users.id
 				${havingClause}
-				ORDER BY Users.${sortFields[req.query.sort] || 'id'} ${req.query.order === 'asc' ? 'ASC' : 'DESC'}
-				LIMIT 30
-				OFFSET ${offset}
 			) as X
 			LEFT OUTER JOIN threads
 			ON X.id = Threads.UserId
 			GROUP BY X.id
+			ORDER BY ${sortFields[req.query.sort] || 'X.id'} ${req.query.order === 'asc' ? 'ASC' : 'DESC'}
+			LIMIT 30
+			OFFSET ${offset}
 		`;
 
 		let users = await sequelize.query(sql, {