From accdffa88a5ccedfbfa45c0663a157d33b6767e2 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Wed, 20 Mar 2019 09:38:16 +0800 Subject: [PATCH] Reuse code --- .../src/components/mixins/serverTable.ts | 37 ++++++++++++++++ .../src/components/mixins/tableOptions.ts | 22 ++++++++++ resources/assets/src/views/admin/Market.vue | 18 ++------ resources/assets/src/views/admin/Players.vue | 42 +++---------------- resources/assets/src/views/admin/Plugins.vue | 18 ++------ resources/assets/src/views/admin/Users.vue | 42 +++---------------- .../components/mixins/serverTable.test.ts | 42 +++++++++++++++++++ .../assets/tests/views/admin/Players.test.ts | 42 ------------------- .../assets/tests/views/admin/Users.test.ts | 42 ------------------- 9 files changed, 121 insertions(+), 184 deletions(-) create mode 100644 resources/assets/src/components/mixins/serverTable.ts create mode 100644 resources/assets/src/components/mixins/tableOptions.ts create mode 100644 resources/assets/tests/components/mixins/serverTable.test.ts diff --git a/resources/assets/src/components/mixins/serverTable.ts b/resources/assets/src/components/mixins/serverTable.ts new file mode 100644 index 00000000..5eef79b2 --- /dev/null +++ b/resources/assets/src/components/mixins/serverTable.ts @@ -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 { + 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() + }, + }, +}) diff --git a/resources/assets/src/components/mixins/tableOptions.ts b/resources/assets/src/components/mixins/tableOptions.ts new file mode 100644 index 00000000..2e20da00 --- /dev/null +++ b/resources/assets/src/components/mixins/tableOptions.ts @@ -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'), + }, + }, + } + }, +}) diff --git a/resources/assets/src/views/admin/Market.vue b/resources/assets/src/views/admin/Market.vue index d1197628..b31732ef 100644 --- a/resources/assets/src/views/admin/Market.vue +++ b/resources/assets/src/views/admin/Market.vue @@ -75,12 +75,16 @@ import { VueGoodTable } from 'vue-good-table' import 'vue-good-table/dist/vue-good-table.min.css' import toastr from 'toastr' import { swal } from '../../js/notify' +import tableOptions from '../../components/mixins/tableOptions' export default { name: 'Market', components: { VueGoodTable, }, + mixins: [ + tableOptions, + ], data() { return { plugins: [], @@ -112,20 +116,6 @@ export default { 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: '', } }, diff --git a/resources/assets/src/views/admin/Players.vue b/resources/assets/src/views/admin/Players.vue index b6fa1afa..3076f0cb 100644 --- a/resources/assets/src/views/admin/Players.vue +++ b/resources/assets/src/views/admin/Players.vue @@ -120,12 +120,18 @@ import { VueGoodTable } from 'vue-good-table' import 'vue-good-table/dist/vue-good-table.min.css' import toastr from 'toastr' import { swal } from '../../js/notify' +import tableOptions from '../../components/mixins/tableOptions' +import serverTable from '../../components/mixins/serverTable' export default { name: 'PlayersManagement', components: { VueGoodTable, }, + mixins: [ + tableOptions, + serverTable, + ], props: { baseUrl: { type: String, @@ -135,7 +141,6 @@ export default { data() { return { players: [], - totalRecords: 0, columns: [ { field: 'pid', label: 'PID', type: 'number', @@ -154,24 +159,6 @@ export default { ], serverParams: { 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: { originalIndex: -1, @@ -192,23 +179,6 @@ export default { this.totalRecords = totalRecords 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() { const player = this.players[this.textureChanges.originalIndex] const { type, tid } = this.textureChanges diff --git a/resources/assets/src/views/admin/Plugins.vue b/resources/assets/src/views/admin/Plugins.vue index e44fcb4c..9a4ccd87 100644 --- a/resources/assets/src/views/admin/Plugins.vue +++ b/resources/assets/src/views/admin/Plugins.vue @@ -79,12 +79,16 @@ import { VueGoodTable } from 'vue-good-table' import 'vue-good-table/dist/vue-good-table.min.css' import toastr from 'toastr' import { swal } from '../../js/notify' +import tableOptions from '../../components/mixins/tableOptions' export default { name: 'Plugins', components: { VueGoodTable, }, + mixins: [ + tableOptions, + ], props: { baseUrl: { type: String, @@ -111,20 +115,6 @@ export default { 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() { diff --git a/resources/assets/src/views/admin/Users.vue b/resources/assets/src/views/admin/Users.vue index 9005565d..b5342e0e 100644 --- a/resources/assets/src/views/admin/Users.vue +++ b/resources/assets/src/views/admin/Users.vue @@ -91,6 +91,8 @@ import 'vue-good-table/dist/vue-good-table.min.css' import toastr from 'toastr' import { trans } from '../../js/i18n' import { swal } from '../../js/notify' +import tableOptions from '../../components/mixins/tableOptions' +import serverTable from '../../components/mixins/serverTable' export default { name: 'UsersManagement', @@ -116,10 +118,13 @@ export default { return `${blessing.base_url}/admin/players?uid=${user.uid}` }, }, + mixins: [ + tableOptions, + serverTable, + ], data() { return { users: [], - totalRecords: 0, columns: [ { field: 'uid', label: 'UID', type: 'number', @@ -147,24 +152,6 @@ export default { ], serverParams: { 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.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) { const { dismiss, value } = await swal({ text: this.$t('admin.newUserEmail'), diff --git a/resources/assets/tests/components/mixins/serverTable.test.ts b/resources/assets/tests/components/mixins/serverTable.test.ts new file mode 100644 index 00000000..5cd910a8 --- /dev/null +++ b/resources/assets/tests/components/mixins/serverTable.test.ts @@ -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') +}) diff --git a/resources/assets/tests/views/admin/Players.test.ts b/resources/assets/tests/views/admin/Players.test.ts index b0468520..b6cb96a1 100644 --- a/resources/assets/tests/views/admin/Players.test.ts +++ b/resources/assets/tests/views/admin/Players.test.ts @@ -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(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 () => { window.$ = jest.fn(() => ({ modal() {} })) Vue.prototype.$http.get.mockResolvedValue({ diff --git a/resources/assets/tests/views/admin/Users.test.ts b/resources/assets/tests/views/admin/Users.test.ts index 70c6b00a..c85e3026 100644 --- a/resources/assets/tests/views/admin/Users.test.ts +++ b/resources/assets/tests/views/admin/Users.test.ts @@ -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(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 () => { Vue.prototype.$http.get.mockResolvedValue({ data: [