Client - add selects to sort users in administration

This commit is contained in:
Sam
2021-10-31 13:27:16 +01:00
parent 80afbe5968
commit 4a5f175053
9 changed files with 189 additions and 26 deletions

View File

@ -54,7 +54,7 @@
</td>
<td class="sport-action">
<span class="cell-heading">
{{ $t('admin.SPORTS.TABLE.ACTION') }}
{{ $t('admin.ACTION') }}
</span>
<div class="action-button">
<button

View File

@ -6,6 +6,12 @@
<button class="top-button" @click.prevent="$router.push('/admin')">
{{ $t('admin.BACK_TO_ADMIN') }}
</button>
<AdminUsersSelects
:sort="sort"
:order_by="order_by"
:query="query"
@updateSelect="reloadUsers"
/>
<div class="responsive-table">
<table>
<thead>
@ -101,35 +107,39 @@
ComputedRef,
computed,
defineComponent,
reactive,
watch,
capitalize,
onBeforeMount,
} from 'vue'
import { useRoute, LocationQuery } from 'vue-router'
import { LocationQuery, useRoute, useRouter } from 'vue-router'
import AdminUsersSelects from '@/components/Administration/AdminUsersSelects.vue'
import Pagination from '@/components/Common/Pagination.vue'
import { ROOT_STORE, USER_STORE, USERS_STORE } from '@/store/constants'
import { IPagination, IPaginationPayload } from '@/types/api'
import { IPagination, TPaginationPayload } from '@/types/api'
import { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'AdminUsers',
components: {
AdminUsersSelects,
Pagination,
},
setup() {
const store = useStore()
const route = useRoute()
const router = useRouter()
const orders: string[] = ['asc', 'desc']
const order_types: string[] = [
const sort: string[] = ['asc', 'desc']
const order_by: string[] = [
'admin',
'created_at',
'username',
'workouts_count',
]
let query: IPaginationPayload = getQuery(route.query)
let query: TPaginationPayload = reactive(getQuery(route.query))
const authUser: ComputedRef<IUserProfile> = computed(
() => store.getters[USER_STORE.GETTERS.AUTH_USER_PROFILE]
@ -144,7 +154,7 @@
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
)
function loadUsers(queryParams: IPaginationPayload) {
function loadUsers(queryParams: TPaginationPayload) {
store.dispatch(USERS_STORE.ACTIONS.GET_USERS, queryParams)
}
function getPage(page: string | (string | null)[] | null): number {
@ -156,18 +166,16 @@
: 10
}
function getOrder(order: string | (string | null)[] | null): string {
return order && typeof order === 'string' && orders.includes(order)
return order && typeof order === 'string' && sort.includes(order)
? order
: 'asc'
}
function getOrderBy(order_by: string | (string | null)[] | null): string {
return order_by &&
typeof order_by === 'string' &&
order_types.includes(order_by)
? order_by
function getOrderBy(order: string | (string | null)[] | null): string {
return order && typeof order === 'string' && order_by.includes(order)
? order
: 'created_at'
}
function getQuery(query: LocationQuery): IPaginationPayload {
function getQuery(query: LocationQuery): TPaginationPayload {
return {
page: getPage(query.page),
per_page: getPerPage(query.per_page),
@ -181,14 +189,24 @@
admin,
})
}
function reloadUsers(queryParam: string, queryValue: string) {
query[queryParam] = queryValue
if (queryParam === 'per_page') {
query.page = 1
}
router.push({ path: '/admin/users', query })
}
onBeforeMount(() => loadUsers(query))
watch(
() => route.query,
(newQuery) => {
query = getQuery(newQuery)
loadUsers(getQuery(newQuery))
(newQuery: LocationQuery) => {
query.page = getPage(newQuery.page)
query.per_page = getPerPage(newQuery.per_page)
query.order = getOrder(newQuery.order)
query.order_by = getOrderBy(newQuery.order_by)
loadUsers(query)
}
)
@ -196,9 +214,12 @@
authUser,
errorMessages,
pagination,
order_by,
query,
sort,
users,
capitalize,
reloadUsers,
updateUser,
}
},
@ -225,6 +246,9 @@
display: block;
margin-bottom: $default-margin * 2;
}
.pagination-center {
margin-top: -3 * $default-margin;
}
}
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<div class="table-selects">
<label>
{{ $t('admin.USERS.SELECTS.ORDER_BY.LABEL') }}:
<select
name="order_by"
id="order_by"
:value="query.order_by"
@change="onSelectUpdate"
>
<option v-for="order in order_by" :value="order" :key="order">
{{ $t(`admin.USERS.SELECTS.ORDER_BY.${order}`) }}
</option>
</select>
</label>
<label>
{{ $t('admin.USERS.SELECTS.ORDER.LABEL') }}:
<select
name="order"
id="order"
:value="query.order"
@change="onSelectUpdate"
>
<option v-for="order in sort" :value="order" :key="order">
{{ $t(`admin.USERS.SELECTS.ORDER.${order.toUpperCase()}`) }}
</option>
</select>
</label>
<label>
{{ $t('admin.USERS.SELECTS.PER_PAGE.LABEL') }}:
<select
name="per_page"
id="per_page"
:value="query.per_page"
@change="onSelectUpdate"
>
<option v-for="nb in per_page" :value="nb" :key="nb">
{{ nb }}
</option>
</select>
</label>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
import { TPaginationPayload } from '@/types/api'
export default defineComponent({
name: 'AdminUsersSelects',
props: {
order_by: {
type: Object as PropType<string[]>,
required: true,
},
query: {
type: Object as PropType<TPaginationPayload>,
required: true,
},
sort: {
type: Object as PropType<string[]>,
required: true,
},
},
emits: ['updateSelect'],
setup(props, { emit }) {
function onSelectUpdate(event: Event & { target: HTMLInputElement }) {
emit('updateSelect', event.target.id, event.target.value)
}
return {
per_page: [10, 50, 100],
onSelectUpdate,
}
},
})
</script>
<style lang="scss" scoped>
@import '~@/scss/base.scss';
.table-selects {
display: flex;
justify-content: space-between;
margin: $default-margin 0;
label {
select {
margin-left: $default-margin;
padding: $default-padding * 0.5;
}
}
@media screen and (max-width: $small-limit) {
flex-wrap: wrap;
label {
margin-bottom: $default-margin;
select {
margin-left: 0;
}
}
}
}
</style>

View File

@ -38,7 +38,7 @@
<script lang="ts">
import { PropType, defineComponent } from 'vue'
import { IPagination, IPaginationPayload } from '@/types/api'
import { IPagination, TPaginationPayload } from '@/types/api'
export default defineComponent({
name: 'Pagination',
@ -52,7 +52,7 @@
required: true,
},
query: {
type: Object as PropType<IPaginationPayload>,
type: Object as PropType<TPaginationPayload>,
required: true,
},
},
@ -60,7 +60,7 @@
function rangePagination(pages: number): number[] {
return Array.from({ length: pages }, (_, i) => i + 1)
}
function getQuery(page: number, cursor?: number): IPaginationPayload {
function getQuery(page: number, cursor?: number): TPaginationPayload {
const newQuery = Object.assign({}, props.query)
newQuery.page = cursor ? page + cursor : page
return newQuery