From efe5c6229cf20b177af7b74eb23b6ded464ba587 Mon Sep 17 00:00:00 2001 From: printempw Date: Sat, 24 Feb 2018 15:59:56 +0800 Subject: [PATCH] Update initialization of datatables --- .../assets/src/js/__tests__/admin.test.js | 30 +- resources/assets/src/js/admin/common.js | 33 +- resources/assets/src/js/admin/players.js | 86 +++++- resources/assets/src/js/admin/plugins.js | 63 ++++ resources/assets/src/js/admin/tables.js | 289 ------------------ resources/assets/src/js/admin/users.js | 118 +++++++ resources/assets/src/sass/admin.scss | 2 + resources/lang/en/locale.js | 4 +- resources/lang/zh_CN/locale.js | 4 +- 9 files changed, 287 insertions(+), 342 deletions(-) delete mode 100644 resources/assets/src/js/admin/tables.js diff --git a/resources/assets/src/js/__tests__/admin.test.js b/resources/assets/src/js/__tests__/admin.test.js index 8dac73c8..e2382f0b 100644 --- a/resources/assets/src/js/__tests__/admin.test.js +++ b/resources/assets/src/js/__tests__/admin.test.js @@ -65,6 +65,8 @@ describe('tests for "customize" module', () => { describe('tests for "players" module', () => { const modulePath = '../admin/players'; + // TODO: test initializing players table + it('show "change player texture" modal dialog', () => { const trans = jest.fn(key => key); const showModal = jest.fn(); @@ -401,6 +403,8 @@ describe('tests for "players" module', () => { describe('tests for "plugins" module', () => { const modulePath = '../admin/plugins'; + // TODO: test initializing plugins table + it('enable a plugin', async () => { const fetch = jest.fn() .mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' })) @@ -673,6 +677,8 @@ describe('tests for "update" module', () => { describe('tests for "users" module', () => { const modulePath = '../admin/users'; + // TODO: test initializing users table + it('change user email', async () => { const fetch = jest.fn() .mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' })) @@ -1126,6 +1132,7 @@ describe('tests for "common" module', () => { const fetch = jest.fn() .mockReturnValue(Promise.resolve({ errno: 0, msg: 'Recorded.' })); + $.fn.dataTable = { defaults: {} }; window.document.cookie = ''; window.fetch = fetch; window.blessing = { @@ -1148,27 +1155,4 @@ describe('tests for "common" module', () => { await sendFeedback(); 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 = '
'; - initTables(); - expect(initUsersTable).toBeCalled(); - - document.body.innerHTML = '
'; - initTables(); - expect(initPlayersTable).toBeCalled(); - - document.body.innerHTML = '
'; - initTables(); - expect($.pluginsTable).not.toBeNull(); - }); }); diff --git a/resources/assets/src/js/admin/common.js b/resources/assets/src/js/admin/common.js index 22e0d012..19690091 100644 --- a/resources/assets/src/js/admin/common.js +++ b/resources/assets/src/js/admin/common.js @@ -1,29 +1,13 @@ -/* global initUsersTable, initPlayersTable, initPluginsTable */ - 'use strict'; -$.pluginsTable = null; - -$(document).ready(initTables); - -function initTables() { - $.extend(true, $.fn.dataTable.defaults, { - language: trans('vendor.datatables'), - scrollX: true, - pageLength: 25, - autoWidth: false, - processing: true, - serverSide: true - }); - - if ($('#user-table').length === 1) { - initUsersTable(); - } else if ($('#player-table').length === 1) { - initPlayersTable(); - } else if ($('#plugin-table').length === 1) { - $.pluginsTable = initPluginsTable(); - } -} +$.extend(true, $.fn.dataTable.defaults, { + language: trans('vendor.datatables'), + scrollX: true, + pageLength: 25, + autoWidth: false, + processing: true, + serverSide: true +}); async function sendFeedback() { if (document.cookie.replace(/(?:(?:^|.*;\s*)feedback_sent\s*=\s*([^;]*).*$)|^.*$/, '$1') !== '') { @@ -55,6 +39,5 @@ async function sendFeedback() { if (process.env.NODE_ENV === 'test') { module.exports = { sendFeedback, - initTables }; } diff --git a/resources/assets/src/js/admin/players.js b/resources/assets/src/js/admin/players.js index 439363cb..c7609125 100644 --- a/resources/assets/src/js/admin/players.js +++ b/resources/assets/src/js/admin/players.js @@ -1,5 +1,88 @@ '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) => `${data}` + }, + { + targets: 2, + data: 'player_name' + }, + { + targets: 3, + data: 'preference', + render: data => { + return ` + `; + } + }, + { + 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 + ``; + } else { + return html + ` + + + `; + } + }, '') + }, + { + targets: 5, + data: 'last_modified' + }, + { + targets: 6, + searchable: false, + orderable: false, + render: (data, type, row) => ` +
+ + +
+ ${trans('admin.deletePlayer')}` + } +]; + async function changePreference() { try { const { errno, msg } = await fetch({ @@ -100,7 +183,7 @@ async function changePlayerName(pid, oldName) { } } catch (error) { showAjaxError(error); - } + } } function changeOwner(pid) { @@ -193,6 +276,7 @@ async function deletePlayer(pid) { if (process.env.NODE_ENV === 'test') { module.exports = { + initPlayersTable, changeOwner, showNicknameInSwal, deletePlayer, diff --git a/resources/assets/src/js/admin/plugins.js b/resources/assets/src/js/admin/plugins.js index d2157742..8088f087 100644 --- a/resources/assets/src/js/admin/plugins.js +++ b/resources/assets/src/js/admin/plugins.js @@ -1,5 +1,67 @@ '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 : `${data.author}` + }, + { + 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 = `${trans('admin.disablePlugin')}`; + } else { + toggleButton = `${trans('admin.enablePlugin')}`; + } + + if (data.enabled && data.hasConfigView) { + configViewButton = `${trans('admin.configurePlugin')}`; + } else { + configViewButton = `${trans('admin.configurePlugin')}`; + } + + const deletePluginButton = `${trans('admin.deletePlugin')}`; + + return toggleButton + configViewButton + deletePluginButton; + } + } +]; + async function enablePlugin(name) { try { const { errno, msg } = await fetch({ @@ -69,6 +131,7 @@ async function deletePlugin(name) { if (process.env.NODE_ENV === 'test') { module.exports = { + initPluginsTable, deletePlugin, enablePlugin, disablePlugin, diff --git a/resources/assets/src/js/admin/tables.js b/resources/assets/src/js/admin/tables.js deleted file mode 100644 index 70c57d3b..00000000 --- a/resources/assets/src/js/admin/tables.js +++ /dev/null @@ -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 ``; - } - }, - { - targets: 4, - data: 'players_count', - searchable: false, - orderable: false, - render: (data, type, row) => { - return `${data}`; - } - }, - { - 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 = `
  • -
  • ${trans('admin.unsetAdmin')}
  • `; - } else { - adminOption = `
  • -
  • ${trans('admin.setAdmin')}
  • `; - } - } - if (row.permission === -1) { - bannedOption = `
  • -
  • ${trans('admin.unban')}
  • `; - } else { - bannedOption = `
  • -
  • ${trans('admin.ban')}
  • `; - } - } - - if (data === 2) { - if (row.permission === 2) { - deleteUserButton = ` - ${trans('admin.deleteUser')}`; - } else { - deleteUserButton = ` - ${trans('admin.deleteUser')}`; - } - } else { - if (row.permission === 1 || row.permission === 2) { - deleteUserButton = ` - ${trans('admin.deleteUser')}`; - } else { - deleteUserButton = ` - ${trans('admin.deleteUser')}`; - } - } - - return ` -
    - - -
    - ${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 `${data}`; - } - }, - { - targets: 2, - data: 'player_name' - }, - { - targets: 3, - data: 'preference', - render: data => { - return ` - `; - } - }, - { - 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] = ``; - } else { - html[textureType] = ` - - - `; - } - }); - return html.steve + html.alex + html.cape; - } - }, - { - targets: 5, - data: 'last_modified' - }, - { - targets: 6, - searchable: false, - orderable: false, - render: (data, type, row) => { - return ` -
    - - -
    - ${trans('admin.deletePlayer')}`; - } - } - ] - }); -} - -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 `${data.author}`; - } - } - }, - { - 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 = ` - ${trans('admin.disablePlugin')}`; - } else { - switchEnableButton = ` - ${trans('admin.enablePlugin')}`; - } - if (data.enabled && data.hasConfigView) { - configViewButton = ` - ${trans('admin.configurePlugin')}`; - } else { - configViewButton = ` - ${trans('admin.configurePlugin')}`; - } - const deletePluginButton = ` - ${trans('admin.deletePlugin')}`; - return switchEnableButton + configViewButton + deletePluginButton; - } - } - ] - }); -} - -if (process.env.NODE_ENV === 'test') { - module.exports = { - initUsersTable, - initPlayersTable, - initPluginsTable, - }; -} diff --git a/resources/assets/src/js/admin/users.js b/resources/assets/src/js/admin/users.js index 4074823f..e69c52e0 100644 --- a/resources/assets/src/js/admin/users.js +++ b/resources/assets/src/js/admin/users.js @@ -1,5 +1,122 @@ '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 => `` + }, + { + targets: 4, + data: 'players_count', + searchable: false, + orderable: false, + render: (data, type, row) => `${data}` + }, + { + 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 = `
  • + ${ adminStatus === 'admin' ? trans('admin.unsetAdmin') : trans('admin.setAdmin') } +
  • `; + } + + const banStatus = row.permission === -1 ? 'banned' : 'normal'; + bannedOption = `
  • + ${ banStatus === 'banned' ? trans('admin.unban') : trans('admin.ban') } +
  • `; + } + + if (currentUserPermission === 2) { + if (row.permission === 2) { + deleteUserButton = `${trans('admin.deleteUser')}`; + } else { + deleteUserButton = `${trans('admin.deleteUser')}`; + } + } else { + if (row.permission === 1 || row.permission === 2) { + deleteUserButton = `${trans('admin.deleteUser')}`; + } else { + deleteUserButton = `${trans('admin.deleteUser')}`; + } + } + + return ` +
    + + +
    + ${deleteUserButton}`; +} + async function changeUserEmail(uid) { const dom = $(`tr#user-${uid} > td:nth-child(2)`); let newUserEmail = ''; @@ -217,6 +334,7 @@ $('body').on('keypress', '.score', function(event){ if (process.env.NODE_ENV === 'test') { module.exports = { + initUsersTable, changeUserPwd, changeBanStatus, changeUserEmail, diff --git a/resources/assets/src/sass/admin.scss b/resources/assets/src/sass/admin.scss index 685f3627..d07c9126 100644 --- a/resources/assets/src/sass/admin.scss +++ b/resources/assets/src/sass/admin.scss @@ -24,6 +24,8 @@ td { img { margin-left: 10px; } + + cursor: pointer; } a:first-child > img { diff --git a/resources/lang/en/locale.js b/resources/lang/en/locale.js index 91040913..40665440 100644 --- a/resources/lang/en/locale.js +++ b/resources/lang/en/locale.js @@ -140,8 +140,8 @@ newUserPassword: 'Please enter the new password:', deleteUserNotice: 'Are you sure to delete this user? It\' permanent.', scoreTip: 'Press ENTER to submit new score', - doubleClickToSeeUser: 'Double click to see info of this user', - doubleClickToSeePlayers: 'Double click to see his/her players', + inspectHisOwner: 'Click to inspect the owner of this player', + inspectHisPlayers: 'Click to inspect the players he owns', // Status banned: 'Banned', diff --git a/resources/lang/zh_CN/locale.js b/resources/lang/zh_CN/locale.js index df98ee6a..860aa3ef 100644 --- a/resources/lang/zh_CN/locale.js +++ b/resources/lang/zh_CN/locale.js @@ -142,8 +142,8 @@ newUserPassword: '请输入新密码:', deleteUserNotice: '真的要删除此用户吗?此操作不可恢复', scoreTip: '输入修改后的积分,回车提交', - doubleClickToSeeUser: '双击可查看该用户的信息', - doubleClickToSeePlayers: '双击可查看该用户的角色', + inspectHisOwner: '点击查看该角色的所有者', + inspectHisPlayers: '点击查看该用户的角色', // Status banned: '封禁',