Use server side table
This commit is contained in:
parent
f71a9b3dd8
commit
7e4ae5381b
@ -238,37 +238,72 @@ class AdminController extends Controller
|
||||
|
||||
public function getUserData(Request $request)
|
||||
{
|
||||
$users = collect();
|
||||
$isSingleUser = $request->has('uid');
|
||||
|
||||
if ($request->has('uid')) {
|
||||
if ($isSingleUser) {
|
||||
$users = User::select(['uid', 'email', 'nickname', 'score', 'permission', 'register_at'])
|
||||
->where('uid', intval($request->input('uid')));
|
||||
->where('uid', intval($request->input('uid')))
|
||||
->get();
|
||||
} else {
|
||||
$users = User::select(['uid', 'email', 'nickname', 'score', 'permission', 'register_at']);
|
||||
$search = $request->input('search', '');
|
||||
$sortField = $request->input('sortField', 'uid');
|
||||
$sortType = $request->input('sortType', 'asc');
|
||||
$page = $request->input('page', 1);
|
||||
$perPage = $request->input('perPage', 10);
|
||||
|
||||
$users = User::select(['uid', 'email', 'nickname', 'score', 'permission', 'register_at'])
|
||||
->where('uid', 'like', '%' . $search . '%')
|
||||
->orWhere('email', 'like', '%' . $search . '%')
|
||||
->orWhere('nickname', 'like', '%' . $search . '%')
|
||||
->orWhere('score', 'like', '%' . $search . '%')
|
||||
->orderBy($sortField, $sortType)
|
||||
->offset(($page - 1) * $perPage)
|
||||
->limit($perPage)
|
||||
->get();
|
||||
}
|
||||
|
||||
return Datatables::of($users)->editColumn('email', function ($user) {
|
||||
return $user->email ?: 'EMPTY';
|
||||
})
|
||||
->setRowId('uid')
|
||||
->addColumn('operations', Auth::user()->permission)
|
||||
->addColumn('players_count', function ($user) {
|
||||
return $user->players->count();
|
||||
})
|
||||
->make(true);
|
||||
$users->transform(function ($user) {
|
||||
$user->operations = auth()->user()->permission;
|
||||
$user->players_count = $user->players->count();
|
||||
return $user;
|
||||
});
|
||||
|
||||
return [
|
||||
'totalRecords' => $isSingleUser ? 1 : User::count(),
|
||||
'data' => $users
|
||||
];
|
||||
}
|
||||
|
||||
public function getPlayerData(Request $request)
|
||||
{
|
||||
$players = collect();
|
||||
if ($request->has('uid')) {
|
||||
$isSpecifiedUser = $request->has('uid');
|
||||
|
||||
if ($isSpecifiedUser) {
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'preference', 'tid_steve', 'tid_alex', 'tid_cape', 'last_modified'])
|
||||
->where('uid', intval($request->input('uid')));
|
||||
->where('uid', intval($request->input('uid')))
|
||||
->get();
|
||||
} else {
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'preference', 'tid_steve', 'tid_alex', 'tid_cape', 'last_modified']);
|
||||
$search = $request->input('search', '');
|
||||
$sortField = $request->input('sortField', 'pid');
|
||||
$sortType = $request->input('sortType', 'asc');
|
||||
$page = $request->input('page', 1);
|
||||
$perPage = $request->input('perPage', 10);
|
||||
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'preference', 'tid_steve', 'tid_alex', 'tid_cape', 'last_modified'])
|
||||
->where('pid', 'like', '%' . $search . '%')
|
||||
->orWhere('uid', 'like', '%' . $search . '%')
|
||||
->orWhere('player_name', 'like', '%' . $search . '%')
|
||||
->orWhere('preference', 'like', '%' . $search . '%')
|
||||
->orderBy($sortField, $sortType)
|
||||
->offset(($page - 1) * $perPage)
|
||||
->limit($perPage)
|
||||
->get();
|
||||
}
|
||||
|
||||
return Datatables::of($players)->setRowId('pid')->make(true);
|
||||
return [
|
||||
'totalRecords' => $isSpecifiedUser ? 1 : Player::count(),
|
||||
'data' => $players
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<section class="content">
|
||||
<vue-good-table
|
||||
mode="remote"
|
||||
:rows="players"
|
||||
:totalRows="totalRecords || players.length"
|
||||
:columns="columns"
|
||||
:search-options="tableOptions.search"
|
||||
:pagination-options="tableOptions.pagination"
|
||||
@on-page-change="onPageChange"
|
||||
@on-sort-change="onSortChange"
|
||||
@on-search="onSearch"
|
||||
@on-per-page-change="onPerPageChange"
|
||||
styleClass="vgt-table striped"
|
||||
>
|
||||
<template slot="table-row" slot-scope="props">
|
||||
@ -94,6 +100,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
players: [],
|
||||
totalRecords: 0,
|
||||
columns: [
|
||||
{ field: 'pid', label: 'PID', type: 'number' },
|
||||
{ field: 'player_name', label: this.$t('general.player.player-name') },
|
||||
@ -103,6 +110,13 @@ export default {
|
||||
{ field: 'last_modified', label: this.$t('general.player.last-modified') },
|
||||
{ field: 'operations', label: this.$t('admin.operationsTitle'), globalSearchDisabled: true, sortable: false },
|
||||
],
|
||||
serverParams: {
|
||||
sortField: 'pid',
|
||||
sortType: 'asc',
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
search: '',
|
||||
},
|
||||
tableOptions: {
|
||||
search: {
|
||||
enabled: true,
|
||||
@ -124,7 +138,29 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
this.players = (await this.$http.get(`/admin/player-data${location.search}`)).data;
|
||||
const { data, totalRecords } = await this.$http.get(
|
||||
`/admin/player-data${location.search}`,
|
||||
!location.search && this.serverParams
|
||||
);
|
||||
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(player, model) {
|
||||
const { dismiss, value } = await swal({
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<section class="content">
|
||||
<vue-good-table
|
||||
mode="remote"
|
||||
:rows="users"
|
||||
:totalRows="totalRecords || users.length"
|
||||
:columns="columns"
|
||||
:search-options="tableOptions.search"
|
||||
:pagination-options="tableOptions.pagination"
|
||||
@on-page-change="onPageChange"
|
||||
@on-sort-change="onSortChange"
|
||||
@on-search="onSearch"
|
||||
@on-per-page-change="onPerPageChange"
|
||||
styleClass="vgt-table striped"
|
||||
>
|
||||
<template slot="table-row" slot-scope="props">
|
||||
@ -96,6 +102,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
users: [],
|
||||
totalRecords: 0,
|
||||
columns: [
|
||||
{ field: 'uid', label: 'UID', type: 'number' },
|
||||
{ field: 'email', label: this.$t('general.user.email') },
|
||||
@ -106,6 +113,13 @@ export default {
|
||||
{ field: 'register_at', label: this.$t('general.user.register-at') },
|
||||
{ field: 'operations', label: this.$t('admin.operationsTitle'), sortable: false, globalSearchDisabled: true }
|
||||
],
|
||||
serverParams: {
|
||||
sortField: 'uid',
|
||||
sortType: 'asc',
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
search: '',
|
||||
},
|
||||
tableOptions: {
|
||||
search: {
|
||||
enabled: true,
|
||||
@ -127,9 +141,30 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
const { data } = await this.$http.get(`/admin/user-data${location.search}`);
|
||||
const { data, totalRecords } = await this.$http.get(
|
||||
`/admin/user-data${location.search}`,
|
||||
!location.search && this.serverParams
|
||||
);
|
||||
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'),
|
||||
|
@ -9,7 +9,41 @@ jest.mock('@/js/notify');
|
||||
test('fetch data after initializing', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [] });
|
||||
mount(Players);
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith('/admin/player-data');
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
'/admin/player-data',
|
||||
{ page: 1, perPage: 10, search: '', sortField: 'pid', sortType: 'asc' }
|
||||
);
|
||||
});
|
||||
|
||||
test('update tables', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
data: Array.from({ length: 20 }).map((item, 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 () => {
|
||||
|
@ -14,7 +14,41 @@ jest.mock('@/js/i18n', () => ({
|
||||
test('fetch data after initializing', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [] });
|
||||
mount(Users);
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith('/admin/user-data');
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
'/admin/user-data',
|
||||
{ page: 1, perPage: 10, search: '', sortField: 'uid', sortType: 'asc' }
|
||||
);
|
||||
});
|
||||
|
||||
test('update tables', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
data: Array.from({ length: 20 }).map((item, 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 () => {
|
||||
|
@ -105,10 +105,10 @@ Route::group(['middleware' => ['auth', 'admin'], 'prefix' => 'admin'], function
|
||||
Route::any('/options', 'AdminController@options');
|
||||
|
||||
Route::view('/users', 'admin.users');
|
||||
Route::get ('/user-data', 'AdminController@getUserData');
|
||||
Route::any ('/user-data', 'AdminController@getUserData');
|
||||
|
||||
Route::view('/players', 'admin.players');
|
||||
Route::get ('/player-data', 'AdminController@getPlayerData');
|
||||
Route::any ('/player-data', 'AdminController@getPlayerData');
|
||||
Route::get ('/user/{uid}', 'AdminController@getOneUser');
|
||||
|
||||
// ajax handlers
|
||||
|
@ -153,7 +153,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
||||
|
||||
public function testGetUserData()
|
||||
{
|
||||
$this->visit('/admin/user-data')
|
||||
$this->getJson('/admin/user-data')
|
||||
->seeJsonStructure([
|
||||
'data' => [[
|
||||
'uid',
|
||||
@ -168,7 +168,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
||||
]);
|
||||
|
||||
$user = factory(User::class)->create();
|
||||
$this->visit('/admin/user-data?uid='.$user->uid)
|
||||
$this->getJson('/admin/user-data?uid='.$user->uid)
|
||||
->seeJsonSubset([
|
||||
'data' => [[
|
||||
'uid' => $user->uid,
|
||||
@ -191,7 +191,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
||||
$player = factory(Player::class)->create();
|
||||
$user = $player->user;
|
||||
|
||||
$this->visit('/admin/player-data')
|
||||
$this->getJson('/admin/player-data')
|
||||
->seeJsonStructure([
|
||||
'data' => [[
|
||||
'pid',
|
||||
@ -205,7 +205,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
||||
]]
|
||||
]);
|
||||
|
||||
$this->visit('/admin/player-data?uid='.$user->uid)
|
||||
$this->getJson('/admin/player-data?uid='.$user->uid)
|
||||
->seeJsonSubset([
|
||||
'data' => [[
|
||||
'pid' => $player->pid,
|
||||
|
Loading…
Reference in New Issue
Block a user