Update initialization of datatables
This commit is contained in:
parent
a13d5a947a
commit
efe5c6229c
@ -65,6 +65,8 @@ describe('tests for "customize" module', () => {
|
|||||||
describe('tests for "players" module', () => {
|
describe('tests for "players" module', () => {
|
||||||
const modulePath = '../admin/players';
|
const modulePath = '../admin/players';
|
||||||
|
|
||||||
|
// TODO: test initializing players table
|
||||||
|
|
||||||
it('show "change player texture" modal dialog', () => {
|
it('show "change player texture" modal dialog', () => {
|
||||||
const trans = jest.fn(key => key);
|
const trans = jest.fn(key => key);
|
||||||
const showModal = jest.fn();
|
const showModal = jest.fn();
|
||||||
@ -401,6 +403,8 @@ describe('tests for "players" module', () => {
|
|||||||
describe('tests for "plugins" module', () => {
|
describe('tests for "plugins" module', () => {
|
||||||
const modulePath = '../admin/plugins';
|
const modulePath = '../admin/plugins';
|
||||||
|
|
||||||
|
// TODO: test initializing plugins table
|
||||||
|
|
||||||
it('enable a plugin', async () => {
|
it('enable a plugin', async () => {
|
||||||
const fetch = jest.fn()
|
const fetch = jest.fn()
|
||||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||||
@ -673,6 +677,8 @@ describe('tests for "update" module', () => {
|
|||||||
describe('tests for "users" module', () => {
|
describe('tests for "users" module', () => {
|
||||||
const modulePath = '../admin/users';
|
const modulePath = '../admin/users';
|
||||||
|
|
||||||
|
// TODO: test initializing users table
|
||||||
|
|
||||||
it('change user email', async () => {
|
it('change user email', async () => {
|
||||||
const fetch = jest.fn()
|
const fetch = jest.fn()
|
||||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||||
@ -1126,6 +1132,7 @@ describe('tests for "common" module', () => {
|
|||||||
const fetch = jest.fn()
|
const fetch = jest.fn()
|
||||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'Recorded.' }));
|
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'Recorded.' }));
|
||||||
|
|
||||||
|
$.fn.dataTable = { defaults: {} };
|
||||||
window.document.cookie = '';
|
window.document.cookie = '';
|
||||||
window.fetch = fetch;
|
window.fetch = fetch;
|
||||||
window.blessing = {
|
window.blessing = {
|
||||||
@ -1148,27 +1155,4 @@ describe('tests for "common" module', () => {
|
|||||||
await sendFeedback();
|
await sendFeedback();
|
||||||
expect(fetch).toHaveBeenCalledTimes(1);
|
expect(fetch).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('initialize data tables', () => {
|
|
||||||
$.fn.dataTable = { defaults: {} };
|
|
||||||
const initUsersTable = jest.fn();
|
|
||||||
const initPlayersTable = jest.fn();
|
|
||||||
const initPluginsTable = jest.fn();
|
|
||||||
window.initUsersTable = initUsersTable;
|
|
||||||
window.initPlayersTable = initPlayersTable;
|
|
||||||
window.initPluginsTable = initPluginsTable;
|
|
||||||
const { initTables } = require(modulePath);
|
|
||||||
|
|
||||||
document.body.innerHTML = '<div id="user-table"></div>';
|
|
||||||
initTables();
|
|
||||||
expect(initUsersTable).toBeCalled();
|
|
||||||
|
|
||||||
document.body.innerHTML = '<div id="player-table"></div>';
|
|
||||||
initTables();
|
|
||||||
expect(initPlayersTable).toBeCalled();
|
|
||||||
|
|
||||||
document.body.innerHTML = '<div id="plugin-table"></div>';
|
|
||||||
initTables();
|
|
||||||
expect($.pluginsTable).not.toBeNull();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
/* global initUsersTable, initPlayersTable, initPluginsTable */
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
$.pluginsTable = null;
|
|
||||||
|
|
||||||
$(document).ready(initTables);
|
|
||||||
|
|
||||||
function initTables() {
|
|
||||||
$.extend(true, $.fn.dataTable.defaults, {
|
$.extend(true, $.fn.dataTable.defaults, {
|
||||||
language: trans('vendor.datatables'),
|
language: trans('vendor.datatables'),
|
||||||
scrollX: true,
|
scrollX: true,
|
||||||
@ -16,15 +9,6 @@ function initTables() {
|
|||||||
serverSide: true
|
serverSide: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($('#user-table').length === 1) {
|
|
||||||
initUsersTable();
|
|
||||||
} else if ($('#player-table').length === 1) {
|
|
||||||
initPlayersTable();
|
|
||||||
} else if ($('#plugin-table').length === 1) {
|
|
||||||
$.pluginsTable = initPluginsTable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendFeedback() {
|
async function sendFeedback() {
|
||||||
if (document.cookie.replace(/(?:(?:^|.*;\s*)feedback_sent\s*=\s*([^;]*).*$)|^.*$/, '$1') !== '') {
|
if (document.cookie.replace(/(?:(?:^|.*;\s*)feedback_sent\s*=\s*([^;]*).*$)|^.*$/, '$1') !== '') {
|
||||||
return;
|
return;
|
||||||
@ -55,6 +39,5 @@ async function sendFeedback() {
|
|||||||
if (process.env.NODE_ENV === 'test') {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sendFeedback,
|
sendFeedback,
|
||||||
initTables
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,88 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if ($('#player-table').length === 1) {
|
||||||
|
$(document).ready(initPlayersTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initPlayersTable() {
|
||||||
|
const specificUid = getQueryString('uid');
|
||||||
|
const query = specificUid ? `?uid=${specificUid}` : '';
|
||||||
|
|
||||||
|
$('#player-table').DataTable({
|
||||||
|
ajax: url(`admin/player-data${query}`),
|
||||||
|
scrollY: ($('.content-wrapper').height() - $('.content-header').outerHeight()) * 0.7,
|
||||||
|
fnDrawCallback: () => $('[data-toggle="tooltip"]').tooltip(),
|
||||||
|
columnDefs: playersTableColumnDefs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const playersTableColumnDefs = [
|
||||||
|
{
|
||||||
|
targets: 0,
|
||||||
|
data: 'pid',
|
||||||
|
width: '1%'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 1,
|
||||||
|
data: 'uid',
|
||||||
|
render: (data, type, row) => `<a href="${url('admin/users?uid=' + row.uid)}" title="${trans('admin.inspectHisOwner')}" data-toggle="tooltip" data-placement="right">${data}</span>`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 2,
|
||||||
|
data: 'player_name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 3,
|
||||||
|
data: 'preference',
|
||||||
|
render: data => {
|
||||||
|
return `
|
||||||
|
<select class="form-control" onchange="changePreference.call(this)">
|
||||||
|
<option ${(data === 'default') ? 'selected=selected' : ''} value="default">Default</option>
|
||||||
|
<option ${(data === 'slim') ? 'selected=selected' : ''} value="slim">Slim</option>
|
||||||
|
</select>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 4,
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
|
render: (data, type, row) => ['steve', 'alex', 'cape'].reduce((html, type) => {
|
||||||
|
const currentTypeTid = row[`tid_${type}`];
|
||||||
|
const imageId = `${row.pid}-${currentTypeTid}`;
|
||||||
|
|
||||||
|
if (currentTypeTid === 0) {
|
||||||
|
return html + `<img id="${imageId}" width="64" />`;
|
||||||
|
} else {
|
||||||
|
return html + `
|
||||||
|
<a href="${ url('skinlib/show/' + currentTypeTid) }">
|
||||||
|
<img id="${imageId}" width="64" src="${url('/preview/64/' + currentTypeTid)}.png" />
|
||||||
|
</a>`;
|
||||||
|
}
|
||||||
|
}, '')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 5,
|
||||||
|
data: 'last_modified'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 6,
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
|
render: (data, type, row) => `
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
${ trans('admin.operationsTitle') } <span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a style="cursor: pointer" onclick="changeTexture(${row.pid}, '${row.player_name}');">${trans('admin.changeTexture')}</a></li>
|
||||||
|
<li><a style="cursor: pointer" onclick="changePlayerName(${row.pid}, '${row.player_name}');">${trans('admin.changePlayerName')}</a></li>
|
||||||
|
<li><a style="cursor: pointer" onclick="changeOwner(${row.pid});">${trans('admin.changeOwner')}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-danger btn-sm" style="cursor: pointer" onclick="deletePlayer(${row.pid});">${trans('admin.deletePlayer')}</a>`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
async function changePreference() {
|
async function changePreference() {
|
||||||
try {
|
try {
|
||||||
const { errno, msg } = await fetch({
|
const { errno, msg } = await fetch({
|
||||||
@ -193,6 +276,7 @@ async function deletePlayer(pid) {
|
|||||||
|
|
||||||
if (process.env.NODE_ENV === 'test') {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
initPlayersTable,
|
||||||
changeOwner,
|
changeOwner,
|
||||||
showNicknameInSwal,
|
showNicknameInSwal,
|
||||||
deletePlayer,
|
deletePlayer,
|
||||||
|
@ -1,5 +1,67 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if ($('#plugin-table').length === 1) {
|
||||||
|
$(document).ready(initPluginsTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initPluginsTable() {
|
||||||
|
$.pluginsTable = $('#plugin-table').DataTable({
|
||||||
|
ajax: url('admin/plugins/data'),
|
||||||
|
fnDrawCallback: () => $('[data-toggle="tooltip"]').tooltip(),
|
||||||
|
columnDefs: pluginsTableColumnDefs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const pluginsTableColumnDefs = [
|
||||||
|
{
|
||||||
|
targets: 0,
|
||||||
|
data: 'title'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 1,
|
||||||
|
data: 'description',
|
||||||
|
width: '35%'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 2,
|
||||||
|
data: 'author',
|
||||||
|
render: data => isEmpty(data.url) ? data.author : `<a href="${data.url}" target="_blank">${data.author}</a>`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 3,
|
||||||
|
data: 'version'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 4,
|
||||||
|
data: 'status'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 5,
|
||||||
|
data: 'operations',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
|
render: (data, type, row) => {
|
||||||
|
let toggleButton, configViewButton;
|
||||||
|
|
||||||
|
if (data.enabled) {
|
||||||
|
toggleButton = `<a class="btn btn-warning btn-sm" onclick="disablePlugin('${row.name}');">${trans('admin.disablePlugin')}</a>`;
|
||||||
|
} else {
|
||||||
|
toggleButton = `<a class="btn btn-primary btn-sm" onclick="enablePlugin('${row.name}');">${trans('admin.enablePlugin')}</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.enabled && data.hasConfigView) {
|
||||||
|
configViewButton = `<a class="btn btn-default btn-sm" href="${url('/')}admin/plugins/config/${row.name}">${trans('admin.configurePlugin')}</a>`;
|
||||||
|
} else {
|
||||||
|
configViewButton = `<a class="btn btn-default btn-sm" disabled="disabled" title="${trans('admin.noPluginConfigNotice')}" data-toggle="tooltip" data-placement="top">${trans('admin.configurePlugin')}</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePluginButton = `<a class="btn btn-danger btn-sm" onclick="deletePlugin('${row.name}');">${trans('admin.deletePlugin')}</a>`;
|
||||||
|
|
||||||
|
return toggleButton + configViewButton + deletePluginButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
async function enablePlugin(name) {
|
async function enablePlugin(name) {
|
||||||
try {
|
try {
|
||||||
const { errno, msg } = await fetch({
|
const { errno, msg } = await fetch({
|
||||||
@ -69,6 +131,7 @@ async function deletePlugin(name) {
|
|||||||
|
|
||||||
if (process.env.NODE_ENV === 'test') {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
initPluginsTable,
|
||||||
deletePlugin,
|
deletePlugin,
|
||||||
enablePlugin,
|
enablePlugin,
|
||||||
disablePlugin,
|
disablePlugin,
|
||||||
|
@ -1,289 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
function initUsersTable() {
|
|
||||||
const uid = getQueryString('uid');
|
|
||||||
const dataUrl = url('admin/user-data') + (uid ? `?uid=${uid}` : '');
|
|
||||||
|
|
||||||
$('#user-table').DataTable({
|
|
||||||
ajax: dataUrl,
|
|
||||||
scrollY: ($('.content-wrapper').height() - $('.content-header').outerHeight()) * 0.7,
|
|
||||||
fnDrawCallback: () => {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
},
|
|
||||||
rowCallback: (row, data) => {
|
|
||||||
$(row).attr('id', `user-${data.uid}`);
|
|
||||||
},
|
|
||||||
columnDefs: [
|
|
||||||
{
|
|
||||||
targets: 0,
|
|
||||||
data: 'uid',
|
|
||||||
width: '1%'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 1,
|
|
||||||
data: 'email'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 2,
|
|
||||||
data: 'nickname'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 3,
|
|
||||||
data: 'score',
|
|
||||||
render: data => {
|
|
||||||
return `<input type="number" class="form-control score" value="${data}" title="${trans('admin.scoreTip')}" data-toggle="tooltip" data-placement="right">`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 4,
|
|
||||||
data: 'players_count',
|
|
||||||
searchable: false,
|
|
||||||
orderable: false,
|
|
||||||
render: (data, type, row) => {
|
|
||||||
return `<span title="${trans('admin.doubleClickToSeePlayers')}"
|
|
||||||
style="cursor: pointer;"
|
|
||||||
ondblclick="window.location.href = '${url('admin/players?uid=') + row.uid}'"
|
|
||||||
data-toggle="tooltip" data-placement="top">${data}</span>`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 5,
|
|
||||||
data: 'permission',
|
|
||||||
className: 'status',
|
|
||||||
render: data => {
|
|
||||||
switch (data) {
|
|
||||||
case -1:
|
|
||||||
return trans('admin.banned');
|
|
||||||
case 0:
|
|
||||||
return trans('admin.normal');
|
|
||||||
case 1:
|
|
||||||
return trans('admin.admin');
|
|
||||||
case 2:
|
|
||||||
return trans('admin.superAdmin');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 6,
|
|
||||||
data: 'register_at'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 7,
|
|
||||||
data: 'operations',
|
|
||||||
searchable: false,
|
|
||||||
orderable: false,
|
|
||||||
render: (data, type, row) => {
|
|
||||||
let adminOption = '', bannedOption = '', deleteUserButton;
|
|
||||||
if (row.permission !== 2) {
|
|
||||||
if (data === 2) {
|
|
||||||
if (row.permission === 1) {
|
|
||||||
adminOption = `<li class="divider"></li>
|
|
||||||
<li><a id="admin-${row.uid}" data="admin" style="cursor: pointer" onclick="changeAdminStatus(${row.uid});">${trans('admin.unsetAdmin')}</a></li>`;
|
|
||||||
} else {
|
|
||||||
adminOption = `<li class="divider"></li>
|
|
||||||
<li><a id="admin-${row.uid}" data="normal" style="cursor: pointer" onclick="changeAdminStatus(${row.uid});">${trans('admin.setAdmin')}</a></li>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (row.permission === -1) {
|
|
||||||
bannedOption = `<li class="divider"></li>
|
|
||||||
<li><a id="ban-${row.uid}" data="banned" style="cursor: pointer" onclick="changeBanStatus(${row.uid});">${trans('admin.unban')}</a></li>`;
|
|
||||||
} else {
|
|
||||||
bannedOption = `<li class="divider"></li>
|
|
||||||
<li><a id="ban-${row.uid}" data="normal" style="cursor: pointer" onclick="changeBanStatus(${row.uid});">${trans('admin.ban')}</a></li>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data === 2) {
|
|
||||||
if (row.permission === 2) {
|
|
||||||
deleteUserButton = `
|
|
||||||
<a class="btn btn-danger btn-sm" disabled="disabled" data-toggle="tooltip" data-placement="bottom" title="${trans('admin.cannotDeleteSuperAdmin')}">${trans('admin.deleteUser')}</a>`;
|
|
||||||
} else {
|
|
||||||
deleteUserButton = `
|
|
||||||
<a class="btn btn-danger btn-sm" style="cursor: pointer" onclick="deleteUserAccount(${row.uid});">${trans('admin.deleteUser')}</a>`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (row.permission === 1 || row.permission === 2) {
|
|
||||||
deleteUserButton = `
|
|
||||||
<a class="btn btn-danger btn-sm" disabled="disabled" data-toggle="tooltip" data-placement="bottom" title="${trans('admin.cannotDeleteAdmin')}">${trans('admin.deleteUser')}</a>`;
|
|
||||||
} else {
|
|
||||||
deleteUserButton = `
|
|
||||||
<a class="btn btn-danger btn-sm" style="cursor: pointer" onclick="deleteUserAccount(${row.uid});">${trans('admin.deleteUser')}</a>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
${trans('admin.operationsTitle')} <span class="caret"></span></button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a style="cursor: pointer" onclick="changeUserEmail(${row.uid});">${trans('admin.changeEmail')}</a></li>
|
|
||||||
<li><a style="cursor: pointer" onclick="changeUserNickName(${row.uid});">${trans('admin.changeNickName')}</a></li>
|
|
||||||
<li><a style="cursor: pointer" onclick="changeUserPwd(${row.uid});">${trans('admin.changePassword')}</a></li>
|
|
||||||
${adminOption}${bannedOption}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
${deleteUserButton}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initPlayersTable() {
|
|
||||||
const uid = getQueryString('uid');
|
|
||||||
const dataUrl = url('admin/player-data') + (uid ? `?uid=${uid}` : '');
|
|
||||||
|
|
||||||
$('#player-table').DataTable({
|
|
||||||
ajax: dataUrl,
|
|
||||||
scrollY: ($('.content-wrapper').height() - $('.content-header').outerHeight()) * 0.7,
|
|
||||||
fnDrawCallback: () => {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
},
|
|
||||||
columnDefs: [
|
|
||||||
{
|
|
||||||
targets: 0,
|
|
||||||
data: 'pid',
|
|
||||||
width: '1%'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 1,
|
|
||||||
data: 'uid',
|
|
||||||
render: (data, type, row) => {
|
|
||||||
return `<span title="${trans('admin.doubleClickToSeeUser')}"
|
|
||||||
style="cursor: pointer;"
|
|
||||||
ondblclick="window.location.href = '${url('admin/users?uid=') + row.uid}'"
|
|
||||||
data-toggle="tooltip" data-placement="top">${data}</span>`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 2,
|
|
||||||
data: 'player_name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 3,
|
|
||||||
data: 'preference',
|
|
||||||
render: data => {
|
|
||||||
return `
|
|
||||||
<select class="form-control" onchange="changePreference.call(this)">
|
|
||||||
<option ${(data === 'default') ? 'selected=selected' : ''} value="default">Default</option>
|
|
||||||
<option ${(data === 'slim') ? 'selected=selected' : ''} value="slim">Slim</option>
|
|
||||||
</select>`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 4,
|
|
||||||
searchable: false,
|
|
||||||
orderable: false,
|
|
||||||
render: (data, type, row) => {
|
|
||||||
const html = { steve: '', alex: '', cape: '' };
|
|
||||||
['steve', 'alex', 'cape'].forEach(textureType => {
|
|
||||||
if (row['tid_' + textureType] === 0) {
|
|
||||||
html[textureType] = `<img id="${row.pid}-${row['tid_' + textureType]}" width="64" />`;
|
|
||||||
} else {
|
|
||||||
html[textureType] = `
|
|
||||||
<a href="${url('/')}skinlib/show/${row['tid_' + textureType]}">
|
|
||||||
<img id="${row.pid}-${row['tid_' + textureType]}" width="64" src="${url('/')}preview/64/${row['tid_' + textureType]}.png" />
|
|
||||||
</a>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return html.steve + html.alex + html.cape;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 5,
|
|
||||||
data: 'last_modified'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 6,
|
|
||||||
searchable: false,
|
|
||||||
orderable: false,
|
|
||||||
render: (data, type, row) => {
|
|
||||||
return `
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
${trans('admin.operationsTitle')} <span class="caret"></span></button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a style="cursor: pointer" onclick="changeTexture(${row.pid}, '${row.player_name}');">${trans('admin.changeTexture')}</a></li>
|
|
||||||
<li><a style="cursor: pointer" onclick="changePlayerName(${row.pid}, '${row.player_name}');">${trans('admin.changePlayerName')}</a></li>
|
|
||||||
<li><a style="cursor: pointer" onclick="changeOwner(${row.pid});">${trans('admin.changeOwner')}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<a class="btn btn-danger btn-sm" style="cursor: pointer" onclick="deletePlayer(${row.pid});">${trans('admin.deletePlayer')}</a>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initPluginsTable() {
|
|
||||||
return $('#plugin-table').DataTable({
|
|
||||||
ajax: url('admin/plugins/data'),
|
|
||||||
fnDrawCallback: () => {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
},
|
|
||||||
columnDefs: [
|
|
||||||
{
|
|
||||||
targets: 0,
|
|
||||||
data: 'title'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 1,
|
|
||||||
data: 'description',
|
|
||||||
width: '35%'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 2,
|
|
||||||
data: 'author',
|
|
||||||
render: data => {
|
|
||||||
if (data.url === '' || data.url === null) {
|
|
||||||
return data.author;
|
|
||||||
} else {
|
|
||||||
return `<a href="${data.url}" target="_blank">${data.author}</a>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 3,
|
|
||||||
data: 'version'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 4,
|
|
||||||
data: 'status'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
targets: 5,
|
|
||||||
data: 'operations',
|
|
||||||
searchable: false,
|
|
||||||
orderable: false,
|
|
||||||
render: (data, type, row) => {
|
|
||||||
let switchEnableButton, configViewButton;
|
|
||||||
if (data.enabled) {
|
|
||||||
switchEnableButton = `
|
|
||||||
<a class="btn btn-warning btn-sm" style="cursor: pointer" onclick="disablePlugin('${row.name}');">${trans('admin.disablePlugin')}</a>`;
|
|
||||||
} else {
|
|
||||||
switchEnableButton = `
|
|
||||||
<a class="btn btn-primary btn-sm" style="cursor: pointer" onclick="enablePlugin('${row.name}');">${trans('admin.enablePlugin')}</a>`;
|
|
||||||
}
|
|
||||||
if (data.enabled && data.hasConfigView) {
|
|
||||||
configViewButton = `
|
|
||||||
<a class="btn btn-default btn-sm" href="${url('/')}admin/plugins/config/${row.name}">${trans('admin.configurePlugin')}</a>`;
|
|
||||||
} else {
|
|
||||||
configViewButton = `
|
|
||||||
<a class="btn btn-default btn-sm" disabled="disabled" title="${trans('admin.noPluginConfigNotice')}" data-toggle="tooltip" data-placement="top">${trans('admin.configurePlugin')}</a>`;
|
|
||||||
}
|
|
||||||
const deletePluginButton = `
|
|
||||||
<a class="btn btn-danger btn-sm" style="cursor: pointer" onclick="deletePlugin('${row.name}');">${trans('admin.deletePlugin')}</a>`;
|
|
||||||
return switchEnableButton + configViewButton + deletePluginButton;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'test') {
|
|
||||||
module.exports = {
|
|
||||||
initUsersTable,
|
|
||||||
initPlayersTable,
|
|
||||||
initPluginsTable,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,5 +1,122 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if ($('#user-table').length === 1) {
|
||||||
|
$(document).ready(initUsersTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initUsersTable() {
|
||||||
|
const specificUid = getQueryString('uid');
|
||||||
|
const query = specificUid ? `?uid=${specificUid}` : '';
|
||||||
|
|
||||||
|
$('#user-table').DataTable({
|
||||||
|
ajax: url(`admin/user-data${query}`),
|
||||||
|
scrollY: ($('.content-wrapper').height() - $('.content-header').outerHeight()) * 0.7,
|
||||||
|
fnDrawCallback: () => $('[data-toggle="tooltip"]').tooltip(),
|
||||||
|
rowCallback: (row, data) => $(row).attr('id', `user-${data.uid}`),
|
||||||
|
columnDefs: usersTableColumnDefs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const userPermissions = {
|
||||||
|
'-1': 'banned',
|
||||||
|
'0': 'normal',
|
||||||
|
'1': 'admin',
|
||||||
|
'2': 'superAdmin'
|
||||||
|
};
|
||||||
|
|
||||||
|
const usersTableColumnDefs = [
|
||||||
|
{
|
||||||
|
targets: 0,
|
||||||
|
data: 'uid',
|
||||||
|
width: '1%'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 1,
|
||||||
|
data: 'email'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 2,
|
||||||
|
data: 'nickname'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 3,
|
||||||
|
data: 'score',
|
||||||
|
render: data => `<input type="number" class="form-control score" value="${data}" title="${trans('admin.scoreTip')}" data-toggle="tooltip" data-placement="right">`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 4,
|
||||||
|
data: 'players_count',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
|
render: (data, type, row) => `<a href="${url('admin/players?uid='+row.uid)}" title="${trans('admin.inspectHisPlayers')}" data-toggle="tooltip" data-placement="right">${data}</span>`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 5,
|
||||||
|
data: 'permission',
|
||||||
|
className: 'status',
|
||||||
|
render: data => trans('admin.' + userPermissions[data])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 6,
|
||||||
|
data: 'register_at'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
targets: 7,
|
||||||
|
data: 'operations',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
|
render: renderUsersTableOperations
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function renderUsersTableOperations(currentUserPermission, type, row) {
|
||||||
|
let adminOption = '', bannedOption = '', deleteUserButton;
|
||||||
|
|
||||||
|
if (row.permission !== 2) {
|
||||||
|
// Only SUPER admins are allowed to set/unset admins
|
||||||
|
if (currentUserPermission === 2) {
|
||||||
|
const adminStatus = row.permission === 1 ? 'admin' : 'normal';
|
||||||
|
adminOption = `<li class="divider"></li> <li><a id="admin-${row.uid}" data="${adminStatus}" onclick="changeAdminStatus(${row.uid});">
|
||||||
|
${ adminStatus === 'admin' ? trans('admin.unsetAdmin') : trans('admin.setAdmin') }
|
||||||
|
</a></li>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const banStatus = row.permission === -1 ? 'banned' : 'normal';
|
||||||
|
bannedOption = `<li class="divider"></li> <li><a id="ban-${row.uid}" data="${banStatus}" onclick="changeBanStatus(${row.uid});">
|
||||||
|
${ banStatus === 'banned' ? trans('admin.unban') : trans('admin.ban') }
|
||||||
|
</a></li>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUserPermission === 2) {
|
||||||
|
if (row.permission === 2) {
|
||||||
|
deleteUserButton = `<a class="btn btn-danger btn-sm" disabled="disabled" data-toggle="tooltip" data-placement="bottom" title="${trans('admin.cannotDeleteSuperAdmin')}">${trans('admin.deleteUser')}</a>`;
|
||||||
|
} else {
|
||||||
|
deleteUserButton = `<a class="btn btn-danger btn-sm" onclick="deleteUserAccount(${row.uid});">${trans('admin.deleteUser')}</a>`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (row.permission === 1 || row.permission === 2) {
|
||||||
|
deleteUserButton = `<a class="btn btn-danger btn-sm" disabled="disabled" data-toggle="tooltip" data-placement="bottom" title="${trans('admin.cannotDeleteAdmin')}">${trans('admin.deleteUser')}</a>`;
|
||||||
|
} else {
|
||||||
|
deleteUserButton = `<a class="btn btn-danger btn-sm" onclick="deleteUserAccount(${row.uid});">${trans('admin.deleteUser')}</a>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
${trans('admin.operationsTitle')} <span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a onclick="changeUserEmail(${row.uid});">${trans('admin.changeEmail')}</a></li>
|
||||||
|
<li><a onclick="changeUserNickName(${row.uid});">${trans('admin.changeNickName')}</a></li>
|
||||||
|
<li><a onclick="changeUserPwd(${row.uid});">${trans('admin.changePassword')}</a></li>
|
||||||
|
${adminOption}
|
||||||
|
${bannedOption}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
${deleteUserButton}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function changeUserEmail(uid) {
|
async function changeUserEmail(uid) {
|
||||||
const dom = $(`tr#user-${uid} > td:nth-child(2)`);
|
const dom = $(`tr#user-${uid} > td:nth-child(2)`);
|
||||||
let newUserEmail = '';
|
let newUserEmail = '';
|
||||||
@ -217,6 +334,7 @@ $('body').on('keypress', '.score', function(event){
|
|||||||
|
|
||||||
if (process.env.NODE_ENV === 'test') {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
initUsersTable,
|
||||||
changeUserPwd,
|
changeUserPwd,
|
||||||
changeBanStatus,
|
changeBanStatus,
|
||||||
changeUserEmail,
|
changeUserEmail,
|
||||||
|
@ -24,6 +24,8 @@ td {
|
|||||||
img {
|
img {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:first-child > img {
|
a:first-child > img {
|
||||||
|
@ -140,8 +140,8 @@
|
|||||||
newUserPassword: 'Please enter the new password:',
|
newUserPassword: 'Please enter the new password:',
|
||||||
deleteUserNotice: 'Are you sure to delete this user? It\' permanent.',
|
deleteUserNotice: 'Are you sure to delete this user? It\' permanent.',
|
||||||
scoreTip: 'Press ENTER to submit new score',
|
scoreTip: 'Press ENTER to submit new score',
|
||||||
doubleClickToSeeUser: 'Double click to see info of this user',
|
inspectHisOwner: 'Click to inspect the owner of this player',
|
||||||
doubleClickToSeePlayers: 'Double click to see his/her players',
|
inspectHisPlayers: 'Click to inspect the players he owns',
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
banned: 'Banned',
|
banned: 'Banned',
|
||||||
|
@ -142,8 +142,8 @@
|
|||||||
newUserPassword: '请输入新密码:',
|
newUserPassword: '请输入新密码:',
|
||||||
deleteUserNotice: '真的要删除此用户吗?此操作不可恢复',
|
deleteUserNotice: '真的要删除此用户吗?此操作不可恢复',
|
||||||
scoreTip: '输入修改后的积分,回车提交',
|
scoreTip: '输入修改后的积分,回车提交',
|
||||||
doubleClickToSeeUser: '双击可查看该用户的信息',
|
inspectHisOwner: '点击查看该角色的所有者',
|
||||||
doubleClickToSeePlayers: '双击可查看该用户的角色',
|
inspectHisPlayers: '点击查看该用户的角色',
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
banned: '封禁',
|
banned: '封禁',
|
||||||
|
Loading…
Reference in New Issue
Block a user