grade/report/singleview/amd/src/bulkactions.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/>.
  15. /**
  16. * Javascript module for bulk actions.
  17. *
  18. * @module gradereport_singleview/bulkactions
  19. * @copyright 2022 Ilya Tregubov <ilya@moodle.com>
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. import Pending from 'core/pending';
  23. import CustomEvents from "core/custom_interaction_events";
  24. import ModalSaveCancel from 'core/modal_save_cancel';
  25. import Templates from 'core/templates';
  26. import ModalEvents from 'core/modal_events';
  27. import * as Str from 'core/str';
  28. import Notification from 'core/notification';
  29. import selectors from 'gradereport_singleview/selectors';
  30. /**
  31. * Initialize module.
  32. */
  33. export const init = () => {
  34. const pendingPromise = new Pending();
  35. registerListenerEvents();
  36. pendingPromise.resolve();
  37. };
  38. /**
  39. * Register bulk actions related event listeners.
  40. *
  41. * @method registerListenerEvents
  42. */
  43. const registerListenerEvents = () => {
  44. const events = [
  45. 'click',
  46. CustomEvents.events.activate,
  47. CustomEvents.events.keyboardActivate
  48. ];
  49. CustomEvents.define(document, events);
  50. // Register events.
  51. events.forEach((event) => {
  52. document.addEventListener(event, async(e) => {
  53. const trigger = e.target.closest(selectors.actions.bulkaction);
  54. if (!trigger) {
  55. return;
  56. }
  57. if ((trigger.dataset.action === 'overrideallgrades') || (trigger.dataset.action === 'overridenonegrades')) {
  58. const override = document.querySelectorAll(selectors.elements.override);
  59. if (trigger.dataset.action === 'overridenonegrades') {
  60. // Alert for removing all grade overrides on page.
  61. Str.get_strings([
  62. {key: 'removeoverride', component: 'gradereport_singleview'},
  63. {key: 'overridenoneconfirm', component: 'gradereport_singleview'},
  64. {key: 'removeoverridesave', component: 'gradereport_singleview'},
  65. {key: 'cancel', component: 'moodle'},
  66. ])
  67. .then((strings) => {
  68. return Notification.confirm(
  69. strings[0],
  70. strings[1],
  71. strings[2],
  72. strings[3],
  73. () => {
  74. // Uncheck each override checkbox - this will make grade and feedback input fields disabled.
  75. override.forEach((el) => {
  76. if (el.checked) {
  77. el.click();
  78. }
  79. });
  80. });
  81. })
  82. .catch(Notification.exception);
  83. } else {
  84. // Check each override checkbox - this will make grade and feedback input fields enabled.
  85. override.forEach((el) => {
  86. if (!el.checked) {
  87. el.click();
  88. }
  89. });
  90. }
  91. } else if ((trigger.dataset.action === 'excludeallgrades') || (trigger.dataset.action === 'excludenonegrades')) {
  92. const exclude = document.querySelectorAll(selectors.elements.exclude);
  93. const checked = (trigger.dataset.action === 'excludeallgrades');
  94. // Uncheck or check each exclude checkbox.
  95. exclude.forEach((el) => {
  96. el.checked = checked;
  97. });
  98. } else if (trigger.dataset.action === 'bulklegend') {
  99. // Modal for bulk insert grades.
  100. Str.get_strings([
  101. {key: 'bulklegend', component: 'gradereport_singleview'},
  102. {key: 'save', component: 'moodle'},
  103. ])
  104. .then((strings) => {
  105. return ModalSaveCancel.create({
  106. body: Templates.render('gradereport_singleview/bulkinsert', {
  107. id: 'bulkinsertmodal',
  108. name: 'bulkinsertmodal'
  109. }),
  110. title: strings[0],
  111. buttons: {
  112. save: strings[1],
  113. },
  114. removeOnClose: true,
  115. show: true,
  116. });
  117. })
  118. .then((modal) => {
  119. modal.getFooter().find(selectors.elements.modalsave).attr('disabled', true);
  120. // We need to acknowledge that we understand risks of loosing data.
  121. // Only when acknowledge checkbox is checked we allow selecting insert options.
  122. modal.getRoot().on('change', selectors.elements.warningcheckbox,
  123. (e) => {
  124. e.preventDefault();
  125. if (e.target.checked) {
  126. modal.getRoot().find(selectors.elements.modalformdata).removeClass('dimmed_text');
  127. modal.getRoot().find(selectors.elements.modalradio).removeAttr('disabled');
  128. modal.getRoot().find(selectors.elements.modalinput).removeAttr('disabled');
  129. const formRadioData = modal.getRoot().find(selectors.elements.modalradiochecked).val();
  130. // We allow saving grades only when all needed data present on form.
  131. if (formRadioData) {
  132. modal.getFooter().find(selectors.elements.modalsave).removeAttr('disabled');
  133. }
  134. } else {
  135. modal.getRoot().find(selectors.elements.modalformdata).addClass('dimmed_text');
  136. modal.getRoot().find(selectors.elements.modalradio).attr('disabled', true);
  137. modal.getRoot().find(selectors.elements.modalinput).attr('disabled', true);
  138. modal.getFooter().find(selectors.elements.modalsave).attr('disabled', true);
  139. }
  140. });
  141. // We allow saving grades only when all needed data present on form.
  142. modal.getRoot().on('change', selectors.elements.modalradio, (e) => {
  143. e.preventDefault();
  144. modal.getFooter().find(selectors.elements.modalsave).removeAttr('disabled');
  145. });
  146. modal.getRoot().on(ModalEvents.save, () => {
  147. // When save button is clicked in modal form we insert data from modal
  148. // into preexisted hidden bulk insert form and Save button for table form.
  149. document.querySelector(selectors.elements.enablebulkinsert).checked = true;
  150. const formRadioData = modal.getRoot().find(selectors.elements.modalradiochecked).val();
  151. const $select = document.querySelector(selectors.elements.formradio);
  152. $select.value = formRadioData;
  153. const formData = modal.getRoot().find(selectors.elements.modalgrade).val();
  154. document.querySelector(selectors.elements.formgrade).value = formData;
  155. document.querySelector(selectors.elements.formsave).click();
  156. });
  157. return modal;
  158. })
  159. .catch(Notification.exception);
  160. }
  161. });
  162. });
  163. };