Merge branch 'MDL-64437-master' of git://github.com/mihailges/moodle
[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         'core/pending'],
32        function($, notification, ajax, templates, str, Picker, dragdrop, Pending) {
34     /**
35      * Constructor
36      *
37      * @param {Number} itemid
38      * @param {String} itemtype
39      * @param {Number} pagectxid
40      */
41     var competencies = function(itemid, itemtype, pagectxid) {
42         this.itemid = itemid;
43         this.itemtype = itemtype;
44         this.pageContextId = pagectxid;
45         this.pickerInstance = null;
47         $('[data-region="actions"] button').prop('disabled', false);
48         this.registerEvents();
49         this.registerDragDrop();
50     };
52     /**
53      * Initialise the drag/drop code.
54      * @method registerDragDrop
55      */
56     competencies.prototype.registerDragDrop = function() {
57         var localthis = this;
58         // Init this module.
59         str.get_string('movecompetency', 'tool_lp').done(
60             function(movestring) {
61                 dragdrop.dragdrop('movecompetency',
62                                   movestring,
63                                   {identifier: 'movecompetency', component: 'tool_lp'},
64                                   {identifier: 'movecompetencyafter', component: 'tool_lp'},
65                                   'drag-samenode',
66                                   'drag-parentnode',
67                                   'drag-handlecontainer',
68                                   function(drag, drop) {
69                                       localthis.handleDrop(drag, drop);
70                                   });
71             }
72         ).fail(notification.exception);
74     };
76     /**
77      * Handle a drop from a drag/drop operation.
78      *
79      * @method handleDrop
80      * @param {DOMNode} drag The dragged node.
81      * @param {DOMNode} drop The dropped on node.
82      */
83     competencies.prototype.handleDrop = function(drag, drop) {
84         var fromid = $(drag).data('id');
85         var toid = $(drop).data('id');
86         var localthis = this;
87         var requests = [];
89         if (localthis.itemtype == 'course') {
90             requests = ajax.call([
91                 {
92                     methodname: 'core_competency_reorder_course_competency',
93                     args: {courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
94                 }
95             ]);
96         } else if (localthis.itemtype == 'template') {
97             requests = ajax.call([
98                 {
99                     methodname: 'core_competency_reorder_template_competency',
100                     args: {templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
101                 }
102             ]);
103         } else if (localthis.itemtype == 'plan') {
104             requests = ajax.call([
105                 {
106                     methodname: 'core_competency_reorder_plan_competency',
107                     args: {planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
108                 }
109             ]);
110         } else {
111             return;
112         }
114         requests[0].fail(notification.exception);
115     };
117     /**
118      * Pick a competency
119      *
120      * @method pickCompetency
121      * @return {Promise}
122      */
123     competencies.prototype.pickCompetency = function() {
124         var self = this;
125         var requests;
126         var pagerender;
127         var pageregion;
128         var pageContextIncludes;
130         if (!self.pickerInstance) {
131             if (self.itemtype === 'template' || self.itemtype === 'course') {
132                 pageContextIncludes = 'parents';
133             }
134             self.pickerInstance = new Picker(self.pageContextId, false, pageContextIncludes);
135             self.pickerInstance.on('save', function(e, data) {
136                 var compIds = data.competencyIds;
137                 var pendingPromise = new Pending();
139                 if (self.itemtype === "course") {
140                     requests = [];
142                     $.each(compIds, function(index, compId) {
143                         requests.push({
144                             methodname: 'core_competency_add_competency_to_course',
145                             args: {courseid: self.itemid, competencyid: compId}
146                         });
147                     });
148                     requests.push({
149                         methodname: 'tool_lp_data_for_course_competencies_page',
150                         args: {courseid: self.itemid, moduleid: 0}
151                     });
153                     pagerender = 'tool_lp/course_competencies_page';
154                     pageregion = 'coursecompetenciespage';
156                 } else if (self.itemtype === "template") {
157                     requests = [];
159                     $.each(compIds, function(index, compId) {
160                         requests.push({
161                             methodname: 'core_competency_add_competency_to_template',
162                             args: {templateid: self.itemid, competencyid: compId}
163                         });
164                     });
165                     requests.push({
166                         methodname: 'tool_lp_data_for_template_competencies_page',
167                         args: {templateid: self.itemid, pagecontext: {contextid: self.pageContextId}}
168                     });
169                     pagerender = 'tool_lp/template_competencies_page';
170                     pageregion = 'templatecompetenciespage';
171                 } else if (self.itemtype === "plan") {
172                     requests = [];
174                     $.each(compIds, function(index, compId) {
175                         requests.push({
176                             methodname: 'core_competency_add_competency_to_plan',
177                             args: {planid: self.itemid, competencyid: compId}
178                         });
179                     });
180                     requests.push({
181                          methodname: 'tool_lp_data_for_plan_page',
182                          args: {planid: self.itemid}
183                     });
184                     pagerender = 'tool_lp/plan_page';
185                     pageregion = 'plan-page';
186                 }
187                 ajax.call(requests)[requests.length - 1]
188                 .then(function(context) {
189                     return templates.render(pagerender, context);
190                 })
191                 .then(function(html, js) {
192                     templates.replaceNode($('[data-region="' + pageregion + '"]'), html, js);
193                     return;
194                 })
195                 .then(pendingPromise.resolve)
196                 .catch(notification.exception);
197             });
198         }
200         return self.pickerInstance.display();
201     };
203     /**
204      * Delete the link between competency and course, template or plan. Reload the page.
205      *
206      * @method doDelete
207      * @param {int} deleteid The id of record to delete.
208      */
209     competencies.prototype.doDelete = function(deleteid) {
210         var localthis = this;
211         var requests = [],
212             pagerender = '',
213             pageregion = '';
215         // Delete the link and reload the page template.
216         if (localthis.itemtype == 'course') {
217             requests = ajax.call([
218                 {methodname: 'core_competency_remove_competency_from_course',
219                     args: {courseid: localthis.itemid, competencyid: deleteid}},
220                 {methodname: 'tool_lp_data_for_course_competencies_page',
221                     args: {courseid: localthis.itemid, moduleid: 0}}
222             ]);
223             pagerender = 'tool_lp/course_competencies_page';
224             pageregion = 'coursecompetenciespage';
225         } else if (localthis.itemtype == 'template') {
226             requests = ajax.call([
227                 {methodname: 'core_competency_remove_competency_from_template',
228                     args: {templateid: localthis.itemid, competencyid: deleteid}},
229                 {methodname: 'tool_lp_data_for_template_competencies_page',
230                     args: {templateid: localthis.itemid, pagecontext: {contextid: localthis.pageContextId}}}
231             ]);
232             pagerender = 'tool_lp/template_competencies_page';
233             pageregion = 'templatecompetenciespage';
234         } else if (localthis.itemtype == 'plan') {
235             requests = ajax.call([
236                 {methodname: 'core_competency_remove_competency_from_plan',
237                     args: {planid: localthis.itemid, competencyid: deleteid}},
238                 {methodname: 'tool_lp_data_for_plan_page',
239                     args: {planid: localthis.itemid}}
240             ]);
241             pagerender = 'tool_lp/plan_page';
242             pageregion = 'plan-page';
243         }
245         requests[1].done(function(context) {
246             templates.render(pagerender, context).done(function(html, js) {
247                 $('[data-region="' + pageregion + '"]').replaceWith(html);
248                 templates.runTemplateJS(js);
249             }).fail(notification.exception);
250         }).fail(notification.exception);
252     };
254     /**
255      * Show a confirm dialogue before deleting a competency.
256      *
257      * @method deleteHandler
258      * @param {int} deleteid The id of record to delete.
259      */
260     competencies.prototype.deleteHandler = function(deleteid) {
261         var localthis = this;
262         var requests = [];
263         var message;
265         if (localthis.itemtype == 'course') {
266             message = 'unlinkcompetencycourse';
267         } else if (localthis.itemtype == 'template') {
268             message = 'unlinkcompetencytemplate';
269         } else if (localthis.itemtype == 'plan') {
270             message = 'unlinkcompetencyplan';
271         } else {
272             return;
273         }
275         requests = ajax.call([{
276             methodname: 'core_competency_read_competency',
277             args: {id: deleteid}
278         }]);
280         requests[0].done(function(competency) {
281             str.get_strings([
282                 {key: 'confirm', component: 'moodle'},
283                 {key: message, component: 'tool_lp', param: competency.shortname},
284                 {key: 'confirm', component: 'moodle'},
285                 {key: 'cancel', component: 'moodle'}
286             ]).done(function(strings) {
287                 notification.confirm(
288                     strings[0], // Confirm.
289                     strings[1], // Unlink the competency X from the course?
290                     strings[2], // Confirm.
291                     strings[3], // Cancel.
292                     function() {
293                         localthis.doDelete(deleteid);
294                     }
295                 );
296             }).fail(notification.exception);
297         }).fail(notification.exception);
298     };
300     /**
301      * Register the javascript event handlers for this page.
302      *
303      * @method registerEvents
304      */
305     competencies.prototype.registerEvents = function() {
306         var localthis = this;
308         if (localthis.itemtype == 'course') {
309             // Course completion rule handling.
310             $('[data-region="coursecompetenciespage"]').on('change', 'select[data-field="ruleoutcome"]', function(e) {
311                 var pendingPromise = new Pending();
312                 var requests = [];
313                 var pagerender = 'tool_lp/course_competencies_page';
314                 var pageregion = 'coursecompetenciespage';
315                 var coursecompetencyid = $(e.target).data('id');
316                 var ruleoutcome = $(e.target).val();
317                 requests = ajax.call([
318                     {methodname: 'core_competency_set_course_competency_ruleoutcome',
319                       args: {coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome}},
320                     {methodname: 'tool_lp_data_for_course_competencies_page',
321                       args: {courseid: localthis.itemid, moduleid: 0}}
322                 ]);
324                 requests[1].then(function(context) {
325                     return templates.render(pagerender, context);
326                 })
327                 .then(function(html, js) {
328                     return templates.replaceNode($('[data-region="' + pageregion + '"]'), html, js);
329                 })
330                 .then(pendingPromise.resolve)
331                 .catch(notification.exception);
332             });
333         }
335         $('[data-region="actions"] button').click(function(e) {
336             var pendingPromise = new Pending();
337             e.preventDefault();
339             localthis.pickCompetency()
340                 .then(pendingPromise.resolve)
341                 .catch();
342         });
343         $('[data-action="delete-competency-link"]').click(function(e) {
344             e.preventDefault();
346             var deleteid = $(e.target).closest('[data-id]').data('id');
347             localthis.deleteHandler(deleteid);
348         });
349     };
351     return /** @alias module:tool_lp/competencies */ competencies;
352 });