diff --git a/lang/en/enrol.php b/lang/en/enrol.php index 9e704416254..6fcb077c1a8 100644 --- a/lang/en/enrol.php +++ b/lang/en/enrol.php @@ -64,6 +64,7 @@ $string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"' $string['enrolmentmethod'] = 'Enrolment method'; $string['enrolments'] = 'Enrolments'; $string['enrolmentoptions'] = 'Enrolment options'; +$string['enrolmentupdatedforuser'] = 'The enrolment for user "{$a->fullname}" has been updated'; $string['enrolnotpermitted'] = 'You do not have permission or are not allowed to enrol someone in this course'; $string['enrolperiod'] = 'Enrolment duration'; $string['enrolusage'] = 'Instances / enrolments'; @@ -136,6 +137,7 @@ $string['totalunenrolledusers'] = '{$a} unenrolled users'; $string['totalotherusers'] = '{$a} other users'; $string['unassignnotpermitted'] = 'You do not have permission to unassign roles in this course'; $string['unenrol'] = 'Unenrol'; +$string['unenrolleduser'] = 'The user "{$a->fullname}" was unenrolled from the course'; $string['unenrolconfirm'] = 'Do you really want to unenrol "{$a->user}" (previously enrolled via "{$a->enrolinstancename}") from "{$a->course}"?'; $string['unenrolme'] = 'Unenrol me from {$a}'; $string['unenrolnotpermitted'] = 'You do not have permission or can not unenrol this user from this course.'; diff --git a/lib/table/amd/build/dynamic.min.js b/lib/table/amd/build/dynamic.min.js index 4632a52583c..4054b65c449 100644 --- a/lib/table/amd/build/dynamic.min.js +++ b/lib/table/amd/build/dynamic.min.js @@ -1,2 +1,2 @@ -define ("core_table/dynamic",["exports","core_table/local/dynamic/repository","core_table/local/dynamic/selectors"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=a.showColumn=a.hideColumn=a.setLastInitial=a.setFirstInitial=a.setPageSize=a.setPageNumber=a.setSortOrder=a.setFilters=a.updateTable=a.refreshTableContent=void 0;c=function(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}(c);function d(a){return g(a)||f(a)||e()}function e(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function f(a){if(Symbol.iterator in Object(a)||"[object Arguments]"===Object.prototype.toString.call(a))return Array.from(a)}function g(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b.\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 {fetch as fetchTableData} from 'core_table/local/dynamic/repository';\nimport * as Selectors from 'core_table/local/dynamic/selectors';\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 * @returns {Promise}\n */\nexport const refreshTableContent = tableRoot => {\n const filterset = getFiltersetFromTable(tableRoot);\n\n return fetchTableData(\n tableRoot.dataset.tableComponent,\n tableRoot.dataset.tableHandler,\n tableRoot.dataset.tableUniqueid,\n {\n sortBy: tableRoot.dataset.tableSortBy,\n sortOrder: tableRoot.dataset.tableSortOrder,\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 )\n .then(data => {\n const placeholder = document.createElement('div');\n placeholder.innerHTML = data.html;\n tableRoot.replaceWith(...placeholder.childNodes);\n\n return data;\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 // Update sort fields.\n if (sortBy && sortOrder) {\n tableRoot.dataset.tableSortBy = sortBy;\n tableRoot.dataset.tableSortOrder = sortOrder;\n }\n\n // Update initials.\n if (firstInitial !== null) {\n tableRoot.dataset.tableFirstInitial = firstInitial;\n }\n\n if (lastInitial !== null) {\n tableRoot.dataset.tableLastInitial = lastInitial;\n }\n\n if (pageNumber !== null) {\n tableRoot.dataset.tablePageNumber = pageNumber;\n }\n\n if (pageSize !== null) {\n tableRoot.dataset.tablePageSize = pageSize;\n }\n\n // Update filters.\n if (filters) {\n tableRoot.dataset.tableFilters = JSON.stringify(filters);\n }\n\n // Update hidden columns.\n if (hiddenColumns) {\n tableRoot.dataset.tableHiddenColumns = JSON.stringify(hiddenColumns);\n }\n\n // Refresh.\n if (refreshContent) {\n return refreshTableContent(tableRoot);\n } else {\n return Promise.resolve();\n }\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 * 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 * 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: 0}, refreshContent);\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 * 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 * Hide a column in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToHide\n * @param {Bool} refreshContent\n */\nexport const hideColumn = (tableRoot, columnToHide, refreshContent = true) => {\n const hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns.push(columnToHide);\n\n 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 */\nexport const showColumn = (tableRoot, columnToShow, refreshContent = true) => {\n let hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns = hiddenColumns.filter(columnName => columnName !== columnToShow);\n\n updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\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 }\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);\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);\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);\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);\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);\n }\n\n });\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","filterset","tableComponent","tableHandler","tableUniqueid","sortBy","tableSortBy","sortOrder","tableSortOrder","joinType","jointype","filters","firstinitial","tableFirstInitial","lastinitial","tableLastInitial","pageNumber","tablePageNumber","pageSize","tablePageSize","hiddenColumns","tableHiddenColumns","then","data","placeholder","document","createElement","innerHTML","html","replaceWith","childNodes","updateTable","firstInitial","lastInitial","refreshContent","stringify","Promise","resolve","setFilters","setSortOrder","setPageNumber","setPageSize","setFirstInitial","setLastInitial","hideColumn","columnToHide","push","showColumn","columnToShow","filter","columnName","init","addEventListener","e","target","closest","sortableLink","table","links","sortableColumn","preventDefault","sortby","sortorder","firstInitialLink","initialsBar","initial","lastInitialLink","pageItem","paginationBar","hide","column","show","getTableFromId","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 {fetch as fetchTableData} from 'core_table/local/dynamic/repository';\nimport * as Selectors from 'core_table/local/dynamic/selectors';\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 * @returns {Promise}\n */\nexport const refreshTableContent = tableRoot => {\n const filterset = getFiltersetFromTable(tableRoot);\n\n return fetchTableData(\n tableRoot.dataset.tableComponent,\n tableRoot.dataset.tableHandler,\n tableRoot.dataset.tableUniqueid,\n {\n sortBy: tableRoot.dataset.tableSortBy,\n sortOrder: tableRoot.dataset.tableSortOrder,\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 )\n .then(data => {\n const placeholder = document.createElement('div');\n placeholder.innerHTML = data.html;\n tableRoot.replaceWith(...placeholder.childNodes);\n\n return data;\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 // Update sort fields.\n if (sortBy && sortOrder) {\n tableRoot.dataset.tableSortBy = sortBy;\n tableRoot.dataset.tableSortOrder = sortOrder;\n }\n\n // Update initials.\n if (firstInitial !== null) {\n tableRoot.dataset.tableFirstInitial = firstInitial;\n }\n\n if (lastInitial !== null) {\n tableRoot.dataset.tableLastInitial = lastInitial;\n }\n\n if (pageNumber !== null) {\n tableRoot.dataset.tablePageNumber = pageNumber;\n }\n\n if (pageSize !== null) {\n tableRoot.dataset.tablePageSize = pageSize;\n }\n\n // Update filters.\n if (filters) {\n tableRoot.dataset.tableFilters = JSON.stringify(filters);\n }\n\n // Update hidden columns.\n if (hiddenColumns) {\n tableRoot.dataset.tableHiddenColumns = JSON.stringify(hiddenColumns);\n }\n\n // Refresh.\n if (refreshContent) {\n return refreshTableContent(tableRoot);\n } else {\n return Promise.resolve();\n }\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 * 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 * 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: 0}, refreshContent);\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 * 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 * Hide a column in the participants table.\n *\n * @param {HTMLElement} tableRoot\n * @param {String} columnToHide\n * @param {Bool} refreshContent\n */\nexport const hideColumn = (tableRoot, columnToHide, refreshContent = true) => {\n const hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns.push(columnToHide);\n\n 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 */\nexport const showColumn = (tableRoot, columnToShow, refreshContent = true) => {\n let hiddenColumns = JSON.parse(tableRoot.dataset.tableHiddenColumns);\n hiddenColumns = hiddenColumns.filter(columnName => columnName !== columnToShow);\n\n updateTable(tableRoot, {hiddenColumns}, refreshContent);\n};\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 }\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);\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);\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);\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);\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);\n }\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"],"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 2844c553ed8..d250c63efff 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\"]"},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]"}}};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 7a6ed15e9da..4e7d1022b19 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","table","links","sortableColumn","hide","show","initialsBar","firstInitial","lastInitial","paginationBar","pageItem"],"mappings":"8JAuBe,CACXA,IAAI,CAAE,CACFC,MAAM,CAAE,sCADN,CADK,CAIXC,KAAK,CAAE,CACHC,KAAK,CAAE,CACHC,cAAc,CAAE,wBADb,CAEHC,IAAI,CAAE,yBAFH,CAGHC,IAAI,CAAE,yBAHH,CADJ,CAJI,CAWXC,WAAW,CAAE,CACTJ,KAAK,CAAE,CACHK,YAAY,CAAE,8BADX,CAEHC,WAAW,CAAE,6BAFV,CADE,CAXF,CAiBXC,aAAa,CAAE,CACXP,KAAK,CAAE,CACHQ,QAAQ,CAAE,gCADP,CADI,CAjBJ,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 },\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"],"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 diff --git a/lib/table/amd/src/dynamic.js b/lib/table/amd/src/dynamic.js index 3c875910c03..633338593c3 100644 --- a/lib/table/amd/src/dynamic.js +++ b/lib/table/amd/src/dynamic.js @@ -299,3 +299,21 @@ export const init = () => { }); }; + +/** + * Fetch the table via its table region id + * + * @param {String} tableRegionId + * @returns {HTMLElement} + */ +export const getTableFromId = tableRegionId => { + const tableRoot = document.querySelector(Selectors.main.fromRegionId(tableRegionId)); + + + if (!tableRoot) { + // The table is not a dynamic table. + throw new Error("The table specified is not a dynamic table and cannot be updated"); + } + + return tableRoot; +}; diff --git a/lib/table/amd/src/local/dynamic/selectors.js b/lib/table/amd/src/local/dynamic/selectors.js index 2a52d91c13b..64c75549653 100644 --- a/lib/table/amd/src/local/dynamic/selectors.js +++ b/lib/table/amd/src/local/dynamic/selectors.js @@ -24,6 +24,7 @@ export default { main: { region: '[data-region="core_table/dynamic"]', + fromRegionId: regionId => `[data-region="core_table/dynamic"][data-table-uniqueid="${regionId}"]`, }, table: { links: { diff --git a/user/amd/build/repository.min.js b/user/amd/build/repository.min.js new file mode 100644 index 00000000000..5ff57f0f070 --- /dev/null +++ b/user/amd/build/repository.min.js @@ -0,0 +1,2 @@ +define ("core_user/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.submitUserEnrolmentForm=a.unenrolUser=void 0;a.unenrolUser=function unenrolUser(a){return(0,b.call)([{methodname:"core_enrol_unenrol_user_enrolment",args:{ueid:a}}])[0]};a.submitUserEnrolmentForm=function submitUserEnrolmentForm(a){return(0,b.call)([{methodname:"core_enrol_submit_user_enrolment_form",args:{formdata:a}}])[0]}}); +//# sourceMappingURL=repository.min.js.map diff --git a/user/amd/build/repository.min.js.map b/user/amd/build/repository.min.js.map new file mode 100644 index 00000000000..7d60e609a70 --- /dev/null +++ b/user/amd/build/repository.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/repository.js"],"names":["unenrolUser","userEnrolmentId","methodname","args","ueid","submitUserEnrolmentForm","formdata"],"mappings":"gMA8B2B,QAAdA,CAAAA,WAAc,CAAAC,CAAe,CAAI,CAC1C,MAAO,WAAU,CAAC,CACdC,UAAU,CAAE,mCADE,CAEdC,IAAI,CAAE,CACFC,IAAI,CAAEH,CADJ,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C,2BAQsC,QAA1BI,CAAAA,uBAA0B,CAAAC,CAAQ,CAAI,CAC/C,MAAO,WAAU,CAAC,CACdJ,UAAU,CAAE,uCADE,CAEdC,IAAI,CAAE,CACFG,QAAQ,CAARA,CADE,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,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 * Module to handle AJAX interactions.\n *\n * @module core_user/repository\n * @copyright 2020 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {call as fetchMany} from 'core/ajax';\n\n/**\n * Unenrol the user with the specified user enrolmentid ID.\n *\n * @param {Number} userEnrolmentId\n * @return {Promise}\n */\nexport const unenrolUser = userEnrolmentId => {\n return fetchMany([{\n methodname: 'core_enrol_unenrol_user_enrolment',\n args: {\n ueid: userEnrolmentId,\n },\n }])[0];\n};\n\n/**\n * Submit the user enrolment form with the specified form data.\n *\n * @param {String} formdata\n * @return {Promise}\n */\nexport const submitUserEnrolmentForm = formdata => {\n return fetchMany([{\n methodname: 'core_enrol_submit_user_enrolment_form',\n args: {\n formdata,\n },\n }])[0];\n};\n"],"file":"repository.min.js"} \ No newline at end of file diff --git a/user/amd/build/status_field.min.js b/user/amd/build/status_field.min.js index 7a8a14cecee..255f72e6085 100644 --- a/user/amd/build/status_field.min.js +++ b/user/amd/build/status_field.min.js @@ -1,2 +1,2 @@ -define ("core_user/status_field",["core/templates","jquery","core/str","core/config","core/notification","core/modal_factory","core/modal_events","core/fragment","core/ajax"],function(a,b,c,d,f,g,h,i,j){var k={EDIT_ENROLMENT:"[data-action=\"editenrolment\"]",SHOW_DETAILS:"[data-action=\"showdetails\"]",UNENROL:"[data-action=\"unenrol\"]"},l=function(a){this.contextid=a.contextid;this.courseid=a.courseid;this.bindEditEnrol();this.bindUnenrol();this.bindStatusDetails()};l.prototype.courseid=0;l.prototype.bindEditEnrol=function(){var a=this;b(k.EDIT_ENROLMENT).click(function(d){d.preventDefault();var e=b(this),i=e.parent(),j=i.data("fullname"),k=e.attr("rel");b.when(c.get_string("edituserenrolment","enrol",j)).then(function(a){return g.create({large:!0,title:a,type:g.types.SAVE_CANCEL})}).done(function(b){b.getRoot().on(h.save,function(c){c.preventDefault();a.submitEditFormAjax(b)});b.getRoot().on(h.hidden,function(){b.destroy()});b.setBody(a.getBody(k));b.show()}).fail(f.exception)})};l.prototype.bindUnenrol=function(){var a=this;b(k.UNENROL).click(function(d){d.preventDefault();var e=b(this),i=e.parent(),j=[{key:"unenrol",component:"enrol"},{key:"unenrolconfirm",component:"enrol",param:{user:i.data("fullname"),course:i.data("coursename"),enrolinstancename:i.data("enrolinstancename")}}],k=g.create({type:g.types.SAVE_CANCEL});b.when(c.get_strings(j),k).done(function(c,f){var g=c[0],i=c[1];f.setTitle(g);f.setBody(i);f.setSaveButtonText(g);f.getRoot().on(h.save,function(){var c={ueid:b(e).attr("rel")};d.preventDefault();a.submitUnenrolFormAjax(f,c)});f.getRoot().on(h.hidden,function(){f.destroy()});f.show()}).fail(f.exception)})};l.prototype.bindStatusDetails=function(){b(k.SHOW_DETAILS).click(function(d){d.preventDefault();var e=b(this),i=e.parent(),j={fullname:i.data("fullname"),coursename:i.data("coursename"),enrolinstancename:i.data("enrolinstancename"),status:i.data("status"),statusclass:i.find("span").attr("class"),timestart:i.data("timestart"),timeend:i.data("timeend"),timeenrolled:i.data("timeenrolled")},l=e.next(k.EDIT_ENROLMENT);if(l.length){j.editenrollink=b("
").append(l.clone()).html()}var m=c.get_strings([{key:"enroldetails",component:"enrol"}]),n=g.create({large:!0,type:g.types.CANCEL});b.when(m,n).done(function(c,d){var e=a.render("core_user/status_details",j);d.setTitle(c[0]);d.setBody(e);if(l.length){d.getRoot().on("click",k.EDIT_ENROLMENT,function(a){a.preventDefault();d.hide();b(l).trigger("click")})}d.show();d.getRoot().on(h.hidden,function(){d.destroy()})}).fail(f.exception)})};l.prototype.submitEditFormAjax=function(a){var c=this,d=a.getRoot().find("form"),e=b(d).find("[name=\"ue\"]").val(),g={methodname:"core_enrol_submit_user_enrolment_form",args:{formdata:d.serialize()}};j.call([g])[0].done(function(b){if(b.result){a.hide();if("undefined"!=typeof window.M.core_formchangechecker){window.M.core_formchangechecker.reset_form_dirty_state()}window.location.reload()}else{var f=JSON.stringify(d.serialize());a.setBody(c.getBody(e,f))}}).fail(f.exception)};l.prototype.submitUnenrolFormAjax=function(a,b){j.call([{methodname:"core_enrol_unenrol_user_enrolment",args:b}])[0].done(function(b){if(b.result){a.hide();if("undefined"!=typeof window.M.core_formchangechecker){window.M.core_formchangechecker.reset_form_dirty_state()}window.location.reload()}else{f.alert(b.errors[0].key,b.errors[0].message)}}).fail(f.exception)};l.prototype.getBody=function(a,b){var c={ueid:a};if("undefined"!=typeof b){c.formdata=b}return i.loadFragment("enrol","user_enrolment_form",this.contextid,c).fail(f.exception)};return{init:function init(a){new l(a)}}}); +define ("core_user/status_field",["exports","core_table/dynamic","./repository","core/str","core_table/local/dynamic/selectors","core/fragment","core/modal_events","core/modal_factory","core/notification","core/templates","core/toast"],function(a,b,c,d,f,g,h,i,j,k,l){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=n(b);c=n(c);d=n(d);f=m(f);g=m(g);h=m(h);i=m(i);j=m(j);k=m(k);function m(a){return a&&a.__esModule?a:{default:a}}function n(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function o(a){for(var b=1;b.\n\n/**\n * AMD module for the user enrolment status field in the course participants page.\n *\n * @module core_user/status_field\n * @copyright 2017 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/templates',\n 'jquery',\n 'core/str',\n 'core/config',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/fragment',\n 'core/ajax'\n ],\n function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Ajax) {\n\n /**\n * Action selectors.\n *\n * @access private\n * @type {{EDIT_ENROLMENT: string, SHOW_DETAILS: string, UNENROL: string}}\n */\n var SELECTORS = {\n EDIT_ENROLMENT: '[data-action=\"editenrolment\"]',\n SHOW_DETAILS: '[data-action=\"showdetails\"]',\n UNENROL: '[data-action=\"unenrol\"]'\n };\n\n /**\n * Constructor\n *\n * @param {Object} options Object containing options. The only valid option at this time is contextid.\n * Each call to templates.render gets it's own instance of this class.\n */\n var StatusFieldActions = function(options) {\n this.contextid = options.contextid;\n this.courseid = options.courseid;\n\n // Bind click event to editenrol buttons.\n this.bindEditEnrol();\n\n // Bind click event to unenrol buttons.\n this.bindUnenrol();\n\n // Bind click event to status details buttons.\n this.bindStatusDetails();\n };\n // Class variables and functions.\n\n /** @var {number} courseid The course ID. */\n StatusFieldActions.prototype.courseid = 0;\n\n /**\n * Private method\n *\n * @method initModal\n * @private\n */\n StatusFieldActions.prototype.bindEditEnrol = function() {\n var statusFieldInstsance = this;\n\n $(SELECTORS.EDIT_ENROLMENT).click(function(e) {\n e.preventDefault();\n\n // The particular edit button that was clicked.\n var clickedEditTrigger = $(this);\n // Get the parent container (it contains the data attributes associated with the status field).\n var parentContainer = clickedEditTrigger.parent();\n // Get the name of the user whose enrolment status is being edited.\n var fullname = parentContainer.data('fullname');\n // Get the user enrolment ID.\n var ueid = clickedEditTrigger.attr('rel');\n\n $.when(Str.get_string('edituserenrolment', 'enrol', fullname)).then(function(modalTitle) {\n return ModalFactory.create({\n large: true,\n title: modalTitle,\n type: ModalFactory.types.SAVE_CANCEL\n });\n }).done(function(modal) {\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function(e) {\n // Don't close the modal yet.\n e.preventDefault();\n // Submit form data.\n statusFieldInstsance.submitEditFormAjax(modal);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Set the modal body.\n modal.setBody(statusFieldInstsance.getBody(ueid));\n\n // Show the modal!\n modal.show();\n }).fail(Notification.exception);\n });\n };\n\n /**\n * Private method\n *\n * @method bindUnenrol\n * @private\n */\n StatusFieldActions.prototype.bindUnenrol = function() {\n var statusFieldInstsance = this;\n\n $(SELECTORS.UNENROL).click(function(e) {\n e.preventDefault();\n var unenrolLink = $(this);\n var parentContainer = unenrolLink.parent();\n var strings = [\n {\n key: 'unenrol',\n component: 'enrol'\n },\n {\n key: 'unenrolconfirm',\n component: 'enrol',\n param: {\n user: parentContainer.data('fullname'),\n course: parentContainer.data('coursename'),\n enrolinstancename: parentContainer.data('enrolinstancename')\n }\n }\n ];\n\n var deleteModalPromise = ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL\n });\n\n $.when(Str.get_strings(strings), deleteModalPromise).done(function(results, modal) {\n var title = results[0];\n var confirmMessage = results[1];\n modal.setTitle(title);\n modal.setBody(confirmMessage);\n modal.setSaveButtonText(title);\n\n // Handle confirm event.\n modal.getRoot().on(ModalEvents.save, function() {\n // Build params.\n var unenrolParams = {\n 'ueid': $(unenrolLink).attr('rel')\n };\n // Don't close the modal yet.\n e.preventDefault();\n // Submit data.\n statusFieldInstsance.submitUnenrolFormAjax(modal, unenrolParams);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Display the delete confirmation modal.\n modal.show();\n }).fail(Notification.exception);\n });\n };\n\n /**\n * Private method\n *\n * @method bindStatusDetails\n * @private\n */\n StatusFieldActions.prototype.bindStatusDetails = function() {\n $(SELECTORS.SHOW_DETAILS).click(function(e) {\n e.preventDefault();\n\n var detailsButton = $(this);\n var parentContainer = detailsButton.parent();\n var context = {\n \"fullname\": parentContainer.data('fullname'),\n \"coursename\": parentContainer.data('coursename'),\n \"enrolinstancename\": parentContainer.data('enrolinstancename'),\n \"status\": parentContainer.data('status'),\n \"statusclass\": parentContainer.find('span').attr('class'),\n \"timestart\": parentContainer.data('timestart'),\n \"timeend\": parentContainer.data('timeend'),\n \"timeenrolled\": parentContainer.data('timeenrolled')\n };\n\n // Get default string for the modal and modal type.\n var strings = [\n {\n key: 'enroldetails',\n component: 'enrol'\n }\n ];\n\n // Find the edit enrolment link.\n var editEnrolLink = detailsButton.next(SELECTORS.EDIT_ENROLMENT);\n if (editEnrolLink.length) {\n // If there's an edit enrolment link for this user, clone it into the context for the modal.\n context.editenrollink = $('
').append(editEnrolLink.clone()).html();\n }\n\n var modalStringsPromise = Str.get_strings(strings);\n var modalPromise = ModalFactory.create({large: true, type: ModalFactory.types.CANCEL});\n $.when(modalStringsPromise, modalPromise).done(function(strings, modal) {\n var modalBodyPromise = Template.render('core_user/status_details', context);\n modal.setTitle(strings[0]);\n modal.setBody(modalBodyPromise);\n\n if (editEnrolLink.length) {\n modal.getRoot().on('click', SELECTORS.EDIT_ENROLMENT, function(e) {\n e.preventDefault();\n modal.hide();\n // Trigger click event for the edit enrolment link to show the edit enrolment modal.\n $(editEnrolLink).trigger('click');\n });\n }\n\n modal.show();\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n }).fail(Notification.exception);\n });\n };\n\n /**\n * Private method\n *\n * @method submitEditFormAjax\n * @param {Object} modal The the AMD modal object containing the form.\n * @private\n */\n StatusFieldActions.prototype.submitEditFormAjax = function(modal) {\n var statusFieldInstsance = this;\n var form = modal.getRoot().find('form');\n\n // User enrolment ID.\n var ueid = $(form).find('[name=\"ue\"]').val();\n\n var request = {\n methodname: 'core_enrol_submit_user_enrolment_form',\n args: {\n formdata: form.serialize()\n }\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n // Dismiss the modal.\n modal.hide();\n\n // Reload the page, don't show changed data warnings.\n if (typeof window.M.core_formchangechecker !== \"undefined\") {\n window.M.core_formchangechecker.reset_form_dirty_state();\n }\n window.location.reload();\n } else {\n // Serialise the form data and reload the form fragment to show validation errors.\n var formData = JSON.stringify(form.serialize());\n modal.setBody(statusFieldInstsance.getBody(ueid, formData));\n }\n }).fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method submitUnenrolFormAjax\n * @param {Object} modal The the AMD modal object containing the form.\n * @param {Object} unenrolParams The unenrol parameters.\n * @private\n */\n StatusFieldActions.prototype.submitUnenrolFormAjax = function(modal, unenrolParams) {\n var request = {\n methodname: 'core_enrol_unenrol_user_enrolment',\n args: unenrolParams\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n // Dismiss the modal.\n modal.hide();\n\n // Reload the page, don't show changed data warnings.\n if (typeof window.M.core_formchangechecker !== \"undefined\") {\n window.M.core_formchangechecker.reset_form_dirty_state();\n }\n window.location.reload();\n } else {\n // Display an alert containing the error message\n Notification.alert(data.errors[0].key, data.errors[0].message);\n }\n }).fail(Notification.exception);\n };\n\n /**\n * Private method\n *\n * @method getBody\n * @private\n * @param {Number} ueid The user enrolment ID associated with the user.\n * @param {string} formData Serialized string of the edit enrolment form data.\n * @return {Promise}\n */\n StatusFieldActions.prototype.getBody = function(ueid, formData) {\n var params = {\n 'ueid': ueid\n };\n if (typeof formData !== 'undefined') {\n params.formdata = formData;\n }\n return Fragment.loadFragment('enrol', 'user_enrolment_form', this.contextid, params).fail(Notification.exception);\n };\n\n return /** @alias module:core_user/editenrolment */ {\n // Public variables and functions.\n /**\n * Every call to init creates a new instance of the class with it's own event listeners etc.\n *\n * @method init\n * @public\n * @param {object} config - config variables for the module.\n */\n init: function(config) {\n (new StatusFieldActions(config));\n }\n };\n });\n"],"file":"status_field.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/status_field.js"],"names":["Selectors","editEnrolment","showDetails","unenrol","statusElement","getDynamicTableFromLink","link","closest","DynamicTableSelectors","main","region","getStatusContainer","getUserEnrolmentIdFromLink","getAttribute","registerEventListeners","contextId","uniqueId","getBodyFunction","userEnrolmentId","formData","getBody","document","addEventListener","e","tableRoot","target","fromRegionId","editLink","preventDefault","showEditDialogue","unenrolLink","showUnenrolConfirmation","showDetailsLink","showStatusDetails","container","ModalFactory","create","large","title","Str","get_string","dataset","fullname","type","types","SAVE_CANCEL","body","then","modal","getRoot","on","ModalEvents","save","submitEditFormAjax","hidden","destroy","show","catch","Notification","exception","submitUnenrolFormAjax","ueid","stringData","key","component","param","user","course","coursename","enrolinstancename","Promise","all","get_strings","strings","setTitle","setSaveButtonText","setBody","context","editenrollink","statusclass","querySelector","editEnrolLink","outerHTML","CANCEL","Templates","render","hide","click","clickedLink","userData","form","find","Repository","submitUserEnrolmentForm","serialize","data","result","DynamicTable","refreshTableContent","notificationString","JSON","stringify","args","unenrolUser","alert","errors","message","formdata","Fragment","loadFragment","init","contextid","uniqueid"],"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 * AMD module for the user enrolment status field in the course participants page.\n *\n * @module core_user/status_field\n * @copyright 2017 Jun Pataleta\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 Repository from './repository';\nimport * as Str from 'core/str';\nimport DynamicTableSelectors from 'core_table/local/dynamic/selectors';\nimport Fragment from 'core/fragment';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport {add as notifyUser} from 'core/toast';\n\nconst Selectors = {\n editEnrolment: '[data-action=\"editenrolment\"]',\n showDetails: '[data-action=\"showdetails\"]',\n unenrol: '[data-action=\"unenrol\"]',\n statusElement: '[data-status]',\n};\n\n/**\n * Get the dynamic table from the specified link.\n *\n * @param {HTMLElement} link\n * @returns {HTMLElement}\n */\nconst getDynamicTableFromLink = link => link.closest(DynamicTableSelectors.main.region);\n\n/**\n * Get the status container from the specified link.\n *\n * @param {HTMLElement} link\n * @returns {HTMLElement}\n */\nconst getStatusContainer = link => link.closest(Selectors.statusElement);\n\n/**\n * Get user enrolment id from the specified link\n *\n * @param {HTMLElement} link\n * @returns {Number}\n */\nconst getUserEnrolmentIdFromLink = link => link.getAttribute('rel');\n\n/**\n * Register all event listeners for the status fields.\n *\n * @param {Number} contextId\n * @param {Number} uniqueId\n */\nconst registerEventListeners = (contextId, uniqueId) => {\n const getBodyFunction = (userEnrolmentId, formData) => getBody(contextId, userEnrolmentId, formData);\n\n document.addEventListener('click', e => {\n const tableRoot = e.target.closest(DynamicTableSelectors.main.fromRegionId(uniqueId));\n if (!tableRoot) {\n return;\n }\n\n const editLink = e.target.closest(Selectors.editEnrolment);\n if (editLink) {\n e.preventDefault();\n\n showEditDialogue(editLink, getBodyFunction);\n }\n\n const unenrolLink = e.target.closest(Selectors.unenrol);\n if (unenrolLink) {\n e.preventDefault();\n\n showUnenrolConfirmation(unenrolLink);\n }\n\n const showDetailsLink = e.target.closest(Selectors.showDetails);\n if (showDetailsLink) {\n e.preventDefault();\n\n showStatusDetails(showDetailsLink);\n }\n });\n};\n\n/**\n * Show the edit dialogue.\n *\n * @param {HTMLElement} link\n * @param {Function} getBody Function to get the body for the specified user enrolment\n */\nconst showEditDialogue = (link, getBody) => {\n const container = getStatusContainer(link);\n const userEnrolmentId = getUserEnrolmentIdFromLink(link);\n\n ModalFactory.create({\n large: true,\n title: Str.get_string('edituserenrolment', 'enrol', container.dataset.fullname),\n type: ModalFactory.types.SAVE_CANCEL,\n body: getBody(userEnrolmentId)\n })\n .then(modal => {\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, e => {\n // Don't close the modal yet.\n e.preventDefault();\n\n // Submit form data.\n submitEditFormAjax(link, getBody, modal, userEnrolmentId, container.dataset);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Show the modal.\n modal.show();\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Show and handle the unenrolment confirmation dialogue.\n *\n * @param {HTMLElement} link\n */\nconst showUnenrolConfirmation = link => {\n const container = getStatusContainer(link);\n const userEnrolmentId = getUserEnrolmentIdFromLink(link);\n\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n })\n .then(modal => {\n // Handle confirm event.\n modal.getRoot().on(ModalEvents.save, e => {\n // Don't close the modal yet.\n e.preventDefault();\n\n // Submit data.\n submitUnenrolFormAjax(\n link,\n modal,\n {\n ueid: userEnrolmentId,\n },\n container.dataset\n );\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, () => {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Display the delete confirmation modal.\n modal.show();\n\n const stringData = [\n {\n key: 'unenrol',\n component: 'enrol',\n },\n {\n key: 'unenrolconfirm',\n component: 'enrol',\n param: {\n user: container.dataset.fullname,\n course: container.dataset.coursename,\n enrolinstancename: container.dataset.enrolinstancename,\n }\n }\n ];\n\n return Promise.all([Str.get_strings(stringData), modal]);\n })\n .then(([strings, modal]) => {\n modal.setTitle(strings[0]);\n modal.setSaveButtonText(strings[0]);\n modal.setBody(strings[1]);\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Show the user details dialogue.\n *\n * @param {HTMLElement} link\n */\nconst showStatusDetails = link => {\n const container = getStatusContainer(link);\n\n const context = {\n editenrollink: '',\n statusclass: container.querySelector('span.badge').getAttribute('class'),\n ...container.dataset,\n };\n\n // Find the edit enrolment link.\n const editEnrolLink = container.querySelector(Selectors.editEnrolment);\n if (editEnrolLink) {\n // If there's an edit enrolment link for this user, clone it into the context for the modal.\n context.editenrollink = editEnrolLink.outerHTML;\n }\n\n ModalFactory.create({\n large: true,\n type: ModalFactory.types.CANCEL,\n title: Str.get_string('enroldetails', 'enrol'),\n body: Templates.render('core_user/status_details', context),\n })\n .then(modal => {\n if (editEnrolLink) {\n modal.getRoot().on('click', Selectors.editEnrolment, e => {\n e.preventDefault();\n modal.hide();\n\n // Trigger click event for the edit enrolment link to show the edit enrolment modal.\n editEnrolLink.click();\n });\n }\n\n modal.show();\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, () => modal.destroy());\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Submit the edit dialogue.\n *\n * @param {HTMLElement} clickedLink\n * @param {Function} getBody\n * @param {Object} modal\n * @param {Number} userEnrolmentId\n * @param {Object} userData\n */\nconst submitEditFormAjax = (clickedLink, getBody, modal, userEnrolmentId, userData) => {\n const form = modal.getRoot().find('form');\n\n Repository.submitUserEnrolmentForm(form.serialize())\n .then(data => {\n if (!data.result) {\n throw data.result;\n }\n\n // Dismiss the modal.\n modal.hide();\n modal.destroy();\n\n return data;\n })\n .then(() => {\n DynamicTable.refreshTableContent(getDynamicTableFromLink(clickedLink));\n\n return Str.get_string('enrolmentupdatedforuser', 'core_enrol', userData);\n })\n .then(notificationString => {\n notifyUser(notificationString);\n\n return;\n })\n .catch(() => {\n modal.setBody(getBody(userEnrolmentId, JSON.stringify(form.serialize())));\n\n return modal;\n });\n};\n\n/**\n * Submit the unenrolment form.\n *\n * @param {HTMLElement} clickedLink\n * @param {Object} modal\n * @param {Object} args\n * @param {Object} userData\n */\nconst submitUnenrolFormAjax = (clickedLink, modal, args, userData) => {\n Repository.unenrolUser(args.ueid)\n .then(data => {\n if (!data.result) {\n // Display an alert containing the error message\n Notification.alert(data.errors[0].key, data.errors[0].message);\n\n return data;\n }\n\n // Dismiss the modal.\n modal.hide();\n modal.destroy();\n\n return data;\n })\n .then(() => {\n DynamicTable.refreshTableContent(getDynamicTableFromLink(clickedLink));\n\n return Str.get_string('unenrolleduser', 'core_enrol', userData);\n })\n .then(notificationString => {\n notifyUser(notificationString);\n\n return;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Get the body fragment.\n *\n * @param {Number} contextId\n * @param {Number} ueid The user enrolment id\n * @param {Object} formdata\n * @returns {Promise}\n */\nconst getBody = (contextId, ueid, formdata = null) => Fragment.loadFragment(\n 'enrol',\n 'user_enrolment_form',\n contextId,\n {\n ueid,\n formdata,\n }\n);\n\n/**\n * Initialise the statu field handler.\n *\n * @param {Number} contextid\n * @param {Number} uniqueid\n */\nexport const init = ({contextid, uniqueid}) => {\n registerEventListeners(contextid, uniqueid);\n};\n"],"file":"status_field.min.js"} \ No newline at end of file diff --git a/user/amd/src/repository.js b/user/amd/src/repository.js new file mode 100644 index 00000000000..7be9378875f --- /dev/null +++ b/user/amd/src/repository.js @@ -0,0 +1,53 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Module to handle AJAX interactions. + * + * @module core_user/repository + * @copyright 2020 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +import {call as fetchMany} from 'core/ajax'; + +/** + * Unenrol the user with the specified user enrolmentid ID. + * + * @param {Number} userEnrolmentId + * @return {Promise} + */ +export const unenrolUser = userEnrolmentId => { + return fetchMany([{ + methodname: 'core_enrol_unenrol_user_enrolment', + args: { + ueid: userEnrolmentId, + }, + }])[0]; +}; + +/** + * Submit the user enrolment form with the specified form data. + * + * @param {String} formdata + * @return {Promise} + */ +export const submitUserEnrolmentForm = formdata => { + return fetchMany([{ + methodname: 'core_enrol_submit_user_enrolment_form', + args: { + formdata, + }, + }])[0]; +}; diff --git a/user/amd/src/status_field.js b/user/amd/src/status_field.js index c03d9de31cf..156312023b1 100644 --- a/user/amd/src/status_field.js +++ b/user/amd/src/status_field.js @@ -20,334 +20,343 @@ * @copyright 2017 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['core/templates', - 'jquery', - 'core/str', - 'core/config', - 'core/notification', - 'core/modal_factory', - 'core/modal_events', - 'core/fragment', - 'core/ajax' - ], - function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Ajax) { - /** - * Action selectors. - * - * @access private - * @type {{EDIT_ENROLMENT: string, SHOW_DETAILS: string, UNENROL: string}} - */ - var SELECTORS = { - EDIT_ENROLMENT: '[data-action="editenrolment"]', - SHOW_DETAILS: '[data-action="showdetails"]', - UNENROL: '[data-action="unenrol"]' - }; +import * as DynamicTable from 'core_table/dynamic'; +import * as Repository from './repository'; +import * as Str from 'core/str'; +import DynamicTableSelectors from 'core_table/local/dynamic/selectors'; +import Fragment from 'core/fragment'; +import ModalEvents from 'core/modal_events'; +import ModalFactory from 'core/modal_factory'; +import Notification from 'core/notification'; +import Templates from 'core/templates'; +import {add as notifyUser} from 'core/toast'; - /** - * Constructor - * - * @param {Object} options Object containing options. The only valid option at this time is contextid. - * Each call to templates.render gets it's own instance of this class. - */ - var StatusFieldActions = function(options) { - this.contextid = options.contextid; - this.courseid = options.courseid; +const Selectors = { + editEnrolment: '[data-action="editenrolment"]', + showDetails: '[data-action="showdetails"]', + unenrol: '[data-action="unenrol"]', + statusElement: '[data-status]', +}; - // Bind click event to editenrol buttons. - this.bindEditEnrol(); +/** + * Get the dynamic table from the specified link. + * + * @param {HTMLElement} link + * @returns {HTMLElement} + */ +const getDynamicTableFromLink = link => link.closest(DynamicTableSelectors.main.region); - // Bind click event to unenrol buttons. - this.bindUnenrol(); +/** + * Get the status container from the specified link. + * + * @param {HTMLElement} link + * @returns {HTMLElement} + */ +const getStatusContainer = link => link.closest(Selectors.statusElement); - // Bind click event to status details buttons. - this.bindStatusDetails(); - }; - // Class variables and functions. +/** + * Get user enrolment id from the specified link + * + * @param {HTMLElement} link + * @returns {Number} + */ +const getUserEnrolmentIdFromLink = link => link.getAttribute('rel'); - /** @var {number} courseid The course ID. */ - StatusFieldActions.prototype.courseid = 0; +/** + * Register all event listeners for the status fields. + * + * @param {Number} contextId + * @param {Number} uniqueId + */ +const registerEventListeners = (contextId, uniqueId) => { + const getBodyFunction = (userEnrolmentId, formData) => getBody(contextId, userEnrolmentId, formData); - /** - * Private method - * - * @method initModal - * @private - */ - StatusFieldActions.prototype.bindEditEnrol = function() { - var statusFieldInstsance = this; + document.addEventListener('click', e => { + const tableRoot = e.target.closest(DynamicTableSelectors.main.fromRegionId(uniqueId)); + if (!tableRoot) { + return; + } - $(SELECTORS.EDIT_ENROLMENT).click(function(e) { - e.preventDefault(); + const editLink = e.target.closest(Selectors.editEnrolment); + if (editLink) { + e.preventDefault(); - // The particular edit button that was clicked. - var clickedEditTrigger = $(this); - // Get the parent container (it contains the data attributes associated with the status field). - var parentContainer = clickedEditTrigger.parent(); - // Get the name of the user whose enrolment status is being edited. - var fullname = parentContainer.data('fullname'); - // Get the user enrolment ID. - var ueid = clickedEditTrigger.attr('rel'); + showEditDialogue(editLink, getBodyFunction); + } - $.when(Str.get_string('edituserenrolment', 'enrol', fullname)).then(function(modalTitle) { - return ModalFactory.create({ - large: true, - title: modalTitle, - type: ModalFactory.types.SAVE_CANCEL - }); - }).done(function(modal) { - // Handle save event. - modal.getRoot().on(ModalEvents.save, function(e) { - // Don't close the modal yet. - e.preventDefault(); - // Submit form data. - statusFieldInstsance.submitEditFormAjax(modal); - }); + const unenrolLink = e.target.closest(Selectors.unenrol); + if (unenrolLink) { + e.preventDefault(); - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); + showUnenrolConfirmation(unenrolLink); + } - // Set the modal body. - modal.setBody(statusFieldInstsance.getBody(ueid)); + const showDetailsLink = e.target.closest(Selectors.showDetails); + if (showDetailsLink) { + e.preventDefault(); - // Show the modal! - modal.show(); - }).fail(Notification.exception); - }); - }; - - /** - * Private method - * - * @method bindUnenrol - * @private - */ - StatusFieldActions.prototype.bindUnenrol = function() { - var statusFieldInstsance = this; - - $(SELECTORS.UNENROL).click(function(e) { - e.preventDefault(); - var unenrolLink = $(this); - var parentContainer = unenrolLink.parent(); - var strings = [ - { - key: 'unenrol', - component: 'enrol' - }, - { - key: 'unenrolconfirm', - component: 'enrol', - param: { - user: parentContainer.data('fullname'), - course: parentContainer.data('coursename'), - enrolinstancename: parentContainer.data('enrolinstancename') - } - } - ]; - - var deleteModalPromise = ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL - }); - - $.when(Str.get_strings(strings), deleteModalPromise).done(function(results, modal) { - var title = results[0]; - var confirmMessage = results[1]; - modal.setTitle(title); - modal.setBody(confirmMessage); - modal.setSaveButtonText(title); - - // Handle confirm event. - modal.getRoot().on(ModalEvents.save, function() { - // Build params. - var unenrolParams = { - 'ueid': $(unenrolLink).attr('rel') - }; - // Don't close the modal yet. - e.preventDefault(); - // Submit data. - statusFieldInstsance.submitUnenrolFormAjax(modal, unenrolParams); - }); - - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - // Display the delete confirmation modal. - modal.show(); - }).fail(Notification.exception); - }); - }; - - /** - * Private method - * - * @method bindStatusDetails - * @private - */ - StatusFieldActions.prototype.bindStatusDetails = function() { - $(SELECTORS.SHOW_DETAILS).click(function(e) { - e.preventDefault(); - - var detailsButton = $(this); - var parentContainer = detailsButton.parent(); - var context = { - "fullname": parentContainer.data('fullname'), - "coursename": parentContainer.data('coursename'), - "enrolinstancename": parentContainer.data('enrolinstancename'), - "status": parentContainer.data('status'), - "statusclass": parentContainer.find('span').attr('class'), - "timestart": parentContainer.data('timestart'), - "timeend": parentContainer.data('timeend'), - "timeenrolled": parentContainer.data('timeenrolled') - }; - - // Get default string for the modal and modal type. - var strings = [ - { - key: 'enroldetails', - component: 'enrol' - } - ]; - - // Find the edit enrolment link. - var editEnrolLink = detailsButton.next(SELECTORS.EDIT_ENROLMENT); - if (editEnrolLink.length) { - // If there's an edit enrolment link for this user, clone it into the context for the modal. - context.editenrollink = $('
').append(editEnrolLink.clone()).html(); - } - - var modalStringsPromise = Str.get_strings(strings); - var modalPromise = ModalFactory.create({large: true, type: ModalFactory.types.CANCEL}); - $.when(modalStringsPromise, modalPromise).done(function(strings, modal) { - var modalBodyPromise = Template.render('core_user/status_details', context); - modal.setTitle(strings[0]); - modal.setBody(modalBodyPromise); - - if (editEnrolLink.length) { - modal.getRoot().on('click', SELECTORS.EDIT_ENROLMENT, function(e) { - e.preventDefault(); - modal.hide(); - // Trigger click event for the edit enrolment link to show the edit enrolment modal. - $(editEnrolLink).trigger('click'); - }); - } - - modal.show(); - - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - }).fail(Notification.exception); - }); - }; - - /** - * Private method - * - * @method submitEditFormAjax - * @param {Object} modal The the AMD modal object containing the form. - * @private - */ - StatusFieldActions.prototype.submitEditFormAjax = function(modal) { - var statusFieldInstsance = this; - var form = modal.getRoot().find('form'); - - // User enrolment ID. - var ueid = $(form).find('[name="ue"]').val(); - - var request = { - methodname: 'core_enrol_submit_user_enrolment_form', - args: { - formdata: form.serialize() - } - }; - - Ajax.call([request])[0].done(function(data) { - if (data.result) { - // Dismiss the modal. - modal.hide(); - - // Reload the page, don't show changed data warnings. - if (typeof window.M.core_formchangechecker !== "undefined") { - window.M.core_formchangechecker.reset_form_dirty_state(); - } - window.location.reload(); - } else { - // Serialise the form data and reload the form fragment to show validation errors. - var formData = JSON.stringify(form.serialize()); - modal.setBody(statusFieldInstsance.getBody(ueid, formData)); - } - }).fail(Notification.exception); - }; - - /** - * Private method - * - * @method submitUnenrolFormAjax - * @param {Object} modal The the AMD modal object containing the form. - * @param {Object} unenrolParams The unenrol parameters. - * @private - */ - StatusFieldActions.prototype.submitUnenrolFormAjax = function(modal, unenrolParams) { - var request = { - methodname: 'core_enrol_unenrol_user_enrolment', - args: unenrolParams - }; - - Ajax.call([request])[0].done(function(data) { - if (data.result) { - // Dismiss the modal. - modal.hide(); - - // Reload the page, don't show changed data warnings. - if (typeof window.M.core_formchangechecker !== "undefined") { - window.M.core_formchangechecker.reset_form_dirty_state(); - } - window.location.reload(); - } else { - // Display an alert containing the error message - Notification.alert(data.errors[0].key, data.errors[0].message); - } - }).fail(Notification.exception); - }; - - /** - * Private method - * - * @method getBody - * @private - * @param {Number} ueid The user enrolment ID associated with the user. - * @param {string} formData Serialized string of the edit enrolment form data. - * @return {Promise} - */ - StatusFieldActions.prototype.getBody = function(ueid, formData) { - var params = { - 'ueid': ueid - }; - if (typeof formData !== 'undefined') { - params.formdata = formData; - } - return Fragment.loadFragment('enrol', 'user_enrolment_form', this.contextid, params).fail(Notification.exception); - }; - - return /** @alias module:core_user/editenrolment */ { - // Public variables and functions. - /** - * Every call to init creates a new instance of the class with it's own event listeners etc. - * - * @method init - * @public - * @param {object} config - config variables for the module. - */ - init: function(config) { - (new StatusFieldActions(config)); - } - }; + showStatusDetails(showDetailsLink); + } }); +}; + +/** + * Show the edit dialogue. + * + * @param {HTMLElement} link + * @param {Function} getBody Function to get the body for the specified user enrolment + */ +const showEditDialogue = (link, getBody) => { + const container = getStatusContainer(link); + const userEnrolmentId = getUserEnrolmentIdFromLink(link); + + ModalFactory.create({ + large: true, + title: Str.get_string('edituserenrolment', 'enrol', container.dataset.fullname), + type: ModalFactory.types.SAVE_CANCEL, + body: getBody(userEnrolmentId) + }) + .then(modal => { + // Handle save event. + modal.getRoot().on(ModalEvents.save, e => { + // Don't close the modal yet. + e.preventDefault(); + + // Submit form data. + submitEditFormAjax(link, getBody, modal, userEnrolmentId, container.dataset); + }); + + // Handle hidden event. + modal.getRoot().on(ModalEvents.hidden, () => { + // Destroy when hidden. + modal.destroy(); + }); + + // Show the modal. + modal.show(); + + return modal; + }) + .catch(Notification.exception); +}; + +/** + * Show and handle the unenrolment confirmation dialogue. + * + * @param {HTMLElement} link + */ +const showUnenrolConfirmation = link => { + const container = getStatusContainer(link); + const userEnrolmentId = getUserEnrolmentIdFromLink(link); + + ModalFactory.create({ + type: ModalFactory.types.SAVE_CANCEL, + }) + .then(modal => { + // Handle confirm event. + modal.getRoot().on(ModalEvents.save, e => { + // Don't close the modal yet. + e.preventDefault(); + + // Submit data. + submitUnenrolFormAjax( + link, + modal, + { + ueid: userEnrolmentId, + }, + container.dataset + ); + }); + + // Handle hidden event. + modal.getRoot().on(ModalEvents.hidden, () => { + // Destroy when hidden. + modal.destroy(); + }); + + // Display the delete confirmation modal. + modal.show(); + + const stringData = [ + { + key: 'unenrol', + component: 'enrol', + }, + { + key: 'unenrolconfirm', + component: 'enrol', + param: { + user: container.dataset.fullname, + course: container.dataset.coursename, + enrolinstancename: container.dataset.enrolinstancename, + } + } + ]; + + return Promise.all([Str.get_strings(stringData), modal]); + }) + .then(([strings, modal]) => { + modal.setTitle(strings[0]); + modal.setSaveButtonText(strings[0]); + modal.setBody(strings[1]); + + return modal; + }) + .catch(Notification.exception); +}; + +/** + * Show the user details dialogue. + * + * @param {HTMLElement} link + */ +const showStatusDetails = link => { + const container = getStatusContainer(link); + + const context = { + editenrollink: '', + statusclass: container.querySelector('span.badge').getAttribute('class'), + ...container.dataset, + }; + + // Find the edit enrolment link. + const editEnrolLink = container.querySelector(Selectors.editEnrolment); + if (editEnrolLink) { + // If there's an edit enrolment link for this user, clone it into the context for the modal. + context.editenrollink = editEnrolLink.outerHTML; + } + + ModalFactory.create({ + large: true, + type: ModalFactory.types.CANCEL, + title: Str.get_string('enroldetails', 'enrol'), + body: Templates.render('core_user/status_details', context), + }) + .then(modal => { + if (editEnrolLink) { + modal.getRoot().on('click', Selectors.editEnrolment, e => { + e.preventDefault(); + modal.hide(); + + // Trigger click event for the edit enrolment link to show the edit enrolment modal. + editEnrolLink.click(); + }); + } + + modal.show(); + + // Handle hidden event. + modal.getRoot().on(ModalEvents.hidden, () => modal.destroy()); + + return modal; + }) + .catch(Notification.exception); +}; + +/** + * Submit the edit dialogue. + * + * @param {HTMLElement} clickedLink + * @param {Function} getBody + * @param {Object} modal + * @param {Number} userEnrolmentId + * @param {Object} userData + */ +const submitEditFormAjax = (clickedLink, getBody, modal, userEnrolmentId, userData) => { + const form = modal.getRoot().find('form'); + + Repository.submitUserEnrolmentForm(form.serialize()) + .then(data => { + if (!data.result) { + throw data.result; + } + + // Dismiss the modal. + modal.hide(); + modal.destroy(); + + return data; + }) + .then(() => { + DynamicTable.refreshTableContent(getDynamicTableFromLink(clickedLink)); + + return Str.get_string('enrolmentupdatedforuser', 'core_enrol', userData); + }) + .then(notificationString => { + notifyUser(notificationString); + + return; + }) + .catch(() => { + modal.setBody(getBody(userEnrolmentId, JSON.stringify(form.serialize()))); + + return modal; + }); +}; + +/** + * Submit the unenrolment form. + * + * @param {HTMLElement} clickedLink + * @param {Object} modal + * @param {Object} args + * @param {Object} userData + */ +const submitUnenrolFormAjax = (clickedLink, modal, args, userData) => { + Repository.unenrolUser(args.ueid) + .then(data => { + if (!data.result) { + // Display an alert containing the error message + Notification.alert(data.errors[0].key, data.errors[0].message); + + return data; + } + + // Dismiss the modal. + modal.hide(); + modal.destroy(); + + return data; + }) + .then(() => { + DynamicTable.refreshTableContent(getDynamicTableFromLink(clickedLink)); + + return Str.get_string('unenrolleduser', 'core_enrol', userData); + }) + .then(notificationString => { + notifyUser(notificationString); + + return; + }) + .catch(Notification.exception); +}; + +/** + * Get the body fragment. + * + * @param {Number} contextId + * @param {Number} ueid The user enrolment id + * @param {Object} formdata + * @returns {Promise} + */ +const getBody = (contextId, ueid, formdata = null) => Fragment.loadFragment( + 'enrol', + 'user_enrolment_form', + contextId, + { + ueid, + formdata, + } +); + +/** + * Initialise the statu field handler. + * + * @param {Number} contextid + * @param {Number} uniqueid + */ +export const init = ({contextid, uniqueid}) => { + registerEventListeners(contextid, uniqueid); +}; diff --git a/user/classes/table/participants.php b/user/classes/table/participants.php index 2f9c5ca3c82..b1f43958507 100644 --- a/user/classes/table/participants.php +++ b/user/classes/table/participants.php @@ -239,7 +239,10 @@ class participants extends \table_sql implements dynamic_table { parent::out($pagesize, $useinitialsbar, $downloadhelpbutton); if (has_capability('moodle/course:enrolreview', $this->context)) { - $params = ['contextid' => $this->context->id, 'courseid' => $this->course->id]; + $params = [ + 'contextid' => $this->context->id, + 'uniqueid' => $this->uniqueid, + ]; $PAGE->requires->js_call_amd('core_user/status_field', 'init', [$params]); } }