131 lines
3.4 KiB
Vue
131 lines
3.4 KiB
Vue
<template>
|
|
<div class="d-flex flex-row">
|
|
<v-text-field
|
|
class="filter flex-1-0"
|
|
placeholder="Filter by Name"
|
|
v-model="filtervalue"
|
|
></v-text-field>
|
|
</div>
|
|
<v-data-table-server
|
|
:headers="headers"
|
|
v-model:items-per-page="resultsPerPage"
|
|
:items="games"
|
|
:items-length="count"
|
|
v-model:page="page"
|
|
@update:options="loadData"
|
|
>
|
|
<template v-slot:item.id="{ item }">
|
|
<a v-bind:href="`/#/games/${item.id}`">{{ item.id }}</a>
|
|
</template>
|
|
<template v-slot:item.title="{ item }">
|
|
<a v-bind:href="`/#/games/${item.id}`">{{ item.title }}</a>
|
|
</template>
|
|
<template v-slot:item.postdate="{ item }">
|
|
{{ new Date(item.postdate * 1000).toISOString().split('T')[0] }}
|
|
</template>
|
|
|
|
<template #bottom></template>
|
|
</v-data-table-server>
|
|
<v-pagination
|
|
:model-value="page"
|
|
:length="pageCount"
|
|
@update:modelValue="setPage($event)"
|
|
></v-pagination>
|
|
</template>
|
|
|
|
<style>
|
|
.filter {
|
|
margin-top: 10px;
|
|
margin-left: 5px;
|
|
margin-right: 5px;
|
|
margin-bottom: 0px;
|
|
}
|
|
</style>
|
|
|
|
<script setup lang="ts">
|
|
import { Game } from '../types'
|
|
import GameTable from './GameTable.vue'
|
|
import { onMounted, watch, ref } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import axios from 'axios'
|
|
import { VDataTable } from 'vuetify/components'
|
|
|
|
type ReadonlyHeaders = VDataTable['$props']['headers']
|
|
|
|
const headers: ReadonlyHeaders = [
|
|
{ title: 'ID', align: 'start', sortable: true, key: 'id' },
|
|
{ title: 'Title', align: 'start', sortable: true, key: 'title' },
|
|
{ title: 'Status', align: 'start', sortable: true, key: 'status' },
|
|
{ title: 'Post Date', align: 'start', sortable: true, key: 'postdate' }
|
|
]
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const games = ref<Game[]>([])
|
|
const pageCount = ref(1)
|
|
let page = ref(1)
|
|
const resultsPerPage = ref(10)
|
|
|
|
let count = ref(10)
|
|
|
|
const filtervalue = ref<string>('')
|
|
|
|
async function loadData({ page, itemsPerPage, sortBy }: any) {
|
|
let sortString = 'id'
|
|
if (sortBy[0]) {
|
|
sortString = `${sortBy[0].key} ${sortBy[0].order}`
|
|
}
|
|
|
|
const response = await axios.post('/api/game', {
|
|
page: `${page - 1}`,
|
|
count: `${itemsPerPage}`,
|
|
orderBy: sortString,
|
|
filter: filtervalue.value ? `title:"${filtervalue.value}"` : ''
|
|
})
|
|
|
|
games.value = response.data.gameData
|
|
pageCount.value = response.data.pageCount
|
|
count.value = response.data.totalCount
|
|
}
|
|
|
|
function setPage(targetPage: number) {
|
|
router.replace({ query: { page: targetPage, filter: route.query.filter } })
|
|
}
|
|
|
|
watch(route, (newValue, oldValue) => {
|
|
if (!route.query.page) {
|
|
router.replace({ query: { page: 1, filter: route.query.filter } })
|
|
page.value = 1
|
|
} else {
|
|
page.value = Number(route.query.page)
|
|
}
|
|
|
|
if (route.query.filter) {
|
|
filtervalue.value = route.query.filter.toString()
|
|
}
|
|
loadData({ page: page.value, itemsPerPage: resultsPerPage.value, sortBy: [] })
|
|
})
|
|
|
|
let debounce: ReturnType<typeof setTimeout>
|
|
watch(filtervalue, (newFilter: string, oldFilter: string) => {
|
|
clearTimeout(debounce)
|
|
debounce = setTimeout(() => {
|
|
router.replace({ query: { page: route.query.page, filter: newFilter } })
|
|
}, 500)
|
|
loadData({ page: page.value, itemsPerPage: resultsPerPage.value, sortBy: [] })
|
|
})
|
|
|
|
onMounted(async () => {
|
|
if (!route.query.page) {
|
|
router.replace({ query: { page: 1 } })
|
|
page.value = 1
|
|
} else {
|
|
page.value = Number(route.query.page)
|
|
}
|
|
if (route.query.filter) {
|
|
filtervalue.value = route.query.filter.toString()
|
|
}
|
|
})
|
|
</script>
|