Client - add selects to sort users in administration
This commit is contained in:
parent
80afbe5968
commit
4a5f175053
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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
|
||||
|
@ -31,6 +31,23 @@
|
||||
"TABLE": {
|
||||
"ADD_ADMIN_RIGHTS": "Add admin rights",
|
||||
"REMOVE_ADMIN_RIGHTS": "Remove admin rights"
|
||||
},
|
||||
"SELECTS": {
|
||||
"ORDER_BY": {
|
||||
"LABEL": "order by",
|
||||
"admin": "admin status",
|
||||
"created_at": "registration date",
|
||||
"username": "username",
|
||||
"workouts_count": "workout count"
|
||||
},
|
||||
"ORDER": {
|
||||
"LABEL": "sort",
|
||||
"ASC": "ascending",
|
||||
"DESC": "descending"
|
||||
},
|
||||
"PER_PAGE": {
|
||||
"LABEL": "par page"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,23 @@
|
||||
"TABLE": {
|
||||
"ADD_ADMIN_RIGHTS": "Ajouter les drois d'admin",
|
||||
"REMOVE_ADMIN_RIGHTS": "Retirer les drois d'admin"
|
||||
},
|
||||
"SELECTS": {
|
||||
"ORDER_BY": {
|
||||
"LABEL": "trier par ",
|
||||
"admin": "status administrateur",
|
||||
"created_at": "date d'inscription",
|
||||
"username": "nom d'utilisateur",
|
||||
"workouts_count": "nombre de séances"
|
||||
},
|
||||
"ORDER": {
|
||||
"LABEL": "tri",
|
||||
"ASC": "ascendant",
|
||||
"DESC": "descendant"
|
||||
},
|
||||
"PER_PAGE": {
|
||||
"LABEL": "par page"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ import authApi from '@/api/authApi'
|
||||
import { ROOT_STORE, USERS_STORE } from '@/store/constants'
|
||||
import { IRootState } from '@/store/modules/root/types'
|
||||
import { IUsersActions, IUsersState } from '@/store/modules/users/types'
|
||||
import { IPaginationPayload } from '@/types/api'
|
||||
import { TPaginationPayload } from '@/types/api'
|
||||
import { IAdminUserPayload } from '@/types/user'
|
||||
import { handleError } from '@/utils'
|
||||
|
||||
export const actions: ActionTree<IUsersState, IRootState> & IUsersActions = {
|
||||
[USERS_STORE.ACTIONS.GET_USERS](
|
||||
context: ActionContext<IUsersState, IRootState>,
|
||||
payload: IPaginationPayload
|
||||
payload: TPaginationPayload
|
||||
): void {
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
context.commit(USERS_STORE.MUTATIONS.UPDATE_USERS_LOADING, true)
|
||||
@ -40,7 +40,6 @@ export const actions: ActionTree<IUsersState, IRootState> & IUsersActions = {
|
||||
context: ActionContext<IUsersState, IRootState>,
|
||||
payload: IAdminUserPayload
|
||||
): void {
|
||||
console.log('payload', payload)
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
authApi
|
||||
.patch(`users/${payload.username}`, { admin: payload.admin })
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
|
||||
import { USERS_STORE } from '@/store/constants'
|
||||
import { IRootState } from '@/store/modules/root/types'
|
||||
import { IPagination, IPaginationPayload } from '@/types/api'
|
||||
import { IPagination, TPaginationPayload } from '@/types/api'
|
||||
import { IAdminUserPayload, IUserProfile } from '@/types/user'
|
||||
|
||||
export interface IUsersState {
|
||||
@ -19,7 +19,7 @@ export interface IUsersState {
|
||||
export interface IUsersActions {
|
||||
[USERS_STORE.ACTIONS.GET_USERS](
|
||||
context: ActionContext<IUsersState, IRootState>,
|
||||
payload: IPaginationPayload
|
||||
payload: TPaginationPayload
|
||||
): void
|
||||
[USERS_STORE.ACTIONS.UPDATE_USER](
|
||||
context: ActionContext<IUsersState, IRootState>,
|
||||
|
@ -6,7 +6,8 @@ export interface IPagination {
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface IPaginationPayload {
|
||||
export type TPaginationPayload = {
|
||||
[key: string]: string | number
|
||||
order: string
|
||||
order_by: string
|
||||
per_page: number
|
||||
|
Loading…
Reference in New Issue
Block a user