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,
// 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();
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';
* @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}) => {
return filterRow;
})
+ .then(result => {
+ pendingPromise.resolve();
+
+ return result;
+ })
.catch(Notification.exception);
};
* 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);
}
};
* 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);
// 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();
* 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);
})
.then(filterRow => {
// Refresh the table.
- updateTableFromFilter();
-
- return filterRow;
+ if (refreshContent) {
+ return updateTableFromFilter();
+ } else {
+ return filterRow;
+ }
})
.catch(Notification.exception);
};
* @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;
+ });
};
/**
filters.forEach(filterRow => {
const filterType = filterRow.querySelector(Selectors.filter.fields.type);
if (!filterType.value) {
- removeOrReplaceFilterRow(filterRow);
+ removeOrReplaceFilterRow(filterRow, false);
}
});
};
* @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.
const filterPromises = filterConfig.map(([filterType, filterData]) => {
if (filterType === 'courseid') {
// The courseid is a special case.
- return Promise.resolve();
+ return false;
}
const filterValues = filterData.values;
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);
};
/**
* @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);
};
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);
}
});
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();
}
};