Rev 1 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
{"version":3,"file":"filter.min.js","sources":["../src/filter.js"],"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 <http://www.gnu.org/licenses/>.\n\n/**\n * Question bank filter management.\n *\n * @module core_question/filter\n * @copyright 2021 Tomo Tsuyuki <tomotsuyuki@catalyst-au.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Core
Filter from 'core/datafilter';\nimport Notification from 'core/notification';\nimport Selectors from 'core/datafilter/selectors';\nimport Templates from 'core/templates';\nimport Fragment from 'core/fragment';\nimport {getString} from 'core/str';\nimport {addIconToContainerRemoveOnCompletion} from 'core/loadingicon';\n\n/**\n * Initialise the question bank filter on the element with the given id.\n *\n * @param {String} filterRegionId ID of the HTML element containing the filters.\n * @param {String} defaultcourseid Course ID for the default course to pass back to the view.\n * @param {String} defaultcategoryid Question bank category ID for the default course to pass back to the view.\n * @param {Number} perpage The number of questions to display per page.\n * @param {Number} bankContextId Context ID of the question bank being filtered.\n * @param {Number} quizCmId Course module ID of the quiz as the viewing context.\n * @param {string} component Frankenstyle name of the component for the fragment API callba
ck (e.g. core_question)\n * @param {string} callback Name of the callback for the fragment API (e.g question_data)\n * @param {string} view The class name of the question bank view class used for this page.\n * @param {Number} cmid If we are in an activitiy, the course module ID.\n * @param {Object} pagevars JSON-encoded parameters from passed from the view, including filters and jointype.\n * @param {Object} extraparams JSON-encoded additional parameters specific to this view class, used for re-rendering the view.\n */\nexport const init = async(\n filterRegionId,\n defaultcourseid,\n defaultcategoryid,\n perpage,\n bankContextId,\n quizCmId,\n component,\n callback,\n view,\n cmid,\n pagevars,\n extraparams,\n) => {\n\n const SELECTORS = {\n QUESTION_CONTAINER_ID: '#questionscontainer',\n QUESTION_TABLE: '#questionscontainer table',\n SORT_LINK: '#questionscontainer div.sorters a',\n PAGINATION_LINK: '#questionscontainer a[href].page-link',
\n LASTCHANGED_FIELD: '#questionsubmit input[name=lastchanged]',\n BULK_ACTIONS: '#bulkactionsui-container input',\n MENU_ACTIONS: '.menu-action',\n EDIT_SWITCH: '.editmode-switch-form input[name=setmode]',\n EDIT_SWITCH_URL: '.editmode-switch-form input[name=pageurl]',\n SHOW_ALL_LINK: '[data-filteraction=\"showall\"]',\n };\n\n const filterSet = document.querySelector(`#${filterRegionId}`);\n\n const viewData = {\n extraparams: JSON.stringify(extraparams),\n cmid,\n view,\n cat: defaultcategoryid,\n courseid: defaultcourseid,\n filter: {},\n jointype: 0,\n qpage: 0,\n qperpage: perpage,\n sortdata: {},\n lastchanged: document.querySelector(SELECTORS.LASTCHANGED_FIELD)?.value ?? null,\n };\n\n let sortData = {};\n const defaultSort = document.querySelector(SELECTORS.QUESTION_TABLE)?.dataset?.defaultsort;\n if (defaultSort) {\n sortData = JSON.parse(defaultSort);\
n }\n\n const [\n showAllText,\n showPerPageText,\n ] = await Promise.all([\n getString('showall', 'core', ''),\n getString('showperpage', 'core', extraparams.defaultqperpage),\n ]);\n\n /**\n * Retrieve table data.\n *\n * @param {Object} filterdata data\n * @param {Promise} pendingPromise pending promise\n */\n const applyFilter = (filterdata, pendingPromise) => {\n // Reload the questions based on the specified filters. If no filters are provided,\n // use the default category filter condition.\n if (filterdata) {\n // Main join types.\n viewData.jointype = parseInt(filterSet.dataset.filterverb, 10);\n delete filterdata.jointype;\n // Retrieve filter info.\n viewData.filter = filterdata;\n if (Object.keys(filterdata).length !== 0) {\n if (!isNaN(viewData.jointype)) {\n filterdata.jointype = viewData.jointype;\n
}\n }\n }\n // Load questions for first page.\n viewData.filter = JSON.stringify(filterdata);\n viewData.sortdata = JSON.stringify(sortData);\n viewData.quizcmid = quizCmId;\n\n const questionscontainer = document.querySelector(SELECTORS.QUESTION_CONTAINER_ID);\n // Clear the contents of the element, then append the loading icon.\n questionscontainer.innerHTML = '';\n addIconToContainerRemoveOnCompletion(questionscontainer, pendingPromise);\n\n Fragment.loadFragment(component, callback, bankContextId, viewData)\n // Render questions for first page and pagination.\n .then((questionhtml, jsfooter) => {\n updateUrlParams(filterdata);\n if (questionhtml === undefined) {\n questionhtml = '';\n }\n if (jsfooter === undefined) {\n jsfooter = '';\n }\n Templates.replaceNode(questionsc
ontainer, questionhtml, jsfooter);\n // Resolve filter promise.\n if (pendingPromise) {\n pendingPromise.resolve();\n }\n return {questionhtml, jsfooter};\n })\n .catch(Notification.exception);\n };\n\n // Init core filter processor with apply callback.\n const coreFilter = new CoreFilter(filterSet, applyFilter);\n coreFilter.activeFilters = {}; // Unset useless courseid filter.\n coreFilter.init();\n\n /**\n * Update URL Param based upon the current filter.\n *\n * @param {Object} filters Active filters.\n */\n const updateUrlParams = (filters) => {\n const url = new URL(location.href);\n const filterQuery = JSON.stringify(filters);\n url.searchParams.set('filter', filterQuery);\n history.pushState(filters, '', url);\n const editSwitch = document.querySelector(SELECTORS.EDIT_SWITCH);\n if (editSwitch) {\n const editSwit
chUrlInput = document.querySelector(SELECTORS.EDIT_SWITCH_URL);\n const editSwitchUrl = new URL(editSwitchUrlInput.value);\n editSwitchUrl.searchParams.set('filter', filterQuery);\n editSwitchUrlInput.value = editSwitchUrl;\n editSwitch.dataset.pageurl = editSwitchUrl;\n }\n };\n\n /**\n * Cleans URL parameters.\n */\n const cleanUrlParams = () => {\n const queryString = location.search;\n const urlParams = new URLSearchParams(queryString);\n if (urlParams.has('cmid')) {\n const cleanedUrl = new URL(location.href.replace(location.search, ''));\n cleanedUrl.searchParams.set('cmid', urlParams.get('cmid'));\n history.pushState({}, '', cleanedUrl);\n }\n\n if (urlParams.has('courseid')) {\n const cleanedUrl = new URL(location.href.replace(location.search, ''));\n cleanedUrl.searchParams.set('courseid', urlParams.get('courseid'));\n history.pushSt
ate({}, '', cleanedUrl);\n }\n };\n\n // Add listeners for the sorting, paging and clear actions.\n document.querySelector('.questionbankwindow').addEventListener('click', e => {\n const sortableLink = e.target.closest(SELECTORS.SORT_LINK);\n const paginationLink = e.target.closest(SELECTORS.PAGINATION_LINK);\n const clearLink = e.target.closest(Selectors.filterset.actions.resetFilters);\n const showallLink = e.target.closest(SELECTORS.SHOW_ALL_LINK);\n if (sortableLink) {\n e.preventDefault();\n const oldSort = sortData;\n sortData = {};\n sortData[sortableLink.dataset.sortname] = sortableLink.dataset.sortorder;\n for (const sortname in oldSort) {\n if (sortname !== sortableLink.dataset.sortname) {\n sortData[sortname] = oldSort[sortname];\n }\n }\n viewData.qpage = 0;\n coreFilter.updateTableFromFilter(false);\n }\
n if (paginationLink) {\n e.preventDefault();\n const paginationURL = new URL(paginationLink.getAttribute(\"href\"));\n const qpage = paginationURL.searchParams.get('qpage');\n if (paginationURL.search !== null) {\n viewData.qpage = qpage;\n coreFilter.updateTableFromFilter(false);\n }\n }\n if (clearLink) {\n cleanUrlParams();\n }\n if (showallLink) {\n\n e.preventDefault();\n\n // Toggle between showing all and going back to the original qperpage.\n if (Number(showallLink.dataset.status) === 0) {\n viewData.qperpage = extraparams.maxqperpage;\n showallLink.dataset.status = 1;\n showallLink.innerText = showPerPageText;\n } else {\n viewData.qperpage = extraparams.defaultqperpage;\n showallLink.dataset.status = 0;\n showallLink.innerText = showAllT
ext;\n }\n viewData.qpage = 0;\n coreFilter.updateTableFromFilter();\n }\n });\n\n // Run apply filter at page load.\n let initialFilters;\n let jointype = null;\n if (pagevars.filter) {\n // Load initial filter based on page vars.\n initialFilters = pagevars.filter;\n if (pagevars.jointype) {\n jointype = pagevars.jointype;\n }\n }\n\n if (Object.entries(initialFilters).length !== 0) {\n // Remove the default empty filter row.\n const emptyFilterRow = filterSet.querySelector(Selectors.filterset.regions.emptyFilterRow);\n if (emptyFilterRow) {\n emptyFilterRow.remove();\n }\n\n // Add filters.\n let rowcount = 0;\n for (const urlFilter in initialFilters) {\n if (urlFilter === 'jointype') {\n jointype = initialFilters[urlFilter];\n continue;\n }\n // Add each filter row.\n rowcou
nt += 1;\n const filterdata = {\n filtertype: urlFilter,\n values: initialFilters[urlFilter].values,\n jointype: initialFilters[urlFilter].jointype,\n filteroptions: initialFilters[urlFilter].filteroptions,\n rownum: rowcount\n };\n coreFilter.addFilterRow(filterdata);\n }\n coreFilter.filterSet.dataset.filterverb = jointype;\n\n // Since we must filter by category, it does not make sense to allow the top-level \"match any\" or \"match none\" conditions,\n // as this would exclude the category. Remove those options and disable the select.\n const join = coreFilter.filterSet.querySelector(Selectors.filterset.fields.join);\n join.querySelectorAll(`option:not([value=\"${jointype}\"])`).forEach((option) => option.remove());\n join.disabled = true;\n }\n};\n"],"names":["async","filterRegionId","defaultcourseid","defaultcategoryid","perpage","bankContextId
","quizCmId","component","callback","view","cmid","pagevars","extraparams","SELECTORS","filterSet","document","querySelector","viewData","JSON","stringify","cat","courseid","filter","jointype","qpage","qperpage","sortdata","lastchanged","_document$querySelect2","value","sortData","defaultSort","_document$querySelect3","dataset","_document$querySelect4","defaultsort","parse","showAllText","showPerPageText","Promise","all","defaultqperpage","coreFilter","CoreFilter","filterdata","pendingPromise","parseInt","filterverb","Object","keys","length","isNaN","quizcmid","questionscontainer","innerHTML","loadFragment","then","questionhtml","jsfooter","updateUrlParams","undefined","replaceNode","resolve","catch","Notification","exception","activeFilters","init","filters","url","URL","location","href","filterQuery","searchParams","set","history","pushState","editSwitch","editSwitchUrlInput","editSwitchUrl","pageurl","initialFilters","addEventListener","e","sortableLink","target","closest","paginationLink","clearLink","Se
lectors","filterset","actions","resetFilters","showallLink","preventDefault","oldSort","sortname","sortorder","updateTableFromFilter","paginationURL","getAttribute","get","search","queryString","urlParams","URLSearchParams","has","cleanedUrl","replace","cleanUrlParams","Number","status","maxqperpage","innerText","entries","emptyFilterRow","regions","remove","rowcount","urlFilter","filtertype","values","filteroptions","rownum","addFilterRow","join","fields","querySelectorAll","forEach","option","disabled"],"mappings":";;;;;;;4UA+CoBA,MAChBC,eACAC,gBACAC,kBACAC,QACAC,cACAC,SACAC,UACAC,SACAC,KACAC,KACAC,SACAC,oHAGMC,gCACqB,sBADrBA,yBAEc,4BAFdA,oBAGS,oCAHTA,0BAIe,wCAJfA,4BAKiB,0CALjBA,sBAQW,4CARXA,0BASe,4CATfA,wBAUa,gCAGbC,UAAYC,SAASC,yBAAkBf,iBAEvCgB,SAAW,CACbL,YAAaM,KAAKC,UAAUP,aAC5BF,KAAAA,KACAD,KAAAA,KACAW,IAAKjB,kBACLkB,SAAUnB,gBACVoB,OAAQ,GACRC,SAAU,EACVC,MAAO,EACPC,SAAUrB,QACVsB,SAAU,GACVC,yEAAaZ,SAASC,cAAcH,sEAAvBe,uBAAqDC,6DAAS,UAG3EC,SAAW,SACTC,2CAAchB,SAASC,cAAcH,4FAAvBmB,uBAAkDC,iDAAlDC,uBAA2DC,YAC3E
J,cACAD,SAAWZ,KAAKkB,MAAML,oBAItBM,YACAC,uBACMC,QAAQC,IAAI,EAClB,kBAAU,UAAW,OAAQ,KAC7B,kBAAU,cAAe,OAAQ5B,YAAY6B,mBAuD3CC,WAAa,IAAIC,oBAAW7B,WA9Cd,CAAC8B,WAAYC,kBAGzBD,aAEA3B,SAASM,SAAWuB,SAAShC,UAAUmB,QAAQc,WAAY,WACpDH,WAAWrB,SAElBN,SAASK,OAASsB,WACqB,IAAnCI,OAAOC,KAAKL,YAAYM,SACnBC,MAAMlC,SAASM,YAChBqB,WAAWrB,SAAWN,SAASM,YAK3CN,SAASK,OAASJ,KAAKC,UAAUyB,YACjC3B,SAASS,SAAWR,KAAKC,UAAUW,UACnCb,SAASmC,SAAW9C,eAEd+C,mBAAqBtC,SAASC,cAAcH,iCAElDwC,mBAAmBC,UAAY,yDACMD,mBAAoBR,kCAEhDU,aAAahD,UAAWC,SAAUH,cAAeY,UAErDuC,MAAK,CAACC,aAAcC,YACjBC,gBAAgBf,iBACKgB,IAAjBH,eACAA,aAAe,SAEFG,IAAbF,WACAA,SAAW,uBAELG,YAAYR,mBAAoBI,aAAcC,UAEpDb,gBACAA,eAAeiB,UAEZ,CAACL,aAAAA,aAAcC,SAAAA,aAEzBK,MAAMC,sBAAaC,cAK5BvB,WAAWwB,cAAgB,GAC3BxB,WAAWyB,aAOLR,gBAAmBS,gBACfC,IAAM,IAAIC,IAAIC,SAASC,MACvBC,YAAcvD,KAAKC,UAAUiD,SACnCC,IAAIK,aAAaC,IAAI,SAAUF,aAC/BG,QAAQC,UAAUT,QAAS,GAAIC,WACzBS,WAAa/D,SAASC,cAAcH,0BACtCiE,WAAY,OACNC,mBAAqBhE,SAASC,cAAcH,2BAC5CmE,cAAgB,IAAIV,IAAIS,mBAAmBlD,OACjDmD,cAAcN,aAAaC,IAAI,SAAUF,aACzCM,mBAAmBlD,MAAQmD,cAC3BF
,WAAW7C,QAAQgD,QAAUD,oBA0EjCE,eAlDJnE,SAASC,cAAc,uBAAuBmE,iBAAiB,SAASC,UAC9DC,aAAeD,EAAEE,OAAOC,QAAQ1E,qBAChC2E,eAAiBJ,EAAEE,OAAOC,QAAQ1E,2BAClC4E,UAAYL,EAAEE,OAAOC,QAAQG,mBAAUC,UAAUC,QAAQC,cACzDC,YAAcV,EAAEE,OAAOC,QAAQ1E,4BACjCwE,aAAc,CACdD,EAAEW,uBACIC,QAAUlE,SAChBA,SAAW,GACXA,SAASuD,aAAapD,QAAQgE,UAAYZ,aAAapD,QAAQiE,cAC1D,MAAMD,YAAYD,QACfC,WAAaZ,aAAapD,QAAQgE,WAClCnE,SAASmE,UAAYD,QAAQC,WAGrChF,SAASO,MAAQ,EACjBkB,WAAWyD,uBAAsB,MAEjCX,eAAgB,CAChBJ,EAAEW,uBACIK,cAAgB,IAAI9B,IAAIkB,eAAea,aAAa,SACpD7E,MAAQ4E,cAAc1B,aAAa4B,IAAI,SAChB,OAAzBF,cAAcG,SACdtF,SAASO,MAAQA,MACjBkB,WAAWyD,uBAAsB,IAGrCV,WA5Ce,YACbe,YAAcjC,SAASgC,OACvBE,UAAY,IAAIC,gBAAgBF,gBAClCC,UAAUE,IAAI,QAAS,OACjBC,WAAa,IAAItC,IAAIC,SAASC,KAAKqC,QAAQtC,SAASgC,OAAQ,KAClEK,WAAWlC,aAAaC,IAAI,OAAQ8B,UAAUH,IAAI,SAClD1B,QAAQC,UAAU,GAAI,GAAI+B,eAG1BH,UAAUE,IAAI,YAAa,OACrBC,WAAa,IAAItC,IAAIC,SAASC,KAAKqC,QAAQtC,SAASgC,OAAQ,KAClEK,WAAWlC,aAAaC,IAAI,WAAY8B,UAAUH,IAAI,aACtD1B,QAAQC,UAAU,GAAI,GAAI+B,cAiC1BE,GAEAhB,cAEAV,EAAEW,iBAGyC,IAAvCgB,OAAOjB,YAAY7D,QAAQ+E,S
AC3B/F,SAASQ,SAAWb,YAAYqG,YAChCnB,YAAY7D,QAAQ+E,OAAS,EAC7BlB,YAAYoB,UAAY5E,kBAExBrB,SAASQ,SAAWb,YAAY6B,gBAChCqD,YAAY7D,QAAQ+E,OAAS,EAC7BlB,YAAYoB,UAAY7E,aAE5BpB,SAASO,MAAQ,EACjBkB,WAAWyD,gCAMf5E,SAAW,QACXZ,SAASW,SAET4D,eAAiBvE,SAASW,OACtBX,SAASY,WACTA,SAAWZ,SAASY,WAIkB,IAA1CyB,OAAOmE,QAAQjC,gBAAgBhC,OAAc,OAEvCkE,eAAiBtG,UAAUE,cAAc0E,mBAAUC,UAAU0B,QAAQD,gBACvEA,gBACAA,eAAeE,aAIfC,SAAW,MACV,MAAMC,aAAatC,eAAgB,IAClB,aAAdsC,UAA0B,CAC1BjG,SAAW2D,eAAesC,oBAI9BD,UAAY,QACN3E,WAAa,CACf6E,WAAYD,UACZE,OAASxC,eAAesC,WAAWE,OACnCnG,SAAU2D,eAAesC,WAAWjG,SACpCoG,cAAezC,eAAesC,WAAWG,cACzCC,OAAQL,UAEZ7E,WAAWmF,aAAajF,YAE5BF,WAAW5B,UAAUmB,QAAQc,WAAaxB,eAIpCuG,KAAOpF,WAAW5B,UAAUE,cAAc0E,mBAAUC,UAAUoC,OAAOD,MAC3EA,KAAKE,8CAAuCzG,iBAAe0G,SAASC,QAAWA,OAAOZ,WACtFQ,KAAKK,UAAW"}