MDL-69559 course: Add course content download UI and execution page
[moodle.git] / course / amd / src / downloadcontent.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * Functions related to downloading course content.
18  *
19  * @module     core_course/downloadcontent
20  * @package    core_course
21  * @copyright  2020 Michael Hawkins <michaelh@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 import Config from 'core/config';
26 import CustomEvents from 'core/custom_interaction_events';
27 import * as ModalFactory from 'core/modal_factory';
28 import jQuery from 'jquery';
29 import Pending from 'core/pending';
31 /**
32  * Set up listener to trigger the download course content modal.
33  *
34  * @return {void}
35  */
36 export const init = () => {
37     const pendingPromise = new Pending();
39     document.addEventListener('click', (e) => {
40         const downloadModalTrigger = e.target.closest('[data-downloadcourse]');
42         if (downloadModalTrigger) {
43             e.preventDefault();
44             displayDownloadConfirmation(downloadModalTrigger);
45         }
46     });
48     pendingPromise.resolve();
49 };
51 /**
52  * Display the download course content modal.
53  *
54  * @method displayDownloadConfirmation
55  * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.
56  * @return {void}
57  */
58 const displayDownloadConfirmation = (downloadModalTrigger) => {
59     ModalFactory.create({
60         title: downloadModalTrigger.dataset.downloadTitle,
61         type: ModalFactory.types.SAVE_CANCEL,
62         body: `<p>${downloadModalTrigger.dataset.downloadBody}</p>`,
63         buttons: {
64             save: downloadModalTrigger.dataset.downloadButtonText
65         },
66         templateContext: {
67             classes: 'downloadcoursecontentmodal'
68         }
69     })
70     .then(modal => {
71         // Display the modal.
72         modal.show();
74         const saveButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action="save"]');
75         const cancelButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action="cancel"]');
76         const modalContainer = document.querySelector('.modal[data-region="modal-container"]');
78         // Create listener to trigger the download when the "Download" button is pressed.
79         jQuery(saveButton).on(CustomEvents.events.activate, (e) => downloadContent(e, downloadModalTrigger, modal));
81         // Create listener to destroy the modal when closing modal by cancelling.
82         jQuery(cancelButton).on(CustomEvents.events.activate, () => {
83             modal.destroy();
84         });
86         // Create listener to destroy the modal when closing modal by clicking outside of it.
87         if (modalContainer.querySelector('.downloadcoursecontentmodal')) {
88             jQuery(modalContainer).on(CustomEvents.events.activate, () => {
89                 modal.destroy();
90             });
91         }
92     });
93 };
95 /**
96  * Trigger downloading of course content.
97  *
98  * @method downloadContent
99  * @param {Event} e The event triggering the download.
100  * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.
101  * @param {Object} modal The modal object.
102  * @return {void}
103  */
104 const downloadContent = (e, downloadModalTrigger, modal) => {
105     e.preventDefault();
107     // Create a form to submit the file download request, so we can avoid sending sesskey over GET.
108     const downloadForm = document.createElement('form');
109     downloadForm.action = downloadModalTrigger.dataset.downloadLink;
110     downloadForm.method = 'POST';
111     // Open download in a new tab, so current course view is not disrupted.
112     downloadForm.target = '_blank';
113     const downloadSesskey = document.createElement('input');
114     downloadSesskey.name = 'sesskey';
115     downloadSesskey.value = Config.sesskey;
116     downloadForm.appendChild(downloadSesskey);
117     downloadForm.style.display = 'none';
119     document.body.appendChild(downloadForm);
120     downloadForm.submit();
121     document.body.removeChild(downloadForm);
123     // Destroy the modal to prevent duplicates if reopened later.
124     modal.destroy();
125 };