4
0
mirror of https://github.com/AzuraCast/AzuraCast.git synced 2024-06-26 19:07:05 +00:00
AzuraCast/web/static/vue/components/DataTable.vue

220 lines
6.7 KiB
Vue
Raw Normal View History

2019-10-06 05:49:22 +00:00
<template>
2019-10-06 09:16:25 +00:00
<div>
2019-10-07 03:14:54 +00:00
<div class="d-flex align-items-center mb-2" v-if="showToolbar">
<div class="flex-fill">
<b-pagination v-model="currentPage" :total-rows="totalRows" :per-page="perPage"
2019-10-07 03:14:54 +00:00
class="mb-0" v-if="showPagination">
</b-pagination>
2019-10-07 03:14:54 +00:00
</div>
<div class="flex-shrink-1 pl-3">
<div class="input-group">
<span class="icon glyphicon input-group-addon search"></span>
<input type="text" v-model="filter" class="search-field form-control" placeholder="Search">
2019-10-06 05:49:22 +00:00
</div>
2019-10-07 03:14:54 +00:00
</div>
<div class="flex-shrink-1 pl-3 pr-3">
2019-10-06 09:16:25 +00:00
<div class="actions btn-group">
<button class="btn btn-default" type="button" title="Refresh"
@click.stop.prevent="onClickRefresh">
2019-10-06 09:16:25 +00:00
<i class="material-icons">refresh</i>
2019-10-06 05:49:22 +00:00
</button>
<div class="dropdown btn-group" v-if="paginated">
2019-10-06 09:16:25 +00:00
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
<span class="dropdown-text">{{ perPageLabel }}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li v-for="pageOption in pageOptions" :class="{ active: (pageOption === perPage) }">
<a href="#" @click.prevent="setPerPage(pageOption)"
class="dropdown-item dropdown-item-button">
{{ getPerPageLabel(pageOption) }}
</a>
</li>
</ul>
</div>
2019-10-06 05:49:22 +00:00
</div>
2019-10-07 03:14:54 +00:00
</div>
</div>
2019-10-06 05:49:22 +00:00
<b-table ref="table" show-empty striped hover :selectable="selectable" :api-url="apiUrl" :per-page="perPage"
2019-10-06 09:16:25 +00:00
:current-page="currentPage" @row-selected="onRowSelected" :items="loadItems" :fields="fields"
tbody-tr-class="align-middle" selected-variant=""
:filter="filter" :filter-debounce="200" @filtered="onFiltered">
2019-10-06 09:16:25 +00:00
<template v-slot:cell(selected)="{ rowSelected }">
<div class="custom-control custom-checkbox pl-0">
<input type="checkbox" class="custom-control-input position-static" :checked="rowSelected">
<label class="custom-control-label"></label>
</div>
2019-10-06 05:49:22 +00:00
</template>
2019-10-06 09:16:25 +00:00
<slot v-for="(_, name) in $slots" :name="name" :slot="name"/>
<template v-for="(_, name) in $scopedSlots" :slot="name" slot-scope="slotData">
<slot :name="name" v-bind="slotData"/>
2019-10-06 05:49:22 +00:00
</template>
2019-10-06 09:16:25 +00:00
</b-table>
2019-10-06 05:49:22 +00:00
<b-pagination v-model="currentPage" :total-rows="totalRows" :per-page="perPage"
2019-10-07 03:14:54 +00:00
class="mb-0 mt-2" v-if="showPagination">
</b-pagination>
2019-10-06 09:16:25 +00:00
</div>
2019-10-06 05:49:22 +00:00
</template>
<style lang="scss">
table.b-table-selectable {
tr > td:nth-child(1) {
padding-right: 0.75rem;
}
tr > td:nth-child(2) {
padding-left: 0.5rem;
}
}
</style>
2019-10-06 05:49:22 +00:00
<script>
import axios from 'axios'
import store from 'store'
2019-10-06 09:16:25 +00:00
// import Vue from 'vue'
// import { LayoutPlugin, PaginationPlugin, TablePlugin } from 'bootstrap-vue'
2019-10-06 05:49:22 +00:00
2019-10-06 09:16:25 +00:00
/*
2019-10-06 05:49:22 +00:00
Vue.use(LayoutPlugin)
Vue.use(TablePlugin)
Vue.use(PaginationPlugin)
2019-10-06 09:16:25 +00:00
*/
2019-10-06 05:49:22 +00:00
export default {
name: 'DataTable',
props: {
id: String,
apiUrl: String,
paginated: {
type: Boolean,
default: false
},
showToolbar: {
type: Boolean,
default: true
},
defaultPerPage: {
type: Number,
default: 10
},
2019-10-06 05:49:22 +00:00
fields: Array,
selectable: {
type: Boolean,
default: false
},
2019-10-06 05:49:22 +00:00
requestConfig: Function,
requestProcess: Function
},
data () {
return {
selected: [],
storeKey: 'datatable_' + this.id + '_perpage',
2019-10-06 05:49:22 +00:00
filter: null,
perPage: (this.paginated) ? this.defaultPerPage : 0,
2019-10-07 03:14:54 +00:00
pageOptions: [10, 25, 50, 0],
2019-10-06 05:49:22 +00:00
currentPage: 1,
totalRows: 0,
flushCache: false
}
},
mounted () {
if (store.enabled && store.get(this.storeKey) !== undefined) {
this.perPage = store.get(this.storeKey)
}
},
watch: {
perPage (newPerPage, oldPerPage) {
store.set(this.storeKey, newPerPage)
2019-10-06 05:49:22 +00:00
}
},
computed: {
2019-10-07 03:14:54 +00:00
showPagination () {
return this.paginated && this.perPage !== 0
},
2019-10-06 05:49:22 +00:00
perPageLabel () {
return this.getPerPageLabel(this.perPage)
}
},
methods: {
getPerPageLabel (num) {
2019-10-07 03:14:54 +00:00
return (num === 0) ? 'All' : num
2019-10-06 05:49:22 +00:00
},
setPerPage (num) {
this.perPage = num
},
onClickRefresh (e) {
if (e.shiftKey) {
this.list()
} else {
this.refresh()
}
},
2019-10-06 05:49:22 +00:00
refresh () {
this.$refs.table.refresh()
},
list () {
this.filter = null
this.currentPage = 1
this.flushCache = true
this.refresh()
},
setFilter (newTerm) {
2019-10-06 05:49:22 +00:00
this.filter = newTerm
},
loadItems (ctx, callback) {
let queryParams = {}
if (this.paginated) {
queryParams.rowCount = ctx.perPage
queryParams.current = ctx.currentPage
2019-10-06 05:49:22 +00:00
}
if (this.flushCache) {
queryParams.flushCache = true
}
if (typeof ctx.filter === 'string') {
queryParams.searchPhrase = ctx.filter
2019-10-06 05:49:22 +00:00
}
if ('' !== ctx.sortBy) {
2019-10-07 03:14:54 +00:00
queryParams.sort = ctx.sortBy
queryParams.sortOrder = (ctx.sortDesc) ? 'DESC' : 'ASC'
2019-10-06 05:49:22 +00:00
}
let requestConfig = { params: queryParams }
if (typeof this.requestConfig === 'function') {
requestConfig = this.requestConfig(requestConfig)
}
axios.get(ctx.apiUrl, requestConfig).then((resp) => {
this.flushCache = false
this.totalRows = resp.data.total
let rows = resp.data.rows
if (typeof this.requestProcess === 'function') {
rows = this.requestProcess(rows)
}
callback(rows)
}).catch((err) => {
this.flushCache = false
this.totalRows = 0
console.error(err.data.message)
callback([])
})
},
onRowSelected (items) {
this.selected = items
this.$emit('row-selected', items)
},
onFiltered (filter) {
this.$emit('filtered', filter)
2019-10-06 05:49:22 +00:00
}
}
}
</script>