Merge branch 'MDL-68977-master' of git://github.com/andrewnicols/moodle
authorJake Dallimore <jake@moodle.com>
Wed, 10 Jun 2020 07:36:44 +0000 (15:36 +0800)
committerJake Dallimore <jake@moodle.com>
Wed, 10 Jun 2020 07:36:44 +0000 (15:36 +0800)
12 files changed:
enrol/manual/amd/build/quickenrolment.min.js
enrol/manual/amd/build/quickenrolment.min.js.map
enrol/manual/amd/src/quickenrolment.js
lib/table/amd/build/dynamic.min.js
lib/table/amd/build/dynamic.min.js.map
lib/table/amd/src/dynamic.js
user/amd/build/local/participantsfilter/filter.min.js
user/amd/build/local/participantsfilter/filter.min.js.map
user/amd/build/participantsfilter.min.js
user/amd/build/participantsfilter.min.js.map
user/amd/src/local/participantsfilter/filter.js
user/amd/src/participantsfilter.js

index a451f2b..02411ec 100644 (file)
Binary files a/enrol/manual/amd/build/quickenrolment.min.js and b/enrol/manual/amd/build/quickenrolment.min.js differ
index 7561852..d587cfe 100644 (file)
Binary files a/enrol/manual/amd/build/quickenrolment.min.js.map and b/enrol/manual/amd/build/quickenrolment.min.js.map differ
index ee67d3c..1034c2b 100644 (file)
@@ -29,6 +29,7 @@ import ModalEvents from 'core/modal_events';
 import ModalFactory from 'core/modal_factory';
 import Notification from 'core/notification';
 import jQuery from 'jquery';
+import Pending from 'core/pending';
 import Prefetch from 'core/prefetch';
 
 const Selectors = {
@@ -85,6 +86,8 @@ const registerEventListeners = contextId => {
  * @returns {Promise}
  */
 const showModal = (dynamicTable, contextId) => {
+    const pendingPromise = new Pending('enrol_manual/quickenrolment:showModal');
+
     return ModalFactory.create({
         type: ModalFactory.types.SAVE_CANCEL,
         large: true,
@@ -130,6 +133,8 @@ const showModal = (dynamicTable, contextId) => {
         })
         .catch();
 
+        pendingPromise.resolve();
+
         return modal;
     })
     .catch(Notification.exception);
index 0060edc..11ddc73 100644 (file)
Binary files a/lib/table/amd/build/dynamic.min.js and b/lib/table/amd/build/dynamic.min.js differ
index 3cbcaea..089870b 100644 (file)
Binary files a/lib/table/amd/build/dynamic.min.js.map and b/lib/table/amd/build/dynamic.min.js.map differ
index b812a1f..899809b 100644 (file)
@@ -123,9 +123,14 @@ export const updateTable = (tableRoot, {
     checkTableIsDynamic(tableRoot);
 
     const pendingPromise = new Pending('core_table/dynamic:updateTable');
+    let tableConfigChanged = false;
 
     // Update sort fields.
     if (sortBy && sortOrder) {
+        // Always update the table if requested and there were sort fields.
+        // These fields are only ever normalised in the backend.
+        tableConfigChanged = true;
+
         const sortData = JSON.parse(tableRoot.dataset.tableSortData);
         sortData.unshift({
             sortby: sortBy,
@@ -136,33 +141,61 @@ export const updateTable = (tableRoot, {
 
     // Update initials.
     if (firstInitial !== null) {
+        if (tableRoot.dataset.tableFirstInitial !== firstInitial) {
+            tableConfigChanged = true;
+        }
+
         tableRoot.dataset.tableFirstInitial = firstInitial;
     }
 
     if (lastInitial !== null) {
+        if (tableRoot.dataset.tableLastInitial !== lastInitial) {
+            tableConfigChanged = true;
+        }
+
         tableRoot.dataset.tableLastInitial = lastInitial;
     }
 
     if (pageNumber !== null) {
+        if (tableRoot.dataset.tablePageNumber != pageNumber) {
+            tableConfigChanged = true;
+        }
+
         tableRoot.dataset.tablePageNumber = pageNumber;
     }
 
     if (pageSize !== null) {
+        if (tableRoot.dataset.tablePageSize != pageSize) {
+            tableConfigChanged = true;
+        }
+
         tableRoot.dataset.tablePageSize = pageSize;
     }
 
     // Update filters.
     if (filters) {
-        tableRoot.dataset.tableFilters = JSON.stringify(filters);
+        const filterJson = JSON.stringify(filters);
+
+        if (tableRoot.dataset.tableFilters !== filterJson) {
+            tableConfigChanged = true;
+        }
+
+        tableRoot.dataset.tableFilters = filterJson;
     }
 
     // Update hidden columns.
     if (hiddenColumns) {
-        tableRoot.dataset.tableHiddenColumns = JSON.stringify(hiddenColumns);
+        const columnJson = JSON.stringify(hiddenColumns);
+
+        if (tableRoot.dataset.tableHiddenColumns !== columnJson) {
+            tableConfigChanged = true;
+        }
+
+        tableRoot.dataset.tableHiddenColumns = columnJson;
     }
 
     // Refresh.
-    if (refreshContent) {
+    if (refreshContent && tableConfigChanged) {
         return refreshTableContent(tableRoot)
         .then(tableRoot => {
             pendingPromise.resolve();
index 0f13ff2..5c2801e 100644 (file)
Binary files a/user/amd/build/local/participantsfilter/filter.min.js and b/user/amd/build/local/participantsfilter/filter.min.js differ
index 1cc0896..a778082 100644 (file)
Binary files a/user/amd/build/local/participantsfilter/filter.min.js.map and b/user/amd/build/local/participantsfilter/filter.min.js.map differ
index 60a726d..9a8b390 100644 (file)
Binary files a/user/amd/build/participantsfilter.min.js and b/user/amd/build/participantsfilter.min.js differ
index 7965370..e986e19 100644 (file)
Binary files a/user/amd/build/participantsfilter.min.js.map and b/user/amd/build/participantsfilter.min.js.map differ
index 6670c2e..445dd3a 100644 (file)
@@ -184,7 +184,7 @@ export default class {
      * @returns {Number}
      */
     get jointype() {
-        return this.filterRoot.querySelector(Selectors.filter.fields.join).value;
+        return parseInt(this.filterRoot.querySelector(Selectors.filter.fields.join).value, 10);
     }
 
     /**
index 4e31a15..539909a 100644 (file)
@@ -27,6 +27,7 @@ import * as DynamicTable from 'core_table/dynamic';
 import GenericFilter from './local/participantsfilter/filter';
 import {get_strings as getStrings} from 'core/str';
 import Notification from 'core/notification';
+import Pending from 'core/pending';
 import Selectors from './local/participantsfilter/selectors';
 import Templates from 'core/templates';
 
@@ -57,6 +58,8 @@ export const init = participantsRegionId => {
      * @return {Promise}
      */
     const addFilterRow = () => {
+        const pendingPromise = new Pending('core_user/participantsfilter:addFilterRow');
+
         const rownum = 1 + getFilterRegion().querySelectorAll(Selectors.filter.region).length;
         return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {"rownumber": rownum})
         .then(({html, js}) => {
@@ -86,6 +89,11 @@ export const init = participantsRegionId => {
 
             return filterRow;
         })
+        .then(result => {
+            pendingPromise.resolve();
+
+            return result;
+        })
         .catch(Notification.exception);
     };
 
@@ -148,14 +156,15 @@ export const init = participantsRegionId => {
      * that it is replaced instead of being removed.
      *
      * @param {HTMLElement} filterRow
+     * @param {Bool} refreshContent Whether to refresh the table content when removing
      */
-    const removeOrReplaceFilterRow = filterRow => {
+    const removeOrReplaceFilterRow = (filterRow, refreshContent) => {
         const filterCount = getFilterRegion().querySelectorAll(Selectors.filter.region).length;
 
         if (filterCount === 1) {
-            replaceFilterRow(filterRow);
+            replaceFilterRow(filterRow, refreshContent);
         } else {
-            removeFilterRow(filterRow);
+            removeFilterRow(filterRow, refreshContent);
         }
     };
 
@@ -163,8 +172,12 @@ export const init = participantsRegionId => {
      * Remove the specified filter row and associated class.
      *
      * @param {HTMLElement} filterRow
+     * @param {Bool} refreshContent Whether to refresh the table content when removing
      */
-    const removeFilterRow = async filterRow => {
+    const removeFilterRow = async(filterRow, refreshContent = true) => {
+        const filterType = filterRow.querySelector(Selectors.filter.fields.type);
+        const hasFilterValue = !!filterType.value;
+
         // Remove the filter object.
         removeFilterObject(filterRow.dataset.filterType);
 
@@ -174,8 +187,10 @@ export const init = participantsRegionId => {
         // Update the list of available filter types.
         updateFiltersOptions();
 
-        // Refresh the table.
-        updateTableFromFilter();
+        if (hasFilterValue && refreshContent) {
+            // Refresh the table if there was any content in this row.
+            updateTableFromFilter();
+        }
 
         // Update filter fieldset legends.
         const filterLegends = await getAvailableFilterLegends();
@@ -190,10 +205,11 @@ export const init = participantsRegionId => {
      * Replace the specified filter row with a new one.
      *
      * @param {HTMLElement} filterRow
+     * @param {Bool} refreshContent Whether to refresh the table content when removing
      * @param {Number} rowNum The number used to label the filter fieldset legend (eg Row 1). Defaults to 1 (the first filter).
      * @return {Promise}
      */
-    const replaceFilterRow = (filterRow, rowNum = 1) => {
+    const replaceFilterRow = (filterRow, refreshContent = true, rowNum = 1) => {
         // Remove the filter object.
         removeFilterObject(filterRow.dataset.filterType);
 
@@ -227,9 +243,11 @@ export const init = participantsRegionId => {
         })
         .then(filterRow => {
             // Refresh the table.
-            updateTableFromFilter();
-
-            return filterRow;
+            if (refreshContent) {
+                return updateTableFromFilter();
+            } else {
+                return filterRow;
+            }
         })
         .catch(Notification.exception);
     };
@@ -257,11 +275,18 @@ export const init = participantsRegionId => {
      * @returns {Promise}
      */
     const removeAllFilters = () => {
+        const pendingPromise = new Pending('core_user/participantsfilter:setFilterFromConfig');
+
         const filters = getFilterRegion().querySelectorAll(Selectors.filter.region);
-        filters.forEach(filterRow => removeOrReplaceFilterRow(filterRow));
+        filters.forEach(filterRow => removeOrReplaceFilterRow(filterRow, false));
 
         // Refresh the table.
-        return updateTableFromFilter();
+        return updateTableFromFilter()
+        .then(result => {
+            pendingPromise.resolve();
+
+            return result;
+        });
     };
 
     /**
@@ -272,7 +297,7 @@ export const init = participantsRegionId => {
         filters.forEach(filterRow => {
             const filterType = filterRow.querySelector(Selectors.filter.fields.type);
             if (!filterType.value) {
-                removeOrReplaceFilterRow(filterRow);
+                removeOrReplaceFilterRow(filterRow, false);
             }
         });
     };
@@ -322,13 +347,14 @@ export const init = participantsRegionId => {
      * @param {Object} config
      * @param {Number} config.jointype
      * @param {Object} config.filters
+     * @returns {Promise}
      */
     const setFilterFromConfig = config => {
         const filterConfig = Object.entries(config.filters);
 
         if (!filterConfig.length) {
             // There are no filters to set from.
-            return;
+            return Promise.resolve();
         }
 
         // Set the main join type.
@@ -337,7 +363,7 @@ export const init = participantsRegionId => {
         const filterPromises = filterConfig.map(([filterType, filterData]) => {
             if (filterType === 'courseid') {
                 // The courseid is a special case.
-                return Promise.resolve();
+                return false;
             }
 
             const filterValues = filterData.values;
@@ -345,18 +371,21 @@ export const init = participantsRegionId => {
             if (!filterValues.length) {
                 // There are no values for this filter.
                 // Skip it.
-                return Promise.resolve();
+                return false;
             }
 
             return addFilterRow().then(([filterRow]) => addFilter(filterRow, filterType, filterValues));
-        });
+        }).filter(promise => promise);
 
-        Promise.all(filterPromises).then(() => {
+        if (!filterPromises.length) {
+            return Promise.resolve();
+        }
+
+        return Promise.all(filterPromises).then(() => {
             return removeEmptyFilters();
         })
         .then(updateFiltersOptions)
-        .then(updateTableFromFilter)
-        .catch();
+        .then(updateTableFromFilter);
     };
 
     /**
@@ -365,13 +394,25 @@ export const init = participantsRegionId => {
      * @return {Promise}
      */
     const updateTableFromFilter = () => {
+        const pendingPromise = new Pending('core_user/participantsfilter:updateTableFromFilter');
+
+        const filters = {};
+        Object.values(activeFilters).forEach(filter => {
+            filters[filter.filterValue.name] = filter.filterValue;
+        });
+
         return DynamicTable.setFilters(
             DynamicTable.getTableFromId(filterSet.dataset.tableRegion),
             {
-                filters: Object.values(activeFilters).map(filter => filter.filterValue),
-                jointype: filterSet.querySelector(Selectors.filterset.fields.join).value,
+                jointype: parseInt(filterSet.querySelector(Selectors.filterset.fields.join).value, 10),
+                filters,
             }
         )
+        .then(result => {
+            pendingPromise.resolve();
+
+            return result;
+        })
         .catch(Notification.exception);
     };
 
@@ -428,7 +469,7 @@ export const init = participantsRegionId => {
         if (e.target.closest(Selectors.filter.actions.remove)) {
             e.preventDefault();
 
-            removeOrReplaceFilterRow(e.target.closest(Selectors.filter.region));
+            removeOrReplaceFilterRow(e.target.closest(Selectors.filter.region), true);
         }
     });
 
@@ -449,7 +490,10 @@ export const init = participantsRegionId => {
     const tableRoot = DynamicTable.getTableFromId(filterSet.dataset.tableRegion);
     const initialFilters = DynamicTable.getFilters(tableRoot);
     if (initialFilters) {
+        const initialFilterPromise = new Pending('core_user/participantsfilter:setFilterFromConfig');
         // Apply the initial filter configuration.
-        setFilterFromConfig(initialFilters);
+        setFilterFromConfig(initialFilters)
+        .then(() => initialFilterPromise.resolve())
+        .catch();
     }
 };