From 2471e6ec8df965d145c353354b5b354233da2754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Mon, 15 Feb 2021 11:36:59 +0100 Subject: [PATCH 1/2] MDL-70871 table: Add 'Show all X' functionality to dynamic_table --- lib/table/amd/build/dynamic.min.js | 2 +- lib/table/amd/build/dynamic.min.js.map | 2 +- .../amd/build/local/dynamic/selectors.min.js | 2 +- .../build/local/dynamic/selectors.min.js.map | 2 +- lib/table/amd/src/dynamic.js | 7 +++ lib/table/amd/src/local/dynamic/selectors.js | 5 ++ lib/tablelib.php | 54 ++++++++++++++++++- 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/lib/table/amd/build/dynamic.min.js b/lib/table/amd/build/dynamic.min.js index 2b10d71505c..99985ca5441 100644 --- a/lib/table/amd/build/dynamic.min.js +++ b/lib/table/amd/build/dynamic.min.js @@ -1,2 +1,2 @@ -function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_table/dynamic",["exports","core_table/local/dynamic/selectors","./local/dynamic/events","core/pending","core/loadingicon","core_table/local/dynamic/repository","core/notification"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});Object.defineProperty(a,"Events",{enumerable:!0,get:function get(){return c.default}});a.getTableFromId=a.init=a.showColumn=a.hideColumn=a.getLastInitial=a.setLastInitial=a.getFirstInitial=a.setFirstInitial=a.getPageSize=a.setPageSize=a.getPageNumber=a.setPageNumber=a.setSortOrder=a.getFilters=a.setFilters=a.updateTable=a.refreshTableContent=void 0;b=j(b);c=h(c);d=h(d);g=h(g);function h(a){return a&&a.__esModule?a:{default:a}}function i(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;i=function(){return a};return a}function j(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=i();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function k(a){return o(a)||n(a)||m(a)||l()}function l(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function m(a,b){if(!a)return;if("string"==typeof a)return p(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return p(a,b)}function n(a){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(a))return Array.from(a)}function o(a){if(Array.isArray(a))return p(a)}function p(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);ca.length)b=a.length;for(var c=0,d=Array(b);c.\n\n/**\n * Module to handle dynamic table features.\n *\n * @module core_table/dynamic\n * @package core_table\n * @copyright 2020 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as Selectors from 'core_table/local/dynamic/selectors';\nimport Events from './local/dynamic/events';\nimport Pending from 'core/pending';\nimport {addIconToContainer} from 'core/loadingicon';\nimport {fetch as fetchTableData} from 'core_table/local/dynamic/repository';\nimport Notification from 'core/notification';\n\nlet watching = false;\n\n/**\n * Ensure that a table is a dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Bool}\n */\nconst checkTableIsDynamic = tableRoot => {\n if (!tableRoot) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n if (!tableRoot.matches(Selectors.main.region)) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n return true;\n};\n\n/**\n * Get the filterset data from a known dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Object}\n */\nconst getFiltersetFromTable = tableRoot => {\n return JSON.parse(tableRoot.dataset.tableFilters);\n};\n\n/**\n * Update the specified table based on its current values.\n *\n * @param {HTMLElement} tableRoot\n * @param {Bool} resetContent\n * @returns {Promise}\n */\nexport const refreshTableContent = (tableRoot, resetContent = false) => {\n const filterset = getFiltersetFromTable(tableRoot);\n addIconToContainer(tableRoot);\n\n const pendingPromise = new Pending('core_table/dynamic:refreshTableContent');\n\n return fetchTableData(\n tableRoot.dataset.tableComponent,\n tableRoot.dataset.tableHandler,\n tableRoot.dataset.tableUniqueid,\n {\n sortData: JSON.parse(tableRoot.dataset.tableSortData),\n joinType: filterset.jointype,\n filters: filterset.filters,\n firstinitial: tableRoot.dataset.tableFirstInitial,\n lastinitial: tableRoot.dataset.tableLastInitial,\n pageNumber: tableRoot.dataset.tablePageNumber,\n pageSize: tableRoot.dataset.tablePageSize,\n hiddenColumns: JSON.parse(tableRoot.dataset.tableHiddenColumns),\n },\n resetContent,\n )\n .then(data => {\n const placeholder = document.createElement('div');\n placeholder.innerHTML = data.html;\n tableRoot.replaceWith(...placeholder.childNodes);\n\n // Update the tableRoot.\n return getTableFromId(tableRoot.dataset.tableUniqueid);\n }).then(tableRoot => {\n tableRoot.dispatchEvent(new CustomEvent(Events.tableContentRefreshed, {\n bubbles: true,\n }));\n\n return tableRoot;\n })\n .then(tableRoot => {\n pendingPromise.resolve();\n\n return tableRoot;\n });\n};\n\nexport const updateTable = (tableRoot, {\n sortBy = null,\n sortOrder = null,\n filters = null,\n firstInitial = null,\n lastInitial = null,\n pageNumber = null,\n pageSize = null,\n hiddenColumns = null,\n} = {}, refreshContent = true) => {\n checkTableIsDynamic(tableRoot);\n\n const pendingPromise = new Pending('core_table/dynamic:updateTable');\n let tableConfigChanged = false;\n\n // Update sort fields.\n if (sortBy && sortOrder) {\n // Always update the table if requested and there were sort fields.\n // These fields are only ever normalised in the backend.\n tableConfigChanged = true;\n\n const sortData = JSON.parse(tableRoot.dataset.tableSortData);\n sortData.unshift({\n sortby: sortBy,\n sortorder: parseInt(sortOrder, 10),\n });\n tableRoot.dataset.tableSortData = JSON.stringify(sortData);\n }\n\n // Update initials.\n if (firstInitial !== null) {\n if (tableRoot.dataset.tableFirstInitial !== firstInitial) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableFirstInitial = firstInitial;\n }\n\n if (lastInitial !== null) {\n if (tableRoot.dataset.tableLastInitial !== lastInitial) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableLastInitial = lastInitial;\n }\n\n if (pageSize !== null) {\n if (tableRoot.dataset.tablePageSize != pageSize) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tablePageSize = pageSize;\n }\n\n // Update filters.\n if (filters) {\n const filterJson = JSON.stringify(filters);\n\n if (tableRoot.dataset.tableFilters !== filterJson) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableFilters = filterJson;\n }\n\n // Reset to page 1 when table content is being altered by filtering or sorting.\n // This ensures the table page being loaded always exists, and gives a consistent experience.\n if (tableConfigChanged) {\n pageNumber = 1;\n }\n\n // Update hidden columns.\n if (hiddenColumns) {\n const columnJson = JSON.stringify(hiddenColumns);\n\n if (tableRoot.dataset.tableHiddenColumns !== columnJson) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableHiddenColumns = columnJson;\n }\n\n if (pageNumber !== null) {\n if (tableRoot.dataset.tablePageNumber != pageNumber) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tablePageNumber = pageNumber;\n }\n\n // Refresh.\n if (refreshContent && tableConfigChanged) {\n return refreshTableContent(tableRoot)\n .then(tableRoot => {\n pendingPromise.resolve();\n return tableRoot;\n });\n } else {\n pendingPromise.resolve();\n return Promise.resolve(tableRoot);\n }\n};\n\n/**\n * Get the table dataset for the specified tableRoot, ensuring that the provided table is a dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {DOMStringMap}\n */\nconst getTableData = tableRoot => {\n checkTableIsDynamic(tableRoot);\n\n return tableRoot.dataset;\n};\n\n/**\n * Update the specified table using the new filters.\n *\n * @param {HTMLElement} tableRoot\n * @param {Object} filters\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setFilters = (tableRoot, filters, refreshContent = true) =>\n updateTable(tableRoot, {filters}, refreshContent);\n\n/**\n * Get the filter data for the specified table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Object}\n */\nexport const getFilters = tableRoot => {\n checkTableIsDynamic(tableRoot);\n\n return getFiltersetFromTable(tableRoot);\n};\n\n/**\n * Update the sort order.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} sortBy\n * @param {Number} sortOrder\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setSortOrder = (tableRoot, sortBy, sortOrder, refreshContent = true) =>\n updateTable(tableRoot, {sortBy, sortOrder}, refreshContent);\n\n/**\n * Set the page number.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} pageNumber\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setPageNumber = (tableRoot, pageNumber, refreshContent = true) =>\n updateTable(tableRoot, {pageNumber}, refreshContent);\n\n/**\n * Get the current page number.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Number}\n */\nexport const getPageNumber = tableRoot => getTableData(tableRoot).tablePageNumber;\n\n/**\n * Set the page size.\n *\n * @param {HTMLElement} tableRoot\n * @param {Number} pageSize\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setPageSize = (tableRoot, pageSize, refreshContent = true) =>\n updateTable(tableRoot, {pageSize, pageNumber: 1}, refreshContent);\n\n/**\n * Get the current page size.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Number}\n */\nexport const getPageSize = tableRoot => getTableData(tableRoot).tablePageSize;\n\n/**\n * Update the first initial to show.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} firstInitial\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setFirstInitial = (tableRoot, firstInitial, refreshContent = true) =>\n updateTable(tableRoot, {firstInitial}, refreshContent);\n\n/**\n * Get the current first initial filter.\n *\n * @param {HTMLElement} tableRoot\n * @returns {String}\n */\nexport const getFirstInitial = tableRoot => getTableData(tableRoot).tableFirstInitial;\n\n/**\n * Update the last initial to show.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} lastInitial\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setLastInitial = (tableRoot, lastInitial, refreshContent = true) =>\n updateTable(tableRoot, {lastInitial}, refreshContent);\n\n/**\n * Get the current last initial filter.\n *\n * @param {HTMLElement} tableRoot\n * @returns {String}\n */\nexport const getLastInitial = tableRoot => getTableData(tableRoot).tableLastInitial;\n\n/**\n * Hide a column in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToHide\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const hideColumn = (tableRoot, columnToHide, refreshContent = true) => {\n const hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns.push(columnToHide);\n\n return updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\n\n/**\n * Make a hidden column visible in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToShow\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const showColumn = (tableRoot, columnToShow, refreshContent = true) => {\n let hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns = hiddenColumns.filter(columnName => columnName !== columnToShow);\n\n return updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\n\n/**\n * Reset table preferences.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Promise}\n */\nconst resetTablePreferences = tableRoot => refreshTableContent(tableRoot, true);\n\n/**\n * Set up listeners to handle table updates.\n */\nexport const init = () => {\n if (watching) {\n // Already watching.\n return;\n }\n watching = true;\n\n document.addEventListener('click', e => {\n const tableRoot = e.target.closest(Selectors.main.region);\n\n if (!tableRoot) {\n return;\n }\n\n const sortableLink = e.target.closest(Selectors.table.links.sortableColumn);\n if (sortableLink) {\n e.preventDefault();\n\n setSortOrder(tableRoot, sortableLink.dataset.sortby, sortableLink.dataset.sortorder)\n .catch(Notification.exception);\n }\n\n const firstInitialLink = e.target.closest(Selectors.initialsBar.links.firstInitial);\n if (firstInitialLink !== null) {\n e.preventDefault();\n\n setFirstInitial(tableRoot, firstInitialLink.dataset.initial).catch(Notification.exception);\n }\n\n const lastInitialLink = e.target.closest(Selectors.initialsBar.links.lastInitial);\n if (lastInitialLink !== null) {\n e.preventDefault();\n\n setLastInitial(tableRoot, lastInitialLink.dataset.initial).catch(Notification.exception);\n }\n\n const pageItem = e.target.closest(Selectors.paginationBar.links.pageItem);\n if (pageItem) {\n e.preventDefault();\n\n setPageNumber(tableRoot, pageItem.dataset.pageNumber).catch(Notification.exception);\n }\n\n const hide = e.target.closest(Selectors.table.links.hide);\n if (hide) {\n e.preventDefault();\n\n hideColumn(tableRoot, hide.dataset.column).catch(Notification.exception);\n }\n\n const show = e.target.closest(Selectors.table.links.show);\n if (show) {\n e.preventDefault();\n\n showColumn(tableRoot, show.dataset.column).catch(Notification.exception);\n }\n\n const resetTablePreferencesLink = e.target.closest('.resettable a');\n if (resetTablePreferencesLink) {\n e.preventDefault();\n\n resetTablePreferences(tableRoot).catch(Notification.exception);\n }\n });\n};\n\n/**\n * Fetch the table via its table region id.\n *\n * @param {String} tableRegionId\n * @returns {HTMLElement}\n */\nexport const getTableFromId = tableRegionId => {\n const tableRoot = document.querySelector(Selectors.main.fromRegionId(tableRegionId));\n\n\n if (!tableRoot) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n return tableRoot;\n};\n\nexport {\n Events\n};\n"],"file":"dynamic.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/dynamic.js"],"names":["watching","checkTableIsDynamic","tableRoot","Error","matches","Selectors","main","region","getFiltersetFromTable","JSON","parse","dataset","tableFilters","refreshTableContent","resetContent","filterset","pendingPromise","Pending","tableComponent","tableHandler","tableUniqueid","sortData","tableSortData","joinType","jointype","filters","firstinitial","tableFirstInitial","lastinitial","tableLastInitial","pageNumber","tablePageNumber","pageSize","tablePageSize","hiddenColumns","tableHiddenColumns","then","data","placeholder","document","createElement","innerHTML","html","replaceWith","childNodes","getTableFromId","dispatchEvent","CustomEvent","Events","tableContentRefreshed","bubbles","resolve","updateTable","sortBy","sortOrder","firstInitial","lastInitial","refreshContent","tableConfigChanged","unshift","sortby","sortorder","parseInt","stringify","filterJson","columnJson","Promise","getTableData","setFilters","getFilters","setSortOrder","setPageNumber","getPageNumber","setPageSize","getPageSize","setFirstInitial","getFirstInitial","setLastInitial","getLastInitial","hideColumn","columnToHide","push","showColumn","columnToShow","filter","columnName","resetTablePreferences","init","addEventListener","e","target","closest","sortableLink","table","links","sortableColumn","preventDefault","catch","Notification","exception","firstInitialLink","initialsBar","initial","lastInitialLink","pageItem","paginationBar","hide","column","show","resetTablePreferencesLink","showCountLink","showCount","toggle","targetPageSize","tableRegionId","querySelector","fromRegionId"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Module to handle dynamic table features.\n *\n * @module core_table/dynamic\n * @package core_table\n * @copyright 2020 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as Selectors from 'core_table/local/dynamic/selectors';\nimport Events from './local/dynamic/events';\nimport Pending from 'core/pending';\nimport {addIconToContainer} from 'core/loadingicon';\nimport {fetch as fetchTableData} from 'core_table/local/dynamic/repository';\nimport Notification from 'core/notification';\n\nlet watching = false;\n\n/**\n * Ensure that a table is a dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Bool}\n */\nconst checkTableIsDynamic = tableRoot => {\n if (!tableRoot) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n if (!tableRoot.matches(Selectors.main.region)) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n return true;\n};\n\n/**\n * Get the filterset data from a known dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Object}\n */\nconst getFiltersetFromTable = tableRoot => {\n return JSON.parse(tableRoot.dataset.tableFilters);\n};\n\n/**\n * Update the specified table based on its current values.\n *\n * @param {HTMLElement} tableRoot\n * @param {Bool} resetContent\n * @returns {Promise}\n */\nexport const refreshTableContent = (tableRoot, resetContent = false) => {\n const filterset = getFiltersetFromTable(tableRoot);\n addIconToContainer(tableRoot);\n\n const pendingPromise = new Pending('core_table/dynamic:refreshTableContent');\n\n return fetchTableData(\n tableRoot.dataset.tableComponent,\n tableRoot.dataset.tableHandler,\n tableRoot.dataset.tableUniqueid,\n {\n sortData: JSON.parse(tableRoot.dataset.tableSortData),\n joinType: filterset.jointype,\n filters: filterset.filters,\n firstinitial: tableRoot.dataset.tableFirstInitial,\n lastinitial: tableRoot.dataset.tableLastInitial,\n pageNumber: tableRoot.dataset.tablePageNumber,\n pageSize: tableRoot.dataset.tablePageSize,\n hiddenColumns: JSON.parse(tableRoot.dataset.tableHiddenColumns),\n },\n resetContent,\n )\n .then(data => {\n const placeholder = document.createElement('div');\n placeholder.innerHTML = data.html;\n tableRoot.replaceWith(...placeholder.childNodes);\n\n // Update the tableRoot.\n return getTableFromId(tableRoot.dataset.tableUniqueid);\n }).then(tableRoot => {\n tableRoot.dispatchEvent(new CustomEvent(Events.tableContentRefreshed, {\n bubbles: true,\n }));\n\n return tableRoot;\n })\n .then(tableRoot => {\n pendingPromise.resolve();\n\n return tableRoot;\n });\n};\n\nexport const updateTable = (tableRoot, {\n sortBy = null,\n sortOrder = null,\n filters = null,\n firstInitial = null,\n lastInitial = null,\n pageNumber = null,\n pageSize = null,\n hiddenColumns = null,\n} = {}, refreshContent = true) => {\n checkTableIsDynamic(tableRoot);\n\n const pendingPromise = new Pending('core_table/dynamic:updateTable');\n let tableConfigChanged = false;\n\n // Update sort fields.\n if (sortBy && sortOrder) {\n // Always update the table if requested and there were sort fields.\n // These fields are only ever normalised in the backend.\n tableConfigChanged = true;\n\n const sortData = JSON.parse(tableRoot.dataset.tableSortData);\n sortData.unshift({\n sortby: sortBy,\n sortorder: parseInt(sortOrder, 10),\n });\n tableRoot.dataset.tableSortData = JSON.stringify(sortData);\n }\n\n // Update initials.\n if (firstInitial !== null) {\n if (tableRoot.dataset.tableFirstInitial !== firstInitial) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableFirstInitial = firstInitial;\n }\n\n if (lastInitial !== null) {\n if (tableRoot.dataset.tableLastInitial !== lastInitial) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableLastInitial = lastInitial;\n }\n\n if (pageSize !== null) {\n if (tableRoot.dataset.tablePageSize != pageSize) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tablePageSize = pageSize;\n }\n\n // Update filters.\n if (filters) {\n const filterJson = JSON.stringify(filters);\n\n if (tableRoot.dataset.tableFilters !== filterJson) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableFilters = filterJson;\n }\n\n // Reset to page 1 when table content is being altered by filtering or sorting.\n // This ensures the table page being loaded always exists, and gives a consistent experience.\n if (tableConfigChanged) {\n pageNumber = 1;\n }\n\n // Update hidden columns.\n if (hiddenColumns) {\n const columnJson = JSON.stringify(hiddenColumns);\n\n if (tableRoot.dataset.tableHiddenColumns !== columnJson) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tableHiddenColumns = columnJson;\n }\n\n if (pageNumber !== null) {\n if (tableRoot.dataset.tablePageNumber != pageNumber) {\n tableConfigChanged = true;\n }\n\n tableRoot.dataset.tablePageNumber = pageNumber;\n }\n\n // Refresh.\n if (refreshContent && tableConfigChanged) {\n return refreshTableContent(tableRoot)\n .then(tableRoot => {\n pendingPromise.resolve();\n return tableRoot;\n });\n } else {\n pendingPromise.resolve();\n return Promise.resolve(tableRoot);\n }\n};\n\n/**\n * Get the table dataset for the specified tableRoot, ensuring that the provided table is a dynamic table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {DOMStringMap}\n */\nconst getTableData = tableRoot => {\n checkTableIsDynamic(tableRoot);\n\n return tableRoot.dataset;\n};\n\n/**\n * Update the specified table using the new filters.\n *\n * @param {HTMLElement} tableRoot\n * @param {Object} filters\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setFilters = (tableRoot, filters, refreshContent = true) =>\n updateTable(tableRoot, {filters}, refreshContent);\n\n/**\n * Get the filter data for the specified table.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Object}\n */\nexport const getFilters = tableRoot => {\n checkTableIsDynamic(tableRoot);\n\n return getFiltersetFromTable(tableRoot);\n};\n\n/**\n * Update the sort order.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} sortBy\n * @param {Number} sortOrder\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setSortOrder = (tableRoot, sortBy, sortOrder, refreshContent = true) =>\n updateTable(tableRoot, {sortBy, sortOrder}, refreshContent);\n\n/**\n * Set the page number.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} pageNumber\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setPageNumber = (tableRoot, pageNumber, refreshContent = true) =>\n updateTable(tableRoot, {pageNumber}, refreshContent);\n\n/**\n * Get the current page number.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Number}\n */\nexport const getPageNumber = tableRoot => getTableData(tableRoot).tablePageNumber;\n\n/**\n * Set the page size.\n *\n * @param {HTMLElement} tableRoot\n * @param {Number} pageSize\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setPageSize = (tableRoot, pageSize, refreshContent = true) =>\n updateTable(tableRoot, {pageSize, pageNumber: 1}, refreshContent);\n\n/**\n * Get the current page size.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Number}\n */\nexport const getPageSize = tableRoot => getTableData(tableRoot).tablePageSize;\n\n/**\n * Update the first initial to show.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} firstInitial\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setFirstInitial = (tableRoot, firstInitial, refreshContent = true) =>\n updateTable(tableRoot, {firstInitial}, refreshContent);\n\n/**\n * Get the current first initial filter.\n *\n * @param {HTMLElement} tableRoot\n * @returns {String}\n */\nexport const getFirstInitial = tableRoot => getTableData(tableRoot).tableFirstInitial;\n\n/**\n * Update the last initial to show.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} lastInitial\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const setLastInitial = (tableRoot, lastInitial, refreshContent = true) =>\n updateTable(tableRoot, {lastInitial}, refreshContent);\n\n/**\n * Get the current last initial filter.\n *\n * @param {HTMLElement} tableRoot\n * @returns {String}\n */\nexport const getLastInitial = tableRoot => getTableData(tableRoot).tableLastInitial;\n\n/**\n * Hide a column in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToHide\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const hideColumn = (tableRoot, columnToHide, refreshContent = true) => {\n const hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns.push(columnToHide);\n\n return updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\n\n/**\n * Make a hidden column visible in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToShow\n * @param {Bool} refreshContent\n * @returns {Promise}\n */\nexport const showColumn = (tableRoot, columnToShow, refreshContent = true) => {\n let hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns = hiddenColumns.filter(columnName => columnName !== columnToShow);\n\n return updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\n\n/**\n * Reset table preferences.\n *\n * @param {HTMLElement} tableRoot\n * @returns {Promise}\n */\nconst resetTablePreferences = tableRoot => refreshTableContent(tableRoot, true);\n\n/**\n * Set up listeners to handle table updates.\n */\nexport const init = () => {\n if (watching) {\n // Already watching.\n return;\n }\n watching = true;\n\n document.addEventListener('click', e => {\n const tableRoot = e.target.closest(Selectors.main.region);\n\n if (!tableRoot) {\n return;\n }\n\n const sortableLink = e.target.closest(Selectors.table.links.sortableColumn);\n if (sortableLink) {\n e.preventDefault();\n\n setSortOrder(tableRoot, sortableLink.dataset.sortby, sortableLink.dataset.sortorder)\n .catch(Notification.exception);\n }\n\n const firstInitialLink = e.target.closest(Selectors.initialsBar.links.firstInitial);\n if (firstInitialLink !== null) {\n e.preventDefault();\n\n setFirstInitial(tableRoot, firstInitialLink.dataset.initial).catch(Notification.exception);\n }\n\n const lastInitialLink = e.target.closest(Selectors.initialsBar.links.lastInitial);\n if (lastInitialLink !== null) {\n e.preventDefault();\n\n setLastInitial(tableRoot, lastInitialLink.dataset.initial).catch(Notification.exception);\n }\n\n const pageItem = e.target.closest(Selectors.paginationBar.links.pageItem);\n if (pageItem) {\n e.preventDefault();\n\n setPageNumber(tableRoot, pageItem.dataset.pageNumber).catch(Notification.exception);\n }\n\n const hide = e.target.closest(Selectors.table.links.hide);\n if (hide) {\n e.preventDefault();\n\n hideColumn(tableRoot, hide.dataset.column).catch(Notification.exception);\n }\n\n const show = e.target.closest(Selectors.table.links.show);\n if (show) {\n e.preventDefault();\n\n showColumn(tableRoot, show.dataset.column).catch(Notification.exception);\n }\n\n const resetTablePreferencesLink = e.target.closest('.resettable a');\n if (resetTablePreferencesLink) {\n e.preventDefault();\n\n resetTablePreferences(tableRoot).catch(Notification.exception);\n }\n\n const showCountLink = e.target.closest(Selectors.showCount.links.toggle);\n if (showCountLink) {\n e.preventDefault();\n\n setPageSize(tableRoot, showCountLink.dataset.targetPageSize).catch(Notification.exception);\n }\n });\n};\n\n/**\n * Fetch the table via its table region id.\n *\n * @param {String} tableRegionId\n * @returns {HTMLElement}\n */\nexport const getTableFromId = tableRegionId => {\n const tableRoot = document.querySelector(Selectors.main.fromRegionId(tableRegionId));\n\n\n if (!tableRoot) {\n // The table is not a dynamic table.\n throw new Error(\"The table specified is not a dynamic table and cannot be updated\");\n }\n\n return tableRoot;\n};\n\nexport {\n Events\n};\n"],"file":"dynamic.min.js"} \ No newline at end of file diff --git a/lib/table/amd/build/local/dynamic/selectors.min.js b/lib/table/amd/build/local/dynamic/selectors.min.js index d250c63efff..bae6b415122 100644 --- a/lib/table/amd/build/local/dynamic/selectors.min.js +++ b/lib/table/amd/build/local/dynamic/selectors.min.js @@ -1,2 +1,2 @@ -define ("core_table/local/dynamic/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={main:{region:"[data-region=\"core_table/dynamic\"]",fromRegionId:function fromRegionId(a){return"[data-region=\"core_table/dynamic\"][data-table-uniqueid=\"".concat(a,"\"]")}},table:{links:{sortableColumn:"a[data-sortable=\"1\"]",hide:"a[data-action=\"hide\"]",show:"a[data-action=\"show\"]"}},initialsBar:{links:{firstInitial:".firstinitial [data-initial]",lastInitial:".lastinitial [data-initial]"}},paginationBar:{links:{pageItem:".pagination [data-page-number]"}}};return a.default}); +define ("core_table/local/dynamic/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={main:{region:"[data-region=\"core_table/dynamic\"]",fromRegionId:function fromRegionId(a){return"[data-region=\"core_table/dynamic\"][data-table-uniqueid=\"".concat(a,"\"]")}},table:{links:{sortableColumn:"a[data-sortable=\"1\"]",hide:"a[data-action=\"hide\"]",show:"a[data-action=\"show\"]"}},initialsBar:{links:{firstInitial:".firstinitial [data-initial]",lastInitial:".lastinitial [data-initial]"}},paginationBar:{links:{pageItem:".pagination [data-page-number]"}},showCount:{links:{toggle:"[data-action=\"showcount\"]"}}};return a.default}); //# sourceMappingURL=selectors.min.js.map diff --git a/lib/table/amd/build/local/dynamic/selectors.min.js.map b/lib/table/amd/build/local/dynamic/selectors.min.js.map index 4e7d1022b19..5d414e405d0 100644 --- a/lib/table/amd/build/local/dynamic/selectors.min.js.map +++ b/lib/table/amd/build/local/dynamic/selectors.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/local/dynamic/selectors.js"],"names":["main","region","fromRegionId","regionId","table","links","sortableColumn","hide","show","initialsBar","firstInitial","lastInitial","paginationBar","pageItem"],"mappings":"8JAuBe,CACXA,IAAI,CAAE,CACFC,MAAM,CAAE,sCADN,CAEFC,YAAY,CAAE,sBAAAC,CAAQ,6EAA+DA,CAA/D,QAFpB,CADK,CAKXC,KAAK,CAAE,CACHC,KAAK,CAAE,CACHC,cAAc,CAAE,wBADb,CAEHC,IAAI,CAAE,yBAFH,CAGHC,IAAI,CAAE,yBAHH,CADJ,CALI,CAYXC,WAAW,CAAE,CACTJ,KAAK,CAAE,CACHK,YAAY,CAAE,8BADX,CAEHC,WAAW,CAAE,6BAFV,CADE,CAZF,CAkBXC,aAAa,CAAE,CACXP,KAAK,CAAE,CACHQ,QAAQ,CAAE,gCADP,CADI,CAlBJ,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Dynamic table selectors.\n *\n * @module core_table/selectors\n * @package core_table\n * @copyright 2020 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default {\n main: {\n region: '[data-region=\"core_table/dynamic\"]',\n fromRegionId: regionId => `[data-region=\"core_table/dynamic\"][data-table-uniqueid=\"${regionId}\"]`,\n },\n table: {\n links: {\n sortableColumn: 'a[data-sortable=\"1\"]',\n hide: 'a[data-action=\"hide\"]',\n show: 'a[data-action=\"show\"]',\n },\n },\n initialsBar: {\n links: {\n firstInitial: '.firstinitial [data-initial]',\n lastInitial: '.lastinitial [data-initial]',\n },\n },\n paginationBar: {\n links: {\n pageItem: '.pagination [data-page-number]'\n }\n },\n};\n"],"file":"selectors.min.js"} \ No newline at end of file +{"version":3,"sources":["../../../src/local/dynamic/selectors.js"],"names":["main","region","fromRegionId","regionId","table","links","sortableColumn","hide","show","initialsBar","firstInitial","lastInitial","paginationBar","pageItem","showCount","toggle"],"mappings":"8JAuBe,CACXA,IAAI,CAAE,CACFC,MAAM,CAAE,sCADN,CAEFC,YAAY,CAAE,sBAAAC,CAAQ,6EAA+DA,CAA/D,QAFpB,CADK,CAKXC,KAAK,CAAE,CACHC,KAAK,CAAE,CACHC,cAAc,CAAE,wBADb,CAEHC,IAAI,CAAE,yBAFH,CAGHC,IAAI,CAAE,yBAHH,CADJ,CALI,CAYXC,WAAW,CAAE,CACTJ,KAAK,CAAE,CACHK,YAAY,CAAE,8BADX,CAEHC,WAAW,CAAE,6BAFV,CADE,CAZF,CAkBXC,aAAa,CAAE,CACXP,KAAK,CAAE,CACHQ,QAAQ,CAAE,gCADP,CADI,CAlBJ,CAuBXC,SAAS,CAAE,CACPT,KAAK,CAAE,CACHU,MAAM,CAAE,6BADL,CADA,CAvBA,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Dynamic table selectors.\n *\n * @module core_table/selectors\n * @package core_table\n * @copyright 2020 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default {\n main: {\n region: '[data-region=\"core_table/dynamic\"]',\n fromRegionId: regionId => `[data-region=\"core_table/dynamic\"][data-table-uniqueid=\"${regionId}\"]`,\n },\n table: {\n links: {\n sortableColumn: 'a[data-sortable=\"1\"]',\n hide: 'a[data-action=\"hide\"]',\n show: 'a[data-action=\"show\"]',\n },\n },\n initialsBar: {\n links: {\n firstInitial: '.firstinitial [data-initial]',\n lastInitial: '.lastinitial [data-initial]',\n },\n },\n paginationBar: {\n links: {\n pageItem: '.pagination [data-page-number]'\n }\n },\n showCount: {\n links: {\n toggle: '[data-action=\"showcount\"]',\n },\n },\n};\n"],"file":"selectors.min.js"} \ No newline at end of file diff --git a/lib/table/amd/src/dynamic.js b/lib/table/amd/src/dynamic.js index 1004a8e83fc..5c8f3dc28df 100644 --- a/lib/table/amd/src/dynamic.js +++ b/lib/table/amd/src/dynamic.js @@ -440,6 +440,13 @@ export const init = () => { resetTablePreferences(tableRoot).catch(Notification.exception); } + + const showCountLink = e.target.closest(Selectors.showCount.links.toggle); + if (showCountLink) { + e.preventDefault(); + + setPageSize(tableRoot, showCountLink.dataset.targetPageSize).catch(Notification.exception); + } }); }; diff --git a/lib/table/amd/src/local/dynamic/selectors.js b/lib/table/amd/src/local/dynamic/selectors.js index 64c75549653..3d0699bc52a 100644 --- a/lib/table/amd/src/local/dynamic/selectors.js +++ b/lib/table/amd/src/local/dynamic/selectors.js @@ -44,4 +44,9 @@ export default { pageItem: '.pagination [data-page-number]' } }, + showCount: { + links: { + toggle: '[data-action="showcount"]', + }, + }, }; diff --git a/lib/tablelib.php b/lib/tablelib.php index 37b8ee5538c..b9a16407cb9 100644 --- a/lib/tablelib.php +++ b/lib/tablelib.php @@ -46,6 +46,11 @@ define('TABLE_P_TOP', 1); define('TABLE_P_BOTTOM', 2); /**#@-*/ +/** + * Constant that defines the 'Show all' page size. + */ +define('TABLE_SHOW_ALL_PAGE_SIZE', 5000); + use core_table\local\filter\filterset; /** @@ -108,6 +113,9 @@ class flexible_table { var $sort_default_column = NULL; var $sort_default_order = SORT_ASC; + /** @var integer The defeult per page size for the table. */ + private $defaultperpage = 30; + /** * Array of positions in which to display download controls. */ @@ -1507,6 +1515,24 @@ class flexible_table { } } + /** + * Get the default per page. + * + * @return int + */ + public function get_default_per_page(): int { + return $this->defaultperpage; + } + + /** + * Set the default per page. + * + * @param int $defaultperpage + */ + public function set_default_per_page(int $defaultperpage): void { + $this->defaultperpage = $defaultperpage; + } + /** * Set the preferred first name initial in an initials bar. * @@ -1678,6 +1704,7 @@ class flexible_table { 'data-table-last-initial' => $this->prefs['i_last'], 'data-table-page-number' => $this->currpage + 1, 'data-table-page-size' => $this->pagesize, + 'data-table-default-per-page' => $this->get_default_per_page(), 'data-table-hidden-columns' => json_encode(array_keys($this->prefs['collapse'])), 'data-table-total-rows' => $this->totalrows, ]); @@ -1696,8 +1723,33 @@ class flexible_table { global $PAGE; if (is_a($this, \core_table\dynamic::class)) { + $output = ''; + + $perpageurl = new moodle_url($PAGE->url); + + // Generate "Show all/Show per page" link. + if ($this->pagesize == TABLE_SHOW_ALL_PAGE_SIZE && $this->totalrows > $this->get_default_per_page()) { + $perpagesize = $this->get_default_per_page(); + $perpagestring = get_string('showperpage', '', $this->get_default_per_page()); + } else if ($this->pagesize < $this->totalrows) { + $perpagesize = TABLE_SHOW_ALL_PAGE_SIZE; + $perpagestring = get_string('showall', '', $this->totalrows); + } + if (isset($perpagesize) && isset($perpagestring)) { + $perpageurl->param('perpage', $perpagesize); + $output .= html_writer::link( + $perpageurl, + $perpagestring, + [ + 'data-action' => 'showcount', + 'data-target-page-size' => $perpagesize, + ] + ); + } + $PAGE->requires->js_call_amd('core_table/dynamic', 'init'); - return html_writer::end_tag('div'); + $output .= html_writer::end_tag('div'); + return $output; } return ''; From 8de59fc435cd5959464fdcb1d6365b6cfee415e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Mon, 15 Feb 2021 12:09:28 +0100 Subject: [PATCH 2/2] MDL-70871 user: Move 'Show all X' functionality to dynamic_table --- user/amd/build/participants.min.js | 2 +- user/amd/build/participants.min.js.map | 2 +- user/amd/src/participants.js | 47 ++++---------------------- user/classes/table/participants.php | 2 ++ user/index.php | 38 +-------------------- 5 files changed, 12 insertions(+), 79 deletions(-) diff --git a/user/amd/build/participants.min.js b/user/amd/build/participants.min.js index 071682ec3a7..0a8e5cdb191 100644 --- a/user/amd/build/participants.min.js +++ b/user/amd/build/participants.min.js @@ -1,2 +1,2 @@ -function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_user/participants",["exports","core_table/dynamic","core/str","core/checkbox-toggleall","core/custom_interaction_events","core_table/local/dynamic/selectors","core/modal_events","core/notification","core/pending","jquery","core_user/local/participants/bulkactions"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=n(b);c=n(c);d=l(d);e=l(e);f=l(f);g=l(g);h=l(h);i=l(i);j=l(j);function l(a){return a&&a.__esModule?a:{default:a}}function m(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;m=function(){return a};return a}function n(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=m();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function o(a,b){return t(a)||s(a,b)||q(a,b)||p()}function p(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function q(a,b){if(!a)return;if("string"==typeof a)return r(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return r(a,b)}function r(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);ca.length)b=a.length;for(var c=0,d=Array(b);c.\n\n/**\n * Some UI stuff for participants page.\n * This is also used by the report/participants/index.php because it has the same functionality.\n *\n * @module core_user/participants\n * @package core_user\n * @copyright 2017 Damyon Wiese\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as DynamicTable from 'core_table/dynamic';\nimport * as Str from 'core/str';\nimport CheckboxToggleAll from 'core/checkbox-toggleall';\nimport CustomEvents from 'core/custom_interaction_events';\nimport DynamicTableSelectors from 'core_table/local/dynamic/selectors';\nimport ModalEvents from 'core/modal_events';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport jQuery from 'jquery';\nimport {showAddNote, showSendMessage} from 'core_user/local/participants/bulkactions';\n\nconst Selectors = {\n bulkActionSelect: \"#formactionid\",\n bulkUserSelectedCheckBoxes: \"input[data-togglegroup='participants-table'][data-toggle='slave']:checked\",\n checkCountButton: \"#checkall\",\n showCountText: '[data-region=\"participant-count\"]',\n showCountToggle: '[data-action=\"showcount\"]',\n stateHelpIcon: '[data-region=\"state-help-icon\"]',\n tableForm: uniqueId => `form[data-table-unique-id=\"${uniqueId}\"]`,\n};\n\nexport const init = ({\n uniqueid,\n noteStateNames = {},\n}) => {\n const root = document.querySelector(Selectors.tableForm(uniqueid));\n const getTableFromUniqueId = uniqueId => root.querySelector(DynamicTableSelectors.main.fromRegionId(uniqueId));\n\n /**\n * Private method.\n *\n * @method registerEventListeners\n * @private\n */\n const registerEventListeners = () => {\n CustomEvents.define(Selectors.bulkActionSelect, [CustomEvents.events.accessibleChange]);\n jQuery(Selectors.bulkActionSelect).on(CustomEvents.events.accessibleChange, e => {\n const bulkActionSelect = e.target.closest('select');\n const action = bulkActionSelect.value;\n const tableRoot = getTableFromUniqueId(uniqueid);\n const checkboxes = tableRoot.querySelectorAll(Selectors.bulkUserSelectedCheckBoxes);\n const pendingPromise = new Pending('core_user/participants:bulkActionSelect');\n\n if (action.indexOf('#') !== -1) {\n e.preventDefault();\n\n const ids = [];\n checkboxes.forEach(checkbox => {\n ids.push(checkbox.getAttribute('name').replace('user', ''));\n });\n\n let bulkAction;\n if (action === '#messageselect') {\n bulkAction = showSendMessage(ids);\n } else if (action === '#addgroupnote') {\n bulkAction = showAddNote(\n root.dataset.courseId,\n ids,\n noteStateNames,\n root.querySelector(Selectors.stateHelpIcon)\n );\n }\n\n if (bulkAction) {\n const pendingBulkAction = new Pending('core_user/participants:bulkActionSelected');\n bulkAction\n .then(modal => {\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Focus on the action select when the dialog is closed.\n bulkActionSelect.focus();\n });\n\n pendingBulkAction.resolve();\n return modal;\n })\n .catch(Notification.exception);\n }\n } else if (action !== '' && checkboxes.length) {\n bulkActionSelect.form.submit();\n }\n\n resetBulkAction(bulkActionSelect);\n pendingPromise.resolve();\n });\n\n root.addEventListener('click', e => {\n // Handle clicking of the \"Show [all|count]\" and \"Select all\" actions.\n const showCountLink = root.querySelector(Selectors.showCountToggle);\n const checkCountButton = root.querySelector(Selectors.checkCountButton);\n\n const showCountLinkClicked = showCountLink && showCountLink.contains(e.target);\n const checkCountButtonClicked = checkCountButton && checkCountButton.contains(e.target);\n\n if (showCountLinkClicked || checkCountButtonClicked) {\n e.preventDefault();\n\n const tableRoot = getTableFromUniqueId(uniqueid);\n\n DynamicTable.setPageSize(tableRoot, showCountLink.dataset.targetPageSize)\n .then(tableRoot => {\n // Always update the toggle state.\n // This ensures that the bulk actions are disabled after changing the page size.\n CheckboxToggleAll.setGroupState(root, 'participants-table', checkCountButtonClicked);\n\n return tableRoot;\n })\n .catch(Notification.exception);\n }\n });\n\n // When the content is refreshed, update the row counts in various places.\n root.addEventListener(DynamicTable.Events.tableContentRefreshed, e => {\n const showCountLink = root.querySelector(Selectors.showCountToggle);\n const checkCountButton = root.querySelector(Selectors.checkCountButton);\n\n const tableRoot = e.target;\n\n const defaultPageSize = parseInt(root.dataset.tableDefaultPerPage, 10);\n const currentPageSize = parseInt(tableRoot.dataset.tablePageSize, 10);\n const totalRowCount = parseInt(tableRoot.dataset.tableTotalRows, 10);\n\n CheckboxToggleAll.updateSlavesFromMasterState(root, 'participants-table');\n\n const pageCountStrings = [\n {\n key: 'countparticipantsfound',\n component: 'core_user',\n param: totalRowCount,\n },\n ];\n\n\n if (totalRowCount <= defaultPageSize) {\n // There are fewer than the default page count numbers of rows.\n showCountLink.classList.add('hidden');\n\n if (checkCountButton) {\n checkCountButton.classList.add('hidden');\n }\n } else if (totalRowCount <= currentPageSize) {\n // The are fewer than the current page size.\n pageCountStrings.push({\n key: 'showperpage',\n component: 'core',\n param: defaultPageSize,\n });\n\n pageCountStrings.push({\n key: 'selectalluserswithcount',\n component: 'core',\n param: defaultPageSize,\n });\n\n // Show the 'Show [x]' link.\n showCountLink.classList.remove('hidden');\n showCountLink.dataset.targetPageSize = defaultPageSize;\n\n if (checkCountButton) {\n // The 'Check all [x]' button is only visible when there are values to set.\n checkCountButton.classList.add('hidden');\n }\n } else {\n pageCountStrings.push({\n key: 'showall',\n component: 'core',\n param: totalRowCount,\n });\n\n pageCountStrings.push({\n key: 'selectalluserswithcount',\n component: 'core',\n param: totalRowCount,\n });\n\n // Show both the 'Show [x]' link, and the 'Check all [x]' button.\n showCountLink.classList.remove('hidden');\n showCountLink.dataset.targetPageSize = totalRowCount;\n\n if (checkCountButton) {\n checkCountButton.classList.remove('hidden');\n }\n }\n\n Str.get_strings(pageCountStrings)\n .then(([showingParticipantCountString, showCountString, selectCountString]) => {\n const showingParticipantCount = root.querySelector(Selectors.showCountText);\n showingParticipantCount.innerHTML = showingParticipantCountString;\n\n if (showCountString) {\n showCountLink.innerHTML = showCountString;\n }\n\n if (selectCountString && checkCountButton) {\n checkCountButton.value = selectCountString;\n }\n\n return;\n })\n .catch(Notification.exception);\n });\n };\n\n const resetBulkAction = bulkActionSelect => {\n bulkActionSelect.value = '';\n };\n\n registerEventListeners();\n};\n"],"file":"participants.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/participants.js"],"names":["Selectors","bulkActionSelect","bulkUserSelectedCheckBoxes","checkCountButton","showCountText","showCountToggle","stateHelpIcon","tableForm","uniqueId","init","uniqueid","noteStateNames","root","document","querySelector","getTableFromUniqueId","DynamicTableSelectors","main","fromRegionId","registerEventListeners","CustomEvents","define","events","accessibleChange","on","e","target","closest","action","value","tableRoot","checkboxes","querySelectorAll","pendingPromise","Pending","indexOf","preventDefault","ids","forEach","checkbox","push","getAttribute","replace","bulkAction","dataset","courseId","pendingBulkAction","then","modal","getRoot","ModalEvents","hidden","focus","resolve","catch","Notification","exception","length","form","submit","resetBulkAction","addEventListener","checkCountButtonClicked","contains","DynamicTable","setPageSize","targetPageSize","CheckboxToggleAll","setGroupState","Events","tableContentRefreshed","defaultPageSize","parseInt","tableDefaultPerPage","currentPageSize","tablePageSize","totalRowCount","tableTotalRows","updateSlavesFromMasterState","pageCountStrings","key","component","param","classList","add","remove","Str","get_strings","showingParticipantCountString","selectCountString","showingParticipantCount","innerHTML"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Some UI stuff for participants page.\n * This is also used by the report/participants/index.php because it has the same functionality.\n *\n * @module core_user/participants\n * @package core_user\n * @copyright 2017 Damyon Wiese\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as DynamicTable from 'core_table/dynamic';\nimport * as Str from 'core/str';\nimport CheckboxToggleAll from 'core/checkbox-toggleall';\nimport CustomEvents from 'core/custom_interaction_events';\nimport DynamicTableSelectors from 'core_table/local/dynamic/selectors';\nimport ModalEvents from 'core/modal_events';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport jQuery from 'jquery';\nimport {showAddNote, showSendMessage} from 'core_user/local/participants/bulkactions';\n\nconst Selectors = {\n bulkActionSelect: \"#formactionid\",\n bulkUserSelectedCheckBoxes: \"input[data-togglegroup='participants-table'][data-toggle='slave']:checked\",\n checkCountButton: \"#checkall\",\n showCountText: '[data-region=\"participant-count\"]',\n showCountToggle: '[data-action=\"showcount\"]',\n stateHelpIcon: '[data-region=\"state-help-icon\"]',\n tableForm: uniqueId => `form[data-table-unique-id=\"${uniqueId}\"]`,\n};\n\nexport const init = ({\n uniqueid,\n noteStateNames = {},\n}) => {\n const root = document.querySelector(Selectors.tableForm(uniqueid));\n const getTableFromUniqueId = uniqueId => root.querySelector(DynamicTableSelectors.main.fromRegionId(uniqueId));\n\n /**\n * Private method.\n *\n * @method registerEventListeners\n * @private\n */\n const registerEventListeners = () => {\n CustomEvents.define(Selectors.bulkActionSelect, [CustomEvents.events.accessibleChange]);\n jQuery(Selectors.bulkActionSelect).on(CustomEvents.events.accessibleChange, e => {\n const bulkActionSelect = e.target.closest('select');\n const action = bulkActionSelect.value;\n const tableRoot = getTableFromUniqueId(uniqueid);\n const checkboxes = tableRoot.querySelectorAll(Selectors.bulkUserSelectedCheckBoxes);\n const pendingPromise = new Pending('core_user/participants:bulkActionSelect');\n\n if (action.indexOf('#') !== -1) {\n e.preventDefault();\n\n const ids = [];\n checkboxes.forEach(checkbox => {\n ids.push(checkbox.getAttribute('name').replace('user', ''));\n });\n\n let bulkAction;\n if (action === '#messageselect') {\n bulkAction = showSendMessage(ids);\n } else if (action === '#addgroupnote') {\n bulkAction = showAddNote(\n root.dataset.courseId,\n ids,\n noteStateNames,\n root.querySelector(Selectors.stateHelpIcon)\n );\n }\n\n if (bulkAction) {\n const pendingBulkAction = new Pending('core_user/participants:bulkActionSelected');\n bulkAction\n .then(modal => {\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Focus on the action select when the dialog is closed.\n bulkActionSelect.focus();\n });\n\n pendingBulkAction.resolve();\n return modal;\n })\n .catch(Notification.exception);\n }\n } else if (action !== '' && checkboxes.length) {\n bulkActionSelect.form.submit();\n }\n\n resetBulkAction(bulkActionSelect);\n pendingPromise.resolve();\n });\n\n root.addEventListener('click', e => {\n // Handle clicking of the \"Select all\" actions.\n const checkCountButton = root.querySelector(Selectors.checkCountButton);\n const checkCountButtonClicked = checkCountButton && checkCountButton.contains(e.target);\n\n if (checkCountButtonClicked) {\n e.preventDefault();\n\n const tableRoot = getTableFromUniqueId(uniqueid);\n\n DynamicTable.setPageSize(tableRoot, checkCountButton.dataset.targetPageSize)\n .then(tableRoot => {\n // Update the toggle state.\n CheckboxToggleAll.setGroupState(root, 'participants-table', true);\n\n return tableRoot;\n })\n .catch(Notification.exception);\n }\n });\n\n // When the content is refreshed, update the row counts in various places.\n root.addEventListener(DynamicTable.Events.tableContentRefreshed, e => {\n const checkCountButton = root.querySelector(Selectors.checkCountButton);\n\n const tableRoot = e.target;\n\n const defaultPageSize = parseInt(tableRoot.dataset.tableDefaultPerPage, 10);\n const currentPageSize = parseInt(tableRoot.dataset.tablePageSize, 10);\n const totalRowCount = parseInt(tableRoot.dataset.tableTotalRows, 10);\n\n CheckboxToggleAll.updateSlavesFromMasterState(root, 'participants-table');\n\n const pageCountStrings = [\n {\n key: 'countparticipantsfound',\n component: 'core_user',\n param: totalRowCount,\n },\n ];\n\n if (totalRowCount <= defaultPageSize) {\n if (checkCountButton) {\n checkCountButton.classList.add('hidden');\n }\n } else if (totalRowCount <= currentPageSize) {\n // The are fewer than the current page size.\n pageCountStrings.push({\n key: 'selectalluserswithcount',\n component: 'core',\n param: defaultPageSize,\n });\n\n if (checkCountButton) {\n // The 'Check all [x]' button is only visible when there are values to set.\n checkCountButton.classList.add('hidden');\n }\n } else {\n pageCountStrings.push({\n key: 'selectalluserswithcount',\n component: 'core',\n param: totalRowCount,\n });\n\n if (checkCountButton) {\n checkCountButton.classList.remove('hidden');\n }\n }\n\n Str.get_strings(pageCountStrings)\n .then(([showingParticipantCountString, selectCountString]) => {\n const showingParticipantCount = root.querySelector(Selectors.showCountText);\n showingParticipantCount.innerHTML = showingParticipantCountString;\n\n if (selectCountString && checkCountButton) {\n checkCountButton.value = selectCountString;\n }\n\n return;\n })\n .catch(Notification.exception);\n });\n };\n\n const resetBulkAction = bulkActionSelect => {\n bulkActionSelect.value = '';\n };\n\n registerEventListeners();\n};\n"],"file":"participants.min.js"} \ No newline at end of file diff --git a/user/amd/src/participants.js b/user/amd/src/participants.js index 63c8e0a5d9b..7e4eb24da42 100644 --- a/user/amd/src/participants.js +++ b/user/amd/src/participants.js @@ -109,23 +109,19 @@ export const init = ({ }); root.addEventListener('click', e => { - // Handle clicking of the "Show [all|count]" and "Select all" actions. - const showCountLink = root.querySelector(Selectors.showCountToggle); + // Handle clicking of the "Select all" actions. const checkCountButton = root.querySelector(Selectors.checkCountButton); - - const showCountLinkClicked = showCountLink && showCountLink.contains(e.target); const checkCountButtonClicked = checkCountButton && checkCountButton.contains(e.target); - if (showCountLinkClicked || checkCountButtonClicked) { + if (checkCountButtonClicked) { e.preventDefault(); const tableRoot = getTableFromUniqueId(uniqueid); - DynamicTable.setPageSize(tableRoot, showCountLink.dataset.targetPageSize) + DynamicTable.setPageSize(tableRoot, checkCountButton.dataset.targetPageSize) .then(tableRoot => { - // Always update the toggle state. - // This ensures that the bulk actions are disabled after changing the page size. - CheckboxToggleAll.setGroupState(root, 'participants-table', checkCountButtonClicked); + // Update the toggle state. + CheckboxToggleAll.setGroupState(root, 'participants-table', true); return tableRoot; }) @@ -135,12 +131,11 @@ export const init = ({ // When the content is refreshed, update the row counts in various places. root.addEventListener(DynamicTable.Events.tableContentRefreshed, e => { - const showCountLink = root.querySelector(Selectors.showCountToggle); const checkCountButton = root.querySelector(Selectors.checkCountButton); const tableRoot = e.target; - const defaultPageSize = parseInt(root.dataset.tableDefaultPerPage, 10); + const defaultPageSize = parseInt(tableRoot.dataset.tableDefaultPerPage, 10); const currentPageSize = parseInt(tableRoot.dataset.tablePageSize, 10); const totalRowCount = parseInt(tableRoot.dataset.tableTotalRows, 10); @@ -154,67 +149,39 @@ export const init = ({ }, ]; - if (totalRowCount <= defaultPageSize) { - // There are fewer than the default page count numbers of rows. - showCountLink.classList.add('hidden'); - if (checkCountButton) { checkCountButton.classList.add('hidden'); } } else if (totalRowCount <= currentPageSize) { // The are fewer than the current page size. - pageCountStrings.push({ - key: 'showperpage', - component: 'core', - param: defaultPageSize, - }); - pageCountStrings.push({ key: 'selectalluserswithcount', component: 'core', param: defaultPageSize, }); - // Show the 'Show [x]' link. - showCountLink.classList.remove('hidden'); - showCountLink.dataset.targetPageSize = defaultPageSize; - if (checkCountButton) { // The 'Check all [x]' button is only visible when there are values to set. checkCountButton.classList.add('hidden'); } } else { - pageCountStrings.push({ - key: 'showall', - component: 'core', - param: totalRowCount, - }); - pageCountStrings.push({ key: 'selectalluserswithcount', component: 'core', param: totalRowCount, }); - // Show both the 'Show [x]' link, and the 'Check all [x]' button. - showCountLink.classList.remove('hidden'); - showCountLink.dataset.targetPageSize = totalRowCount; - if (checkCountButton) { checkCountButton.classList.remove('hidden'); } } Str.get_strings(pageCountStrings) - .then(([showingParticipantCountString, showCountString, selectCountString]) => { + .then(([showingParticipantCountString, selectCountString]) => { const showingParticipantCount = root.querySelector(Selectors.showCountText); showingParticipantCount.innerHTML = showingParticipantCountString; - if (showCountString) { - showCountLink.innerHTML = showCountString; - } - if (selectCountString && checkCountButton) { checkCountButton.value = selectCountString; } diff --git a/user/classes/table/participants.php b/user/classes/table/participants.php index 09823d73a59..ecbaff21526 100644 --- a/user/classes/table/participants.php +++ b/user/classes/table/participants.php @@ -195,6 +195,8 @@ class participants extends \table_sql implements dynamic_table { $this->no_sorting('groups'); } + $this->set_default_per_page(20); + $this->set_attribute('id', 'participants'); $this->countries = get_string_manager()->get_list_of_countries(true); diff --git a/user/index.php b/user/index.php index 7bf05da3eb9..a4f9648228f 100644 --- a/user/index.php +++ b/user/index.php @@ -35,7 +35,6 @@ use core_table\local\filter\integer_filter; use core_table\local\filter\string_filter; define('DEFAULT_PAGE_SIZE', 20); -define('SHOW_ALL_PAGE_SIZE', 5000); $page = optional_param('page', 0, PARAM_INT); // Which page to show. $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // How many per page. @@ -189,7 +188,6 @@ echo html_writer::start_tag('form', [ 'id' => 'participantsform', 'data-course-id' => $course->id, 'data-table-unique-id' => $participanttable->uniqueid, - 'data-table-default-per-page' => ($perpage < DEFAULT_PAGE_SIZE) ? $perpage : DEFAULT_PAGE_SIZE, ]); echo '
'; echo ''; @@ -205,40 +203,6 @@ echo html_writer::tag( echo $participanttablehtml; -$perpageurl = new moodle_url('/user/index.php', [ - 'contextid' => $context->id, - 'id' => $course->id, -]); -$perpagesize = DEFAULT_PAGE_SIZE; -$perpagevisible = false; -$perpagestring = ''; - -if ($perpage == SHOW_ALL_PAGE_SIZE && $participanttable->totalrows > DEFAULT_PAGE_SIZE) { - $perpageurl->param('perpage', $participanttable->totalrows); - $perpagesize = SHOW_ALL_PAGE_SIZE; - $perpagevisible = true; - $perpagestring = get_string('showperpage', '', DEFAULT_PAGE_SIZE); -} else if ($participanttable->get_page_size() < $participanttable->totalrows) { - $perpageurl->param('perpage', SHOW_ALL_PAGE_SIZE); - $perpagesize = SHOW_ALL_PAGE_SIZE; - $perpagevisible = true; - $perpagestring = get_string('showall', '', $participanttable->totalrows); -} - -$perpageclasses = ''; -if (!$perpagevisible) { - $perpageclasses = 'hidden'; -} -echo $OUTPUT->container(html_writer::link( - $perpageurl, - $perpagestring, - [ - 'data-action' => 'showcount', - 'data-target-page-size' => $perpagesize, - 'class' => $perpageclasses, - ] -), [], 'showall'); - $bulkoptions = (object) [ 'uniqueid' => $participanttable->uniqueid, ]; @@ -256,7 +220,7 @@ if ($bulkoperations) { 'id' => 'checkall', 'class' => 'btn btn-secondary', 'value' => $label, - 'data-target-page-size' => $participanttable->totalrows, + 'data-target-page-size' => TABLE_SHOW_ALL_PAGE_SIZE, ]); } echo html_writer::end_tag('div');