8b5ae2ea181828b95e162d5d10653c77d57aae26
[moodle.git] / admin / tool / lp / amd / src / competencies.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  * Handle add/remove competency links.
18  *
19  * @module     tool_lp/competencies
20  * @package    tool_lp
21  * @copyright  2015 Damyon Wiese <damyon@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 define(['jquery',
25         'core/notification',
26         'core/ajax',
27         'core/templates',
28         'core/str',
29         'tool_lp/competencypicker',
30         'tool_lp/dragdrop-reorder'],
31        function($, notification, ajax, templates, str, Picker, dragdrop) {
33     /**
34      * Constructor
35      *
36      * @param {Number} itemid
37      * @param {String} itemtype
38      * @param {Number} pagectxid
39      */
40     var competencies = function(itemid, itemtype, pagectxid) {
41         this.itemid = itemid;
42         this.itemtype = itemtype;
43         this.pageContextId = pagectxid;
44         this.pickerInstance = null;
46         $('[data-region="actions"] button').prop('disabled', false);
47         this.registerEvents();
48         this.registerDragDrop();
49     };
51     /**
52      * Initialise the drag/drop code.
53      * @method registerDragDrop
54      */
55     competencies.prototype.registerDragDrop = function() {
56         var localthis = this;
57         // Init this module.
58         str.get_string('movecompetency', 'tool_lp').done(
59             function(movestring) {
60                 dragdrop.dragdrop('movecompetency',
61                                   movestring,
62                                   { identifier: 'movecompetency', component: 'tool_lp'},
63                                   { identifier: 'movecompetencyafter', component: 'tool_lp'},
64                                   'drag-samenode',
65                                   'drag-parentnode',
66                                   'drag-handlecontainer',
67                                   function(drag, drop) {
68                                       localthis.handleDrop.call(localthis, drag, drop);
69                                   });
70             }
71         ).fail(notification.exception);
73     };
75     /**
76      * Handle a drop from a drag/drop operation.
77      *
78      * @method handleDrop
79      * @param {DOMNode} drag The dragged node.
80      * @param {DOMNode} drop The dropped on node.
81      */
82     competencies.prototype.handleDrop = function(drag, drop) {
83         var fromid = $(drag).data('id');
84         var toid = $(drop).data('id');
85         var localthis = this;
86         var requests = [];
88         if (localthis.itemtype == 'course') {
89             requests = ajax.call([
90                 {
91                     methodname: 'core_competency_reorder_course_competency',
92                     args: { courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
93                 }
94             ]);
95         } else if (localthis.itemtype == 'template') {
96             requests = ajax.call([
97                 {
98                     methodname: 'core_competency_reorder_template_competency',
99                     args: { templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
100                 }
101             ]);
102         } else if (localthis.itemtype == 'plan') {
103             requests = ajax.call([
104                 {
105                     methodname: 'core_competency_reorder_plan_competency',
106                     args: { planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
107                 }
108             ]);
109         } else {
110             return;
111         }
113         requests[0].fail(notification.exception);
114     };
116     /**
117      * Pick a competency
118      *
119      * @method pickCompetency
120      */
121     competencies.prototype.pickCompetency = function() {
122         var self = this;
123         var requests;
124         var pagerender;
125         var pageregion;
126         var pageContextIncludes;
128         if (!self.pickerInstance) {
129             if (self.itemtype === 'template' || self.itemtype === 'course') {
130                 pageContextIncludes = 'parents';
131             }
132             self.pickerInstance = new Picker(self.pageContextId, false, pageContextIncludes);
133             self.pickerInstance.on('save', function(e, data) {
134                 var compIds = data.competencyIds;
136                 if (self.itemtype === "course") {
137                     requests = [];
139                     $.each(compIds, function(index, compId) {
140                         requests.push({
141                             methodname: 'core_competency_add_competency_to_course',
142                             args: { courseid: self.itemid, competencyid: compId }
143                         });
144                     });
145                     requests.push({
146                         methodname: 'tool_lp_data_for_course_competencies_page',
147                         args: { courseid: self.itemid }
148                     });
150                     pagerender = 'tool_lp/course_competencies_page';
151                     pageregion = 'coursecompetenciespage';
153                 } else if (self.itemtype === "template") {
154                     requests = [];
156                     $.each(compIds, function(index, compId) {
157                         requests.push({
158                             methodname: 'core_competency_add_competency_to_template',
159                             args: { templateid: self.itemid, competencyid: compId }
160                         });
161                     });
162                     requests.push({
163                         methodname: 'tool_lp_data_for_template_competencies_page',
164                         args: { templateid: self.itemid, pagecontext: { contextid: self.pageContextId }}
165                     });
166                     pagerender = 'tool_lp/template_competencies_page';
167                     pageregion = 'templatecompetenciespage';
168                 } else if (self.itemtype === "plan") {
169                     requests = [];
171                     $.each(compIds, function(index, compId) {
172                         requests.push({
173                             methodname: 'core_competency_add_competency_to_plan',
174                             args: { planid: self.itemid, competencyid: compId }
175                         });
176                     });
177                     requests.push({
178                          methodname: 'tool_lp_data_for_plan_page',
179                          args: { planid: self.itemid}
180                     });
181                     pagerender = 'tool_lp/plan_page';
182                     pageregion = 'plan-page';
183                 }
185                 ajax.call(requests)[requests.length - 1].then(function(context) {
186                     return templates.render(pagerender, context).done(function(html, js) {
187                         $('[data-region="' + pageregion + '"]').replaceWith(html);
188                         templates.runTemplateJS(js);
189                     });
190                 }, notification.exception);
191             });
192         }
194         self.pickerInstance.display();
195     };
197     /**
198      * Delete the link between competency and course, template or plan. Reload the page.
199      *
200      * @method doDelete
201      * @param {int} deleteid The id of record to delete.
202      */
203     competencies.prototype.doDelete = function(deleteid) {
204         var localthis = this;
205         var requests = [],
206             pagerender = '',
207             pageregion = '';
209         // Delete the link and reload the page template.
210         if (localthis.itemtype == 'course') {
211             requests = ajax.call([
212                 { methodname: 'core_competency_remove_competency_from_course',
213                     args: { courseid: localthis.itemid, competencyid: deleteid } },
214                 { methodname: 'tool_lp_data_for_course_competencies_page',
215                     args: { courseid: localthis.itemid } }
216             ]);
217             pagerender = 'tool_lp/course_competencies_page';
218             pageregion = 'coursecompetenciespage';
219         } else if (localthis.itemtype == 'template') {
220             requests = ajax.call([
221                 { methodname: 'core_competency_remove_competency_from_template',
222                     args: { templateid: localthis.itemid, competencyid: deleteid } },
223                 { methodname: 'tool_lp_data_for_template_competencies_page',
224                     args: { templateid: localthis.itemid, pagecontext: { contextid: localthis.pageContextId } } }
225             ]);
226             pagerender = 'tool_lp/template_competencies_page';
227             pageregion = 'templatecompetenciespage';
228         } else if (localthis.itemtype == 'plan') {
229             requests = ajax.call([
230                 { methodname: 'core_competency_remove_competency_from_plan',
231                     args: { planid: localthis.itemid, competencyid: deleteid } },
232                 { methodname: 'tool_lp_data_for_plan_page',
233                     args: { planid: localthis.itemid } }
234             ]);
235             pagerender = 'tool_lp/plan_page';
236             pageregion = 'plan-page';
237         }
239         requests[1].done(function(context) {
240             templates.render(pagerender, context).done(function(html, js) {
241                 $('[data-region="' + pageregion + '"]').replaceWith(html);
242                 templates.runTemplateJS(js);
243             }).fail(notification.exception);
244         }).fail(notification.exception);
246     };
248     /**
249      * Show a confirm dialogue before deleting a competency.
250      *
251      * @method deleteHandler
252      * @param {int} deleteid The id of record to delete.
253      */
254     competencies.prototype.deleteHandler = function(deleteid) {
255         var localthis = this;
256         var requests = [];
257         var message;
259         if (localthis.itemtype == 'course') {
260             message = 'unlinkcompetencycourse';
261         } else if (localthis.itemtype == 'template') {
262             message = 'unlinkcompetencytemplate';
263         } else if (localthis.itemtype == 'plan') {
264             message = 'unlinkcompetencyplan';
265         } else {
266             return;
267         }
269         requests = ajax.call([{
270             methodname: 'core_competency_read_competency',
271             args: { id: deleteid }
272         }]);
274         requests[0].done(function(competency) {
275             str.get_strings([
276                 { key: 'confirm', component: 'moodle' },
277                 { key: message, component: 'tool_lp', param: competency.shortname },
278                 { key: 'confirm', component: 'moodle' },
279                 { key: 'cancel', component: 'moodle' }
280             ]).done(function(strings) {
281                 notification.confirm(
282                     strings[0], // Confirm.
283                     strings[1], // Unlink the competency X from the course?
284                     strings[2], // Confirm.
285                     strings[3], // Cancel.
286                     function() {
287                         localthis.doDelete(deleteid);
288                     }
289                 );
290             }).fail(notification.exception);
291         }).fail(notification.exception);
292     };
294     /**
295      * Register the javascript event handlers for this page.
296      *
297      * @method registerEvents
298      */
299     competencies.prototype.registerEvents = function() {
300         var localthis = this;
302         if (localthis.itemtype == 'course') {
303             // Course completion rule handling.
304             $('[data-region="coursecompetenciespage"]').on('change', 'select[data-field="ruleoutcome"]', function(e) {
305                 var requests = [];
306                 var pagerender = 'tool_lp/course_competencies_page';
307                 var pageregion = 'coursecompetenciespage';
308                 var coursecompetencyid = $(e.target).data('id');
309                 var ruleoutcome = $(e.target).val();
310                 requests = ajax.call([
311                     { methodname: 'core_competency_set_course_competency_ruleoutcome',
312                       args: { coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome } },
313                     { methodname: 'tool_lp_data_for_course_competencies_page',
314                       args: { courseid: localthis.itemid } }
315                 ]);
317                 requests[1].done(function(context) {
318                     templates.render(pagerender, context).done(function(html, js) {
319                         $('[data-region="' + pageregion + '"]').replaceWith(html);
320                         templates.runTemplateJS(js);
321                     }).fail(notification.exception);
322                 }).fail(notification.exception);
323             });
324         }
326         $('[data-region="actions"] button').click(function(e) {
327             e.preventDefault();
328             localthis.pickCompetency();
329         });
330         $('[data-action="delete-competency-link"]').click(function(e) {
331             e.preventDefault();
333             var deleteid = $(e.target).closest('[data-id]').data('id');
334             localthis.deleteHandler(deleteid);
335         });
336     };
338     return /** @alias module:tool_lp/competencies */ competencies;
339 });