Client - display pagination on workouts list

This commit is contained in:
Sam
2021-11-02 20:26:43 +01:00
parent e8350abf55
commit a8d0680457
16 changed files with 297 additions and 10 deletions

View File

@ -8,16 +8,22 @@
:event="pagination.has_prev ? 'click' : ''"
:disabled="!pagination.has_prev"
>
<i class="fa fa-chevron-left" aria-hidden="true" />
{{ $t('api.PAGINATION.PREVIOUS') }}
</router-link>
</li>
<li
v-for="page in rangePagination(pagination.pages)"
v-for="page in rangePagination(pagination.pages, pagination.page)"
:key="page"
class="page"
:class="{ active: page === pagination.page }"
>
<router-link class="page-link" :to="{ path, query: getQuery(page) }">
<span v-if="page === '...'"> ... </span>
<router-link
v-else
class="page-link"
:to="{ path, query: getQuery(+page) }"
>
{{ page }}
</router-link>
</li>
@ -29,6 +35,7 @@
:disabled="!pagination.has_next"
>
{{ $t('api.PAGINATION.NEXT') }}
<i class="fa fa-chevron-right" aria-hidden="true" />
</router-link>
</li>
</ul>
@ -39,6 +46,7 @@
import { PropType, defineComponent } from 'vue'
import { IPagination, TPaginationPayload } from '@/types/api'
import { rangePagination } from '@/utils/api'
export default defineComponent({
name: 'Pagination',
@ -57,9 +65,6 @@
},
},
setup(props) {
function rangePagination(pages: number): number[] {
return Array.from({ length: pages }, (_, i) => i + 1)
}
function getQuery(page: number, cursor?: number): TPaginationPayload {
const newQuery = Object.assign({}, props.query)
newQuery.page = cursor ? page + cursor : page
@ -115,6 +120,18 @@
border-bottom-right-radius: 5px;
margin-left: -1px;
}
.fa {
font-size: 0.8em;
padding: 0 $default-padding * 0.5;
}
}
@media screen and (max-width: $medium-limit) {
.pagination {
.page {
display: none;
}
}
}
}
</style>

View File

@ -143,7 +143,7 @@
sum += tooltipItem.parsed.y
})
return (
`${t('statistics.TOTAL')}: ` +
`${t('common.TOTAL')}: ` +
formatTooltipValue(props.displayedData, sum)
)
},

View File

@ -197,6 +197,9 @@
}
function onFilter() {
emit('filter')
if ('page' in params) {
params['page'] = '1'
}
router.push({ path: '/workouts', query: params })
}

View File

@ -1,6 +1,15 @@
<template>
<div class="workouts-list">
<div class="box" :class="{ 'empty-table': workouts.length === 0 }">
<div class="total">
<span class="total-label">
{{ $t('common.TOTAL').toLowerCase() }}:
</span>
<span v-if="pagination.total">
{{ pagination.total }}
{{ $t('workouts.WORKOUT', pagination.total) }}
</span>
</div>
<FilterSelects
:sort="sortList"
:order_by="orderByList"
@ -9,6 +18,12 @@
@updateSelect="reloadWorkouts"
/>
<div class="workouts-table responsive-table">
<Pagination
class="top-pagination"
:pagination="pagination"
path="/workouts"
:query="query"
/>
<table>
<thead>
<tr>
@ -96,6 +111,7 @@
</tr>
</tbody>
</table>
<Pagination :pagination="pagination" path="/workouts" :query="query" />
</div>
</div>
<NoWorkouts v-if="workouts.length === 0" />
@ -117,9 +133,11 @@
import { LocationQuery, useRoute, useRouter } from 'vue-router'
import FilterSelects from '@/components/Common/FilterSelects.vue'
import Pagination from '@/components/Common/Pagination.vue'
import StaticMap from '@/components/Common/StaticMap.vue'
import NoWorkouts from '@/components/Workouts/NoWorkouts.vue'
import { WORKOUTS_STORE } from '@/store/constants'
import { IPagination } from '@/types/api'
import { ITranslatedSport } from '@/types/sports'
import { IUserProfile } from '@/types/user'
import { IWorkout, TWorkoutsPayload } from '@/types/workouts'
@ -133,6 +151,7 @@
components: {
FilterSelects,
NoWorkouts,
Pagination,
StaticMap,
},
props: {
@ -158,6 +177,9 @@
const workouts: ComputedRef<IWorkout[]> = computed(
() => store.getters[WORKOUTS_STORE.GETTERS.USER_WORKOUTS]
)
const pagination: ComputedRef<IPagination> = computed(
() => store.getters[WORKOUTS_STORE.GETTERS.WORKOUTS_PAGINATION]
)
let query: TWorkoutsPayload = getWorkoutsQuery(route.query)
onBeforeMount(() => {
@ -205,6 +227,7 @@
return {
query,
orderByList,
pagination,
sortList,
workouts,
capitalize,
@ -225,11 +248,36 @@
width: 100%;
.box {
padding: $default-padding $default-padding * 2;
@media screen and (max-width: $small-limit) {
&.empty-table {
display: none;
}
}
.total {
display: flex;
gap: $default-padding * 0.5;
.total-label {
font-weight: bold;
}
}
.top-pagination {
display: none;
@media screen and (max-width: $small-limit) {
display: flex;
}
}
::v-deep(.pagination-center) {
@media screen and (max-width: $small-limit) {
ul {
margin-top: 0;
}
}
}
.workouts-table {
.sport-col {
padding-right: 0;