Reuse code
This commit is contained in:
parent
61b687275f
commit
accdffa88a
37
resources/assets/src/components/mixins/serverTable.ts
Normal file
37
resources/assets/src/components/mixins/serverTable.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
data: () => ({
|
||||||
|
columns: [] as Array<{ field: string }>,
|
||||||
|
totalRecords: 0,
|
||||||
|
serverParams: {
|
||||||
|
sortField: '',
|
||||||
|
sortType: 'asc',
|
||||||
|
page: 1,
|
||||||
|
perPage: 10,
|
||||||
|
search: '',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
methods: {
|
||||||
|
fetchData(): Promise<void> {
|
||||||
|
return Promise.resolve()
|
||||||
|
},
|
||||||
|
onPageChange(params: { currentPage: number }) {
|
||||||
|
this.serverParams.page = params.currentPage
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
onPerPageChange(params: { currentPerPage: number }) {
|
||||||
|
this.serverParams.perPage = params.currentPerPage
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
onSortChange(params: { sortType: 'asc' | 'desc', columnIndex: number }) {
|
||||||
|
this.serverParams.sortType = params.sortType
|
||||||
|
this.serverParams.sortField = this.columns[params.columnIndex].field
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
onSearch(params: { searchTerm: string }) {
|
||||||
|
this.serverParams.search = params.searchTerm
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
22
resources/assets/src/components/mixins/tableOptions.ts
Normal file
22
resources/assets/src/components/mixins/tableOptions.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tableOptions: {
|
||||||
|
search: {
|
||||||
|
enabled: true,
|
||||||
|
placeholder: this.$t('vendor.datatable.search'),
|
||||||
|
},
|
||||||
|
pagination: {
|
||||||
|
enabled: true,
|
||||||
|
nextLabel: this.$t('vendor.datatable.next'),
|
||||||
|
prevLabel: this.$t('vendor.datatable.prev'),
|
||||||
|
rowsPerPageLabel: this.$t('vendor.datatable.rowsPerPage'),
|
||||||
|
allLabel: this.$t('vendor.datatable.all'),
|
||||||
|
ofLabel: this.$t('vendor.datatable.of'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
@ -75,12 +75,16 @@ import { VueGoodTable } from 'vue-good-table'
|
||||||
import 'vue-good-table/dist/vue-good-table.min.css'
|
import 'vue-good-table/dist/vue-good-table.min.css'
|
||||||
import toastr from 'toastr'
|
import toastr from 'toastr'
|
||||||
import { swal } from '../../js/notify'
|
import { swal } from '../../js/notify'
|
||||||
|
import tableOptions from '../../components/mixins/tableOptions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Market',
|
name: 'Market',
|
||||||
components: {
|
components: {
|
||||||
VueGoodTable,
|
VueGoodTable,
|
||||||
},
|
},
|
||||||
|
mixins: [
|
||||||
|
tableOptions,
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
plugins: [],
|
plugins: [],
|
||||||
|
|
@ -112,20 +116,6 @@ export default {
|
||||||
globalSearchDisabled: true,
|
globalSearchDisabled: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
tableOptions: {
|
|
||||||
search: {
|
|
||||||
enabled: true,
|
|
||||||
placeholder: this.$t('vendor.datatable.search'),
|
|
||||||
},
|
|
||||||
pagination: {
|
|
||||||
enabled: true,
|
|
||||||
nextLabel: this.$t('vendor.datatable.next'),
|
|
||||||
prevLabel: this.$t('vendor.datatable.prev'),
|
|
||||||
rowsPerPageLabel: this.$t('vendor.datatable.rowsPerPage'),
|
|
||||||
allLabel: this.$t('vendor.datatable.all'),
|
|
||||||
ofLabel: this.$t('vendor.datatable.of'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
installing: '',
|
installing: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,18 @@ import { VueGoodTable } from 'vue-good-table'
|
||||||
import 'vue-good-table/dist/vue-good-table.min.css'
|
import 'vue-good-table/dist/vue-good-table.min.css'
|
||||||
import toastr from 'toastr'
|
import toastr from 'toastr'
|
||||||
import { swal } from '../../js/notify'
|
import { swal } from '../../js/notify'
|
||||||
|
import tableOptions from '../../components/mixins/tableOptions'
|
||||||
|
import serverTable from '../../components/mixins/serverTable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PlayersManagement',
|
name: 'PlayersManagement',
|
||||||
components: {
|
components: {
|
||||||
VueGoodTable,
|
VueGoodTable,
|
||||||
},
|
},
|
||||||
|
mixins: [
|
||||||
|
tableOptions,
|
||||||
|
serverTable,
|
||||||
|
],
|
||||||
props: {
|
props: {
|
||||||
baseUrl: {
|
baseUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
@ -135,7 +141,6 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
players: [],
|
players: [],
|
||||||
totalRecords: 0,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'pid', label: 'PID', type: 'number',
|
field: 'pid', label: 'PID', type: 'number',
|
||||||
|
|
@ -154,24 +159,6 @@ export default {
|
||||||
],
|
],
|
||||||
serverParams: {
|
serverParams: {
|
||||||
sortField: 'pid',
|
sortField: 'pid',
|
||||||
sortType: 'asc',
|
|
||||||
page: 1,
|
|
||||||
perPage: 10,
|
|
||||||
search: '',
|
|
||||||
},
|
|
||||||
tableOptions: {
|
|
||||||
search: {
|
|
||||||
enabled: true,
|
|
||||||
placeholder: this.$t('vendor.datatable.search'),
|
|
||||||
},
|
|
||||||
pagination: {
|
|
||||||
enabled: true,
|
|
||||||
nextLabel: this.$t('vendor.datatable.next'),
|
|
||||||
prevLabel: this.$t('vendor.datatable.prev'),
|
|
||||||
rowsPerPageLabel: this.$t('vendor.datatable.rowsPerPage'),
|
|
||||||
allLabel: this.$t('vendor.datatable.all'),
|
|
||||||
ofLabel: this.$t('vendor.datatable.of'),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
textureChanges: {
|
textureChanges: {
|
||||||
originalIndex: -1,
|
originalIndex: -1,
|
||||||
|
|
@ -192,23 +179,6 @@ export default {
|
||||||
this.totalRecords = totalRecords
|
this.totalRecords = totalRecords
|
||||||
this.players = data
|
this.players = data
|
||||||
},
|
},
|
||||||
onPageChange(params) {
|
|
||||||
this.serverParams.page = params.currentPage
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPerPageChange(params) {
|
|
||||||
this.serverParams.perPage = params.currentPerPage
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSortChange(params) {
|
|
||||||
this.serverParams.sortType = params.sortType
|
|
||||||
this.serverParams.sortField = this.columns[params.columnIndex].field
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSearch(params) {
|
|
||||||
this.serverParams.search = params.searchTerm
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
async changeTexture() {
|
async changeTexture() {
|
||||||
const player = this.players[this.textureChanges.originalIndex]
|
const player = this.players[this.textureChanges.originalIndex]
|
||||||
const { type, tid } = this.textureChanges
|
const { type, tid } = this.textureChanges
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,16 @@ import { VueGoodTable } from 'vue-good-table'
|
||||||
import 'vue-good-table/dist/vue-good-table.min.css'
|
import 'vue-good-table/dist/vue-good-table.min.css'
|
||||||
import toastr from 'toastr'
|
import toastr from 'toastr'
|
||||||
import { swal } from '../../js/notify'
|
import { swal } from '../../js/notify'
|
||||||
|
import tableOptions from '../../components/mixins/tableOptions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Plugins',
|
name: 'Plugins',
|
||||||
components: {
|
components: {
|
||||||
VueGoodTable,
|
VueGoodTable,
|
||||||
},
|
},
|
||||||
|
mixins: [
|
||||||
|
tableOptions,
|
||||||
|
],
|
||||||
props: {
|
props: {
|
||||||
baseUrl: {
|
baseUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
@ -111,20 +115,6 @@ export default {
|
||||||
globalSearchDisabled: true,
|
globalSearchDisabled: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
tableOptions: {
|
|
||||||
search: {
|
|
||||||
enabled: true,
|
|
||||||
placeholder: this.$t('vendor.datatable.search'),
|
|
||||||
},
|
|
||||||
pagination: {
|
|
||||||
enabled: true,
|
|
||||||
nextLabel: this.$t('vendor.datatable.next'),
|
|
||||||
prevLabel: this.$t('vendor.datatable.prev'),
|
|
||||||
rowsPerPageLabel: this.$t('vendor.datatable.rowsPerPage'),
|
|
||||||
allLabel: this.$t('vendor.datatable.all'),
|
|
||||||
ofLabel: this.$t('vendor.datatable.of'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ import 'vue-good-table/dist/vue-good-table.min.css'
|
||||||
import toastr from 'toastr'
|
import toastr from 'toastr'
|
||||||
import { trans } from '../../js/i18n'
|
import { trans } from '../../js/i18n'
|
||||||
import { swal } from '../../js/notify'
|
import { swal } from '../../js/notify'
|
||||||
|
import tableOptions from '../../components/mixins/tableOptions'
|
||||||
|
import serverTable from '../../components/mixins/serverTable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UsersManagement',
|
name: 'UsersManagement',
|
||||||
|
|
@ -116,10 +118,13 @@ export default {
|
||||||
return `${blessing.base_url}/admin/players?uid=${user.uid}`
|
return `${blessing.base_url}/admin/players?uid=${user.uid}`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mixins: [
|
||||||
|
tableOptions,
|
||||||
|
serverTable,
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
users: [],
|
users: [],
|
||||||
totalRecords: 0,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'uid', label: 'UID', type: 'number',
|
field: 'uid', label: 'UID', type: 'number',
|
||||||
|
|
@ -147,24 +152,6 @@ export default {
|
||||||
],
|
],
|
||||||
serverParams: {
|
serverParams: {
|
||||||
sortField: 'uid',
|
sortField: 'uid',
|
||||||
sortType: 'asc',
|
|
||||||
page: 1,
|
|
||||||
perPage: 10,
|
|
||||||
search: '',
|
|
||||||
},
|
|
||||||
tableOptions: {
|
|
||||||
search: {
|
|
||||||
enabled: true,
|
|
||||||
placeholder: this.$t('vendor.datatable.search'),
|
|
||||||
},
|
|
||||||
pagination: {
|
|
||||||
enabled: true,
|
|
||||||
nextLabel: this.$t('vendor.datatable.next'),
|
|
||||||
prevLabel: this.$t('vendor.datatable.prev'),
|
|
||||||
rowsPerPageLabel: this.$t('vendor.datatable.rowsPerPage'),
|
|
||||||
allLabel: this.$t('vendor.datatable.all'),
|
|
||||||
ofLabel: this.$t('vendor.datatable.of'),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -180,23 +167,6 @@ export default {
|
||||||
this.totalRecords = totalRecords
|
this.totalRecords = totalRecords
|
||||||
this.users = data
|
this.users = data
|
||||||
},
|
},
|
||||||
onPageChange(params) {
|
|
||||||
this.serverParams.page = params.currentPage
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onPerPageChange(params) {
|
|
||||||
this.serverParams.perPage = params.currentPerPage
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSortChange(params) {
|
|
||||||
this.serverParams.sortType = params.sortType
|
|
||||||
this.serverParams.sortField = this.columns[params.columnIndex].field
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
onSearch(params) {
|
|
||||||
this.serverParams.search = params.searchTerm
|
|
||||||
this.fetchData()
|
|
||||||
},
|
|
||||||
async changeEmail(user) {
|
async changeEmail(user) {
|
||||||
const { dismiss, value } = await swal({
|
const { dismiss, value } = await swal({
|
||||||
text: this.$t('admin.newUserEmail'),
|
text: this.$t('admin.newUserEmail'),
|
||||||
|
|
|
||||||
42
resources/assets/tests/components/mixins/serverTable.test.ts
Normal file
42
resources/assets/tests/components/mixins/serverTable.test.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import serverTable from '@/components/mixins/serverTable'
|
||||||
|
|
||||||
|
test('change current page', () => {
|
||||||
|
const wrapper = mount(serverTable)
|
||||||
|
jest.spyOn(wrapper.vm, 'fetchData')
|
||||||
|
wrapper.vm.onPageChange({ currentPage: 2 })
|
||||||
|
expect(wrapper.vm.fetchData).toBeCalled()
|
||||||
|
expect(wrapper.vm.serverParams.page).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('change per page', () => {
|
||||||
|
const wrapper = mount(serverTable)
|
||||||
|
jest.spyOn(wrapper.vm, 'fetchData')
|
||||||
|
wrapper.vm.onPerPageChange({ currentPerPage: 2 })
|
||||||
|
expect(wrapper.vm.fetchData).toBeCalled()
|
||||||
|
expect(wrapper.vm.serverParams.perPage).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('change sort type', () => {
|
||||||
|
const wrapper = mount(serverTable)
|
||||||
|
jest.spyOn(wrapper.vm, 'fetchData')
|
||||||
|
wrapper.setData({
|
||||||
|
columns: [
|
||||||
|
{ field: '0' },
|
||||||
|
{ field: '1' },
|
||||||
|
{ field: '2' },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
wrapper.vm.onSortChange({ sortType: 'desc', columnIndex: 2 })
|
||||||
|
expect(wrapper.vm.fetchData).toBeCalled()
|
||||||
|
expect(wrapper.vm.serverParams.sortType).toBe('desc')
|
||||||
|
expect(wrapper.vm.serverParams.sortField).toBe('2')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('search', () => {
|
||||||
|
const wrapper = mount(serverTable)
|
||||||
|
jest.spyOn(wrapper.vm, 'fetchData')
|
||||||
|
wrapper.vm.onSearch({ searchTerm: 'q' })
|
||||||
|
expect(wrapper.vm.fetchData).toBeCalled()
|
||||||
|
expect(wrapper.vm.serverParams.search).toBe('q')
|
||||||
|
})
|
||||||
|
|
@ -17,48 +17,6 @@ test('fetch data after initializing', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('update tables', () => {
|
|
||||||
interface Methods {
|
|
||||||
onPageChange(options: { currentPage: number }): void
|
|
||||||
onPerPageChange(options: { currentPerPage: number }): void
|
|
||||||
onSortChange(options: { sortType: 'asc' | 'desc', columnIndex: number }): void
|
|
||||||
}
|
|
||||||
|
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
|
||||||
data: Array.from({ length: 20 }).map((_, pid) => ({ pid })),
|
|
||||||
})
|
|
||||||
const wrapper = mount<Vue & Methods>(Players)
|
|
||||||
|
|
||||||
wrapper.find('.vgt-input').setValue('abc')
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/player-data',
|
|
||||||
{
|
|
||||||
page: 1, perPage: 10, search: 'abc', sortField: 'pid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onPageChange({ currentPage: 2 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/player-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 10, search: 'abc', sortField: 'pid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onPerPageChange({ currentPerPage: 5 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/player-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 5, search: 'abc', sortField: 'pid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onSortChange({ sortType: 'desc', columnIndex: 0 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/player-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 5, search: 'abc', sortField: 'pid', sortType: 'desc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('change texture', async () => {
|
test('change texture', async () => {
|
||||||
window.$ = jest.fn(() => ({ modal() {} }))
|
window.$ = jest.fn(() => ({ modal() {} }))
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
Vue.prototype.$http.get.mockResolvedValue({
|
||||||
|
|
|
||||||
|
|
@ -22,48 +22,6 @@ test('fetch data after initializing', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('update tables', () => {
|
|
||||||
interface Methods {
|
|
||||||
onPageChange(options: { currentPage: number }): void
|
|
||||||
onPerPageChange(options: { currentPerPage: number }): void
|
|
||||||
onSortChange(options: { sortType: 'asc' | 'desc', columnIndex: number }): void
|
|
||||||
}
|
|
||||||
|
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
|
||||||
data: Array.from({ length: 20 }).map((_, uid) => ({ uid })),
|
|
||||||
})
|
|
||||||
const wrapper = mount<Vue & Methods>(Users)
|
|
||||||
|
|
||||||
wrapper.find('.vgt-input').setValue('abc')
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/user-data',
|
|
||||||
{
|
|
||||||
page: 1, perPage: 10, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onPageChange({ currentPage: 2 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/user-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 10, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onPerPageChange({ currentPerPage: 5 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/user-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 5, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
wrapper.vm.onSortChange({ sortType: 'desc', columnIndex: 0 })
|
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
||||||
'/admin/user-data',
|
|
||||||
{
|
|
||||||
page: 2, perPage: 5, search: 'abc', sortField: 'uid', sortType: 'desc',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('humanize permission', async () => {
|
test('humanize permission', async () => {
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
Vue.prototype.$http.get.mockResolvedValue({
|
||||||
data: [
|
data: [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user