Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * A managed category.
3
 *
4
 * @namespace M.course.management
5
 * @class Category
6
 * @constructor
7
 * @extends Item
8
 */
9
Category = function() {
10
    Category.superclass.constructor.apply(this, arguments);
11
};
12
Category.NAME = 'moodle-course-management-category';
13
Category.CSS_PREFIX = 'management-category';
14
Category.ATTRS = {
15
    /**
16
     * The category ID relating to this category.
17
     * @attribute categoryid
18
     * @type Number
19
     * @writeOnce
20
     * @default null
21
     */
22
    categoryid: {
23
        getter: function(value, name) {
24
            if (value === null) {
25
                value = this.get('node').getData('id');
26
                this.set(name, value);
27
            }
28
            return value;
29
        },
30
        value: null,
31
        writeOnce: true
32
    },
33
 
34
    /**
35
     * True if this category is the currently selected category.
36
     * @attribute selected
37
     * @type Boolean
38
     * @default null
39
     */
40
    selected: {
41
        getter: function(value, name) {
42
            if (value === null) {
43
                value = this.get('node').getData(name);
44
                if (value === null) {
45
                    value = false;
46
                }
47
                this.set(name, value);
48
            }
49
            return value;
50
        },
51
        value: null
52
    },
53
 
54
    /**
55
     * An array of courses belonging to this category.
56
     * @attribute courses
57
     * @type Course[]
58
     * @default Array
59
     */
60
    courses: {
61
        validator: function(val) {
62
            return Y.Lang.isArray(val);
63
        },
64
        value: []
65
    }
66
};
67
Category.prototype = {
68
    /**
69
     * Initialises an instance of a Category.
70
     * @method initializer
71
     */
72
    initializer: function() {
73
        this.set('itemname', 'category');
74
    },
75
 
76
    /**
77
     * Returns the name of the category.
78
     * @method getName
79
     * @return {String}
80
     */
81
    getName: function() {
82
        return this.get('node').one('a.categoryname').get('innerHTML');
83
    },
84
 
85
    /**
86
     * Registers a course as belonging to this category.
87
     * @method registerCourse
88
     * @param {Course} course
89
     */
90
    registerCourse: function(course) {
91
        var courses = this.get('courses');
92
        courses.push(course);
93
        this.set('courses', courses);
94
    },
95
 
96
    /**
97
     * Handles a category related event.
98
     *
99
     * @method handle
100
     * @param {String} action
101
     * @param {EventFacade} e
102
     * @return {Boolean}
103
     */
104
    handle: function(action, e) {
105
        var catarg = {categoryid: this.get('categoryid')},
106
            selected = this.get('console').get('activecategoryid');
107
        if (selected && selected !== catarg.categoryid) {
108
            catarg.selectedcategory = selected;
109
        }
110
        switch (action) {
111
            case 'moveup':
112
                e.preventDefault();
113
                this.get('console').performAjaxAction('movecategoryup', catarg, this.moveup, this);
114
                break;
115
            case 'movedown':
116
                e.preventDefault();
117
                this.get('console').performAjaxAction('movecategorydown', catarg, this.movedown, this);
118
                break;
119
            case 'show':
120
                e.preventDefault();
121
                this.get('console').performAjaxAction('showcategory', catarg, this.show, this);
122
                break;
123
            case 'hide':
124
                e.preventDefault();
125
                this.get('console').performAjaxAction('hidecategory', catarg, this.hide, this);
126
                break;
127
            case 'expand':
128
                e.preventDefault();
129
                if (this.get('node').getData('expanded') === '0') {
130
                    this.get('node').setAttribute('data-expanded', '1').setData('expanded', 'true');
131
                    this.get('console').performAjaxAction('getsubcategorieshtml', catarg, this.loadSubcategories, this);
132
                }
133
                this.expand();
134
                break;
135
            case 'collapse':
136
                e.preventDefault();
137
                this.collapse();
138
                break;
139
            case 'select':
140
                var c = this.get('console'),
141
                    movecategoryto = c.get('categorylisting').one('#menumovecategoriesto');
142
                // If any category is selected and there are more then one categories.
143
                if (movecategoryto) {
144
                    if (c.isCategorySelected(e.currentTarget) &&
145
                            c.get('categories').length > 1) {
146
                        movecategoryto.removeAttribute('disabled');
147
                    } else {
148
                        movecategoryto.setAttribute('disabled', true);
149
                    }
150
                    c.handleBulkSortByaction();
151
                }
152
                break;
153
            default:
154
                Y.log('Invalid AJAX action requested of managed category.', 'warn', 'moodle-course-management');
155
                return false;
156
        }
157
    },
158
 
159
    /**
160
     * Expands the category making its sub categories visible.
161
     * @method expand
162
     */
163
    expand: function() {
164
        var node = this.get('node'),
165
            action = node.one('a[data-action=expand]'),
166
            ul = node.one('ul[role=group]');
167
        node.removeClass('collapsed').setAttribute('aria-expanded', 'true');
168
        action.setAttribute('data-action', 'collapse').setAttrs({
169
            title: M.util.get_string('collapsecategory', 'moodle', this.getName())
170
        });
171
 
172
        require(['core/str', 'core/templates', 'core/notification'], function(Str, Templates, Notification) {
173
            Str.get_string('collapse', 'core')
174
                .then(function(string) {
175
                    return Templates.renderPix('t/switch_minus', 'core', string);
176
                })
177
                .then(function(html) {
178
                    html = Y.Node.create(html).addClass('tree-icon').getDOMNode().outerHTML;
179
                    return action.set('innerHTML', html);
180
                }).fail(Notification.exception);
181
        });
182
 
183
        if (ul) {
184
            ul.setAttribute('aria-hidden', 'false');
185
        }
186
        this.get('console').performAjaxAction('expandcategory', {categoryid: this.get('categoryid')}, null, this);
187
    },
188
 
189
    /**
190
     * Collapses the category making its sub categories hidden.
191
     * @method collapse
192
     */
193
    collapse: function() {
194
        var node = this.get('node'),
195
            action = node.one('a[data-action=collapse]'),
196
            ul = node.one('ul[role=group]');
197
        node.addClass('collapsed').setAttribute('aria-expanded', 'false');
198
        action.setAttribute('data-action', 'expand').setAttrs({
199
            title: M.util.get_string('expandcategory', 'moodle', this.getName())
200
        });
201
 
202
        require(['core/str', 'core/templates', 'core/notification'], function(Str, Templates, Notification) {
203
            Str.get_string('expand', 'core')
204
                .then(function(string) {
205
                    return Templates.renderPix('t/switch_plus', 'core', string);
206
                })
207
                .then(function(html) {
208
                    html = Y.Node.create(html).addClass('tree-icon').getDOMNode().outerHTML;
209
                    return action.set('innerHTML', html);
210
                }).fail(Notification.exception);
211
        });
212
 
213
        if (ul) {
214
            ul.setAttribute('aria-hidden', 'true');
215
        }
216
        this.get('console').performAjaxAction('collapsecategory', {categoryid: this.get('categoryid')}, null, this);
217
    },
218
 
219
    /**
220
     * Loads sub categories provided by an AJAX request..
221
     *
222
     * @method loadSubcategories
223
     * @protected
224
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
225
     * @param {Object} response The response from the AJAX request.
226
     * @param {Object} args The arguments given to the request.
227
     * @return {Boolean} Returns true on success - false otherwise.
228
     */
229
    loadSubcategories: function(transactionid, response, args) {
230
        var outcome = this.checkAjaxResponse(transactionid, response, args),
231
            node = this.get('node'),
232
            managementconsole = this.get('console'),
233
            ul,
234
            actionnode;
235
        if (outcome === false) {
236
            Y.log('AJAX failed to load sub categories for ' + this.get('itemname'), 'warn', 'moodle-course-management');
237
            return false;
238
        }
239
        Y.log('AJAX loaded subcategories for ' + this.get('itemname'), 'info', 'moodle-course-management');
240
        node.append(outcome.html);
241
        managementconsole.initialiseCategories(node);
242
        if (M.core && M.core.actionmenu && M.core.actionmenu.newDOMNode) {
243
            M.core.actionmenu.newDOMNode(node);
244
        }
245
        ul = node.one('ul[role=group]');
246
        actionnode = node.one('a[data-action=collapse]');
247
        if (ul && actionnode) {
248
            actionnode.setAttribute('aria-controls', ul.generateID());
249
        }
250
        return true;
251
    },
252
 
253
    /**
254
     * Moves the course to this category.
255
     *
256
     * @method moveCourseTo
257
     * @param {Course} course
258
     */
259
    moveCourseTo: function(course) {
260
        require(['core/notification'], function(Notification) {
261
            Notification.saveCancelPromise(
262
                M.util.get_string('confirmation', 'admin'),
263
                M.util.get_string('confirmcoursemove', 'moodle',
264
                {
265
                    course: course.getName(),
266
                    category: this.getName(),
267
                }),
268
                M.util.get_string('move', 'moodle')
269
            ).then(function() {
270
                this.get('console').performAjaxAction('movecourseintocategory', {
271
                    courseid: course.get('courseid'),
272
                    categoryid: this.get('categoryid'),
273
                }, this.completeMoveCourse, this);
274
                return;
275
            }.bind(this)).catch(function() {
276
                // User cancelled.
277
            });
278
        }.bind(this));
279
    },
280
 
281
    /**
282
     * Completes moving a course to this category.
283
     * @method completeMoveCourse
284
     * @protected
285
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
286
     * @param {Object} response The response from the AJAX request.
287
     * @param {Object} args The arguments given to the request.
288
     * @return {Boolean}
289
     */
290
    completeMoveCourse: function(transactionid, response, args) {
291
        var outcome = this.checkAjaxResponse(transactionid, response, args),
292
            managementconsole = this.get('console'),
293
            category,
294
            course,
295
            totals;
296
        if (outcome === false) {
297
            Y.log('AJAX failed to move courses into this category: ' + this.get('itemname'), 'warn', 'moodle-course-management');
298
            return false;
299
        }
300
        course = managementconsole.getCourseById(args.courseid);
301
        if (!course) {
302
            Y.log('Course was moved but the course listing could not be found to reflect this', 'warn', 'moodle-course-management');
303
            return false;
304
        }
305
        Y.log('Moved the course (' + course.getName() + ') into this category (' + this.getName() + ')',
306
            'debug', 'moodle-course-management');
307
        this.highlight();
308
        if (course) {
309
            if (outcome.paginationtotals) {
310
                totals = managementconsole.get('courselisting').one('.listing-pagination-totals');
311
                if (totals) {
312
                    totals.set('innerHTML', outcome.paginationtotals);
313
                }
314
            }
315
            if (outcome.totalcatcourses !== 'undefined') {
316
                totals = this.get('node').one('.course-count span');
317
                if (totals) {
318
                    totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.totalcatcourses));
319
                }
320
            }
321
            if (typeof outcome.fromcatcoursecount !== 'undefined') {
322
                category = managementconsole.get('activecategoryid');
323
                category = managementconsole.getCategoryById(category);
324
                if (category) {
325
                    totals = category.get('node').one('.course-count span');
326
                    if (totals) {
327
                        totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.fromcatcoursecount));
328
                    }
329
                }
330
            }
331
            course.remove();
332
        }
333
        return true;
334
    },
335
 
336
    /**
337
     * Makes an item visible.
338
     *
339
     * @method show
340
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
341
     * @param {Object} response The response from the AJAX request.
342
     * @param {Object} args The arguments given to the request.
343
     * @return {Boolean}
344
     */
345
    show: function(transactionid, response, args) {
346
        var outcome = this.checkAjaxResponse(transactionid, response, args),
347
            hidebtn;
348
        if (outcome === false) {
349
            Y.log('AJAX request to show ' + this.get('itemname') + ' by outcome.', 'warn', 'moodle-course-management');
350
            return false;
351
        }
352
 
353
        this.markVisible();
354
        hidebtn = this.get('node').one('a[data-action=hide]');
355
        if (hidebtn) {
356
            hidebtn.focus();
357
        }
358
        if (outcome.categoryvisibility) {
359
            this.updateChildVisibility(outcome.categoryvisibility);
360
        }
361
        if (outcome.coursevisibility) {
362
            this.updateCourseVisiblity(outcome.coursevisibility);
363
        }
364
        this.updated();
365
        Y.log('Success: category made visible by AJAX.', 'info', 'moodle-course-management');
366
    },
367
 
368
    /**
369
     * Hides an item.
370
     *
371
     * @method hide
372
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
373
     * @param {Object} response The response from the AJAX request.
374
     * @param {Object} args The arguments given to the request.
375
     * @return {Boolean}
376
     */
377
    hide: function(transactionid, response, args) {
378
        var outcome = this.checkAjaxResponse(transactionid, response, args),
379
            showbtn;
380
        if (outcome === false) {
381
            Y.log('AJAX request to hide ' + this.get('itemname') + ' by outcome.', 'warn', 'moodle-course-management');
382
            return false;
383
        }
384
        this.markHidden();
385
        showbtn = this.get('node').one('a[data-action=show]');
386
        if (showbtn) {
387
            showbtn.focus();
388
        }
389
        if (outcome.categoryvisibility) {
390
            this.updateChildVisibility(outcome.categoryvisibility);
391
        }
392
        if (outcome.coursevisibility) {
393
            this.updateCourseVisiblity(outcome.coursevisibility);
394
        }
395
        this.updated();
396
        Y.log('Success: ' + this.get('itemname') + ' made hidden by AJAX.', 'info', 'moodle-course-management');
397
    },
398
 
399
    /**
400
     * Updates the visibility of child courses if required.
401
     * @method updateCourseVisiblity
402
     * @chainable
403
     * @param courses
404
     */
405
    updateCourseVisiblity: function(courses) {
406
        var managementconsole = this.get('console'),
407
            key,
408
            course;
409
        Y.log('Changing categories course visibility', 'info', 'moodle-course-management');
410
        try {
411
            for (key in courses) {
412
                if (typeof courses[key] === 'object') {
413
                    course = managementconsole.getCourseById(courses[key].id);
414
                    if (course) {
415
                        if (courses[key].visible === "1") {
416
                            course.markVisible();
417
                        } else {
418
                            course.markHidden();
419
                        }
420
                    }
421
                }
422
            }
423
        } catch (err) {
424
            Y.log('Error trying to update course visibility: ' + err.message, 'warn', 'moodle-course-management');
425
        }
426
        return this;
427
    },
428
 
429
    /**
430
     * Updates the visibility of subcategories if required.
431
     * @method updateChildVisibility
432
     * @chainable
433
     * @param categories
434
     */
435
    updateChildVisibility: function(categories) {
436
        var managementconsole = this.get('console'),
437
            key,
438
            category;
439
        Y.log('Changing categories subcategory visibility', 'info', 'moodle-course-management');
440
        try {
441
            for (key in categories) {
442
                if (typeof categories[key] === 'object') {
443
                    category = managementconsole.getCategoryById(categories[key].id);
444
                    if (category) {
445
                        if (categories[key].visible === "1") {
446
                            category.markVisible();
447
                        } else {
448
                            category.markHidden();
449
                        }
450
                    }
451
                }
452
            }
453
        } catch (err) {
454
            Y.log('Error trying to update category visibility: ' + err.message, 'warn', 'moodle-course-management');
455
        }
456
        return this;
457
    }
458
};
459
Y.extend(Category, Item, Category.prototype);