lib/amd/src/local/process_monitor/manager.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. * The course file uploader.
  17. *
  18. * This module is used to upload files directly into the course.
  19. *
  20. * @module core/local/process_monitor/manager
  21. * @copyright 2022 Ferran Recio <ferran@moodle.com>
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. import {Reactive} from 'core/reactive';
  25. import {eventTypes, dispatchStateChangedEvent} from 'core/local/process_monitor/events';
  26. const initialState = {
  27. display: {
  28. show: false,
  29. },
  30. queue: [],
  31. };
  32. /**
  33. * The reactive file uploader class.
  34. *
  35. * As all the upload queues are reactive, any plugin can implement its own upload monitor.
  36. *
  37. * @module core/local/process_monitor/manager
  38. * @class ProcessMonitorManager
  39. * @copyright 2021 Ferran Recio <ferran@moodle.com>
  40. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41. */
  42. class ProcessMonitorManager extends Reactive {
  43. /**
  44. * The next process id to use.
  45. *
  46. * @attribute nextId
  47. * @type number
  48. * @default 1
  49. * @package
  50. */
  51. nextId = 1;
  52. /**
  53. * Generate a unique process id.
  54. * @return {number} a generated process Id
  55. */
  56. generateProcessId() {
  57. return this.nextId++;
  58. }
  59. }
  60. /**
  61. * @var {Object} mutations the monitor mutations.
  62. */
  63. const mutations = {
  64. /**
  65. * Add a new process to the queue.
  66. *
  67. * @param {StateManager} stateManager the current state manager
  68. * @param {Object} processData the upload id to finish
  69. */
  70. addProcess: function(stateManager, processData) {
  71. const state = stateManager.state;
  72. stateManager.setReadOnly(false);
  73. state.queue.add({...processData});
  74. state.display.show = true;
  75. stateManager.setReadOnly(true);
  76. },
  77. /**
  78. * Remove a process from the queue.
  79. *
  80. * @param {StateManager} stateManager the current state manager
  81. * @param {Number} processId the process id
  82. */
  83. removeProcess: function(stateManager, processId) {
  84. const state = stateManager.state;
  85. stateManager.setReadOnly(false);
  86. state.queue.delete(processId);
  87. if (state.queue.size === 0) {
  88. state.display.show = false;
  89. }
  90. stateManager.setReadOnly(true);
  91. },
  92. /**
  93. * Update a process process to the queue.
  94. *
  95. * @param {StateManager} stateManager the current state manager
  96. * @param {Object} processData the upload id to finish
  97. * @param {Number} processData.id the process id
  98. */
  99. updateProcess: function(stateManager, processData) {
  100. if (processData.id === undefined) {
  101. throw Error(`Missing process ID in process data`);
  102. }
  103. const state = stateManager.state;
  104. stateManager.setReadOnly(false);
  105. const queueItem = state.queue.get(processData.id);
  106. if (!queueItem) {
  107. throw Error(`Unkown process with id ${processData.id}`);
  108. }
  109. for (const [prop, propValue] of Object.entries(processData)) {
  110. queueItem[prop] = propValue;
  111. }
  112. stateManager.setReadOnly(true);
  113. },
  114. /**
  115. * Set the monitor show attribute.
  116. *
  117. * @param {StateManager} stateManager the current state manager
  118. * @param {Boolean} show the show value
  119. */
  120. setShow: function(stateManager, show) {
  121. const state = stateManager.state;
  122. stateManager.setReadOnly(false);
  123. state.display.show = show;
  124. if (!show) {
  125. this.cleanFinishedProcesses(stateManager);
  126. }
  127. stateManager.setReadOnly(true);
  128. },
  129. /**
  130. * Remove a processes from the queue.
  131. *
  132. * @param {StateManager} stateManager the current state manager
  133. */
  134. removeAllProcesses: function(stateManager) {
  135. const state = stateManager.state;
  136. stateManager.setReadOnly(false);
  137. state.queue.forEach((element) => {
  138. state.queue.delete(element.id);
  139. });
  140. state.display.show = false;
  141. stateManager.setReadOnly(true);
  142. },
  143. /**
  144. * Clean all finished processes.
  145. *
  146. * @param {StateManager} stateManager the current state manager
  147. */
  148. cleanFinishedProcesses: function(stateManager) {
  149. const state = stateManager.state;
  150. stateManager.setReadOnly(false);
  151. state.queue.forEach((element) => {
  152. if (element.finished && !element.error) {
  153. state.queue.delete(element.id);
  154. }
  155. });
  156. if (state.queue.size === 0) {
  157. state.display.show = false;
  158. }
  159. stateManager.setReadOnly(true);
  160. },
  161. };
  162. const manager = new ProcessMonitorManager({
  163. name: `ProcessMonitor`,
  164. eventName: eventTypes.processMonitorStateChange,
  165. eventDispatch: dispatchStateChangedEvent,
  166. mutations: mutations,
  167. state: initialState,
  168. });
  169. export {manager};