| Línea 80... |
Línea 80... |
| 80 |
CustomEvents.events.activate,
|
80 |
CustomEvents.events.activate,
|
| 81 |
CustomEvents.events.keyboardActivate
|
81 |
CustomEvents.events.keyboardActivate
|
| 82 |
];
|
82 |
];
|
| Línea 83... |
Línea 83... |
| 83 |
|
83 |
|
| 84 |
const fetchModuleData = (() => {
|
84 |
const fetchModuleData = (() => {
|
| Línea 85... |
Línea 85... |
| 85 |
let innerPromise = null;
|
85 |
let innerPromises = new Map();
|
| 86 |
|
86 |
|
| 87 |
return () => {
|
87 |
return (sectionNum) => {
|
| 88 |
if (!innerPromise) {
|
- |
|
| 89 |
innerPromise = new Promise((resolve) => {
|
- |
|
| 90 |
resolve(Repository.activityModules(courseId));
|
88 |
if (innerPromises.has(sectionNum)) {
|
| Línea 91... |
Línea 89... |
| 91 |
});
|
89 |
return innerPromises.get(sectionNum);
|
| - |
|
90 |
}
|
| - |
|
91 |
|
| - |
|
92 |
innerPromises.set(
|
| - |
|
93 |
sectionNum,
|
| - |
|
94 |
new Promise((resolve) => {
|
| - |
|
95 |
resolve(Repository.activityModules(courseId, sectionNum));
|
| 92 |
}
|
96 |
})
|
| 93 |
|
97 |
);
|
| Línea 94... |
Línea 98... |
| 94 |
return innerPromise;
|
98 |
return innerPromises.get(sectionNum);
|
| 95 |
};
|
99 |
};
|
| Línea 96... |
Línea 100... |
| 96 |
})();
|
100 |
})();
|
| 97 |
|
101 |
|
| 98 |
const fetchFooterData = (() => {
|
102 |
const fetchFooterData = (() => {
|
| 99 |
let footerInnerPromise = null;
|
103 |
let footerInnerPromise = null;
|
| 100 |
|
104 |
|
| 101 |
return (sectionId) => {
|
105 |
return (sectionNum) => {
|
| Línea 102... |
Línea 106... |
| 102 |
if (!footerInnerPromise) {
|
106 |
if (!footerInnerPromise) {
|
| 103 |
footerInnerPromise = new Promise((resolve) => {
|
107 |
footerInnerPromise = new Promise((resolve) => {
|
| Línea 114... |
Línea 118... |
| 114 |
// Display module chooser event listeners.
|
118 |
// Display module chooser event listeners.
|
| 115 |
events.forEach((event) => {
|
119 |
events.forEach((event) => {
|
| 116 |
document.addEventListener(event, async(e) => {
|
120 |
document.addEventListener(event, async(e) => {
|
| 117 |
if (e.target.closest(selectors.elements.sectionmodchooser)) {
|
121 |
if (e.target.closest(selectors.elements.sectionmodchooser)) {
|
| 118 |
let caller;
|
122 |
let caller;
|
| - |
|
123 |
let sectionnum;
|
| 119 |
// We need to know who called this.
|
124 |
// We need to know who called this.
|
| 120 |
// Standard courses use the ID in the main section info.
|
125 |
// Standard courses use the ID in the main section info.
|
| 121 |
const sectionDiv = e.target.closest(selectors.elements.section);
|
126 |
const sectionDiv = e.target.closest(selectors.elements.section);
|
| 122 |
// Front page courses need some special handling.
|
127 |
// Front page courses need some special handling.
|
| 123 |
const button = e.target.closest(selectors.elements.sectionmodchooser);
|
128 |
const button = e.target.closest(selectors.elements.sectionmodchooser);
|
| Línea 124... |
Línea 129... |
| 124 |
|
129 |
|
| 125 |
// If we don't have a section ID use the fallback ID.
|
130 |
// If we don't have a section number use the fallback ID.
|
| 126 |
// We always want the sectionDiv caller first as it keeps track of section ID's after DnD changes.
|
131 |
// We always want the sectionDiv caller first as it keeps track of section number's after DnD changes.
|
| 127 |
// The button attribute is always just a fallback for us as the section div is not always available.
|
132 |
// The button attribute is always just a fallback for us as the section div is not always available.
|
| 128 |
// A YUI change could be done maybe to only update the button attribute but we are going for minimal change here.
|
133 |
// A YUI change could be done maybe to only update the button attribute but we are going for minimal change here.
|
| 129 |
if (sectionDiv !== null && sectionDiv.hasAttribute('data-sectionid')) {
|
134 |
if (sectionDiv !== null && sectionDiv.hasAttribute('data-number')) {
|
| 130 |
// We check for attributes just in case of outdated contrib course formats.
|
135 |
// We check for attributes just in case of outdated contrib course formats.
|
| - |
|
136 |
caller = sectionDiv;
|
| 131 |
caller = sectionDiv;
|
137 |
sectionnum = sectionDiv.getAttribute('data-number');
|
| 132 |
} else {
|
138 |
} else {
|
| - |
|
139 |
caller = button;
|
| - |
|
140 |
|
| - |
|
141 |
if (caller.hasAttribute('data-sectionid')) {
|
| - |
|
142 |
window.console.warn(
|
| - |
|
143 |
'The data-sectionid attribute has been deprecated. ' +
|
| - |
|
144 |
'Please update your code to use data-sectionnum instead.'
|
| - |
|
145 |
);
|
| - |
|
146 |
caller.setAttribute('data-sectionnum', caller.dataset.sectionid);
|
| - |
|
147 |
}
|
| 133 |
caller = button;
|
148 |
sectionnum = caller.dataset.sectionnum;
|
| Línea 134... |
Línea 149... |
| 134 |
}
|
149 |
}
|
| 135 |
|
150 |
|
| 136 |
// We want to show the modal instantly but loading whilst waiting for our data.
|
151 |
// We want to show the modal instantly but loading whilst waiting for our data.
|
| 137 |
let bodyPromiseResolver;
|
152 |
let bodyPromiseResolver;
|
| 138 |
const bodyPromise = new Promise(resolve => {
|
153 |
const bodyPromise = new Promise(resolve => {
|
| Línea 139... |
Línea 154... |
| 139 |
bodyPromiseResolver = resolve;
|
154 |
bodyPromiseResolver = resolve;
|
| 140 |
});
|
155 |
});
|
| Línea 141... |
Línea 156... |
| 141 |
|
156 |
|
| 142 |
const footerData = await fetchFooterData(caller.dataset.sectionid);
|
157 |
const footerData = await fetchFooterData(sectionnum);
|
| 143 |
const sectionModal = buildModal(bodyPromise, footerData);
|
158 |
const sectionModal = buildModal(bodyPromise, footerData);
|
| 144 |
|
159 |
|
| 145 |
// Now we have a modal we should start fetching data.
|
160 |
// Now we have a modal we should start fetching data.
|
| 146 |
// If an error occurs while fetching the data, display the error within the modal.
|
161 |
// If an error occurs while fetching the data, display the error within the modal.
|
| 147 |
const data = await fetchModuleData().catch(async(e) => {
|
162 |
const data = await fetchModuleData(sectionnum).catch(async(e) => {
|
| 148 |
const errorTemplateData = {
|
163 |
const errorTemplateData = {
|
| Línea 154... |
Línea 169... |
| 154 |
// Early return if there is no module data.
|
169 |
// Early return if there is no module data.
|
| 155 |
if (!data) {
|
170 |
if (!data) {
|
| 156 |
return;
|
171 |
return;
|
| 157 |
}
|
172 |
}
|
| Línea 158... |
Línea 173... |
| 158 |
|
173 |
|
| 159 |
// Apply the section id to all the module instance links.
|
174 |
// Apply the section num to all the module instance links.
|
| 160 |
const builtModuleData = sectionIdMapper(
|
175 |
const builtModuleData = sectionMapper(
|
| 161 |
data,
|
176 |
data,
|
| 162 |
caller.dataset.sectionid,
|
177 |
sectionnum,
|
| 163 |
caller.dataset.sectionreturnid,
|
178 |
caller.dataset.sectionreturnnum,
|
| 164 |
caller.dataset.beforemod
|
179 |
caller.dataset.beforemod
|
| Línea 165... |
Línea 180... |
| 165 |
);
|
180 |
);
|
| 166 |
|
181 |
|
| 167 |
ChooserDialogue.displayChooser(
|
182 |
ChooserDialogue.displayChooser(
|
| 168 |
sectionModal,
|
183 |
sectionModal,
|
| 169 |
builtModuleData,
|
184 |
builtModuleData,
|
| 170 |
partiallyAppliedFavouriteManager(data, caller.dataset.sectionid),
|
185 |
partiallyAppliedFavouriteManager(data, sectionnum),
|
| Línea 171... |
Línea 186... |
| 171 |
footerData,
|
186 |
footerData,
|
| 172 |
);
|
187 |
);
|
| Línea 182... |
Línea 197... |
| 182 |
initialized = true;
|
197 |
initialized = true;
|
| 183 |
};
|
198 |
};
|
| Línea 184... |
Línea 199... |
| 184 |
|
199 |
|
| 185 |
/**
|
200 |
/**
|
| 186 |
* Given the web service data and an ID we want to make a deep copy
|
201 |
* Given the web service data and an ID we want to make a deep copy
|
| 187 |
* of the WS data then add on the section ID to the addoption URL
|
202 |
* of the WS data then add on the section num to the addoption URL
|
| 188 |
*
|
203 |
*
|
| 189 |
* @method sectionIdMapper
|
204 |
* @method sectionMapper
|
| 190 |
* @param {Object} webServiceData Our original data from the Web service call
|
205 |
* @param {Object} webServiceData Our original data from the Web service call
|
| 191 |
* @param {Number} id The ID of the section we need to append to the links
|
206 |
* @param {Number} num The number of the section we need to append to the links
|
| 192 |
* @param {Number|null} sectionreturnid The ID of the section return we need to append to the links
|
207 |
* @param {Number|null} sectionreturnnum The number of the section return we need to append to the links
|
| 193 |
* @param {Number|null} beforemod The ID of the cm we need to append to the links
|
208 |
* @param {Number|null} beforemod The ID of the cm we need to append to the links
|
| 194 |
* @return {Array} [modules] with URL's built
|
209 |
* @return {Array} [modules] with URL's built
|
| 195 |
*/
|
210 |
*/
|
| 196 |
const sectionIdMapper = (webServiceData, id, sectionreturnid, beforemod) => {
|
211 |
const sectionMapper = (webServiceData, num, sectionreturnnum, beforemod) => {
|
| 197 |
// We need to take a fresh deep copy of the original data as an object is a reference type.
|
212 |
// We need to take a fresh deep copy of the original data as an object is a reference type.
|
| 198 |
const newData = JSON.parse(JSON.stringify(webServiceData));
|
213 |
const newData = JSON.parse(JSON.stringify(webServiceData));
|
| 199 |
newData.content_items.forEach((module) => {
|
214 |
newData.content_items.forEach((module) => {
|
| 200 |
module.link += '§ion=' + id + '&beforemod=' + (beforemod ?? 0);
|
215 |
module.link += '§ion=' + num + '&beforemod=' + (beforemod ?? 0);
|
| 201 |
if (sectionreturnid) {
|
216 |
if (sectionreturnnum) {
|
| 202 |
module.link += '&sr=' + sectionreturnid;
|
217 |
module.link += '&sr=' + sectionreturnnum;
|
| 203 |
}
|
218 |
}
|
| 204 |
});
|
219 |
});
|
| 205 |
return newData.content_items;
|
220 |
return newData.content_items;
|
| Línea 350... |
Línea 365... |
| 350 |
* Export a curried function where the builtModules has been applied.
|
365 |
* Export a curried function where the builtModules has been applied.
|
| 351 |
* We have our array of modules so we can rerender the favourites area and have all of the items sorted.
|
366 |
* We have our array of modules so we can rerender the favourites area and have all of the items sorted.
|
| 352 |
*
|
367 |
*
|
| 353 |
* @method partiallyAppliedFavouriteManager
|
368 |
* @method partiallyAppliedFavouriteManager
|
| 354 |
* @param {Array} moduleData This is our raw WS data that we need to manipulate
|
369 |
* @param {Array} moduleData This is our raw WS data that we need to manipulate
|
| 355 |
* @param {Number} sectionId We need this to add the sectionID to the URL's in the faves area after rerender
|
370 |
* @param {Number} sectionnum We need this to add the sectionnum to the URL's in the faves area after rerender
|
| 356 |
* @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array
|
371 |
* @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array
|
| 357 |
*/
|
372 |
*/
|
| 358 |
const partiallyAppliedFavouriteManager = (moduleData, sectionId) => {
|
373 |
const partiallyAppliedFavouriteManager = (moduleData, sectionnum) => {
|
| 359 |
/**
|
374 |
/**
|
| 360 |
* Curried function that is being returned.
|
375 |
* Curried function that is being returned.
|
| 361 |
*
|
376 |
*
|
| 362 |
* @param {String} internal Internal name of the module to manage
|
377 |
* @param {String} internal Internal name of the module to manage
|
| 363 |
* @param {Boolean} favourite Is the caller adding a favourite or removing one?
|
378 |
* @param {Boolean} favourite Is the caller adding a favourite or removing one?
|
| Línea 376... |
Línea 391... |
| 376 |
result.favourite = true;
|
391 |
result.favourite = true;
|
| Línea 377... |
Línea 392... |
| 377 |
|
392 |
|
| 378 |
// eslint-disable-next-line camelcase
|
393 |
// eslint-disable-next-line camelcase
|
| Línea 379... |
Línea 394... |
| 379 |
newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);
|
394 |
newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);
|
| Línea 380... |
Línea 395... |
| 380 |
|
395 |
|
| 381 |
const builtFaves = sectionIdMapper(newFaves, sectionId);
|
396 |
const builtFaves = sectionMapper(newFaves, sectionnum);
|
| Línea 382... |
Línea 397... |
| 382 |
|
397 |
|