Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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();
1441 ariadna 125
                var courseCount = this.get('node').getData('course-count');
126
                if (courseCount === '0') {
127
                    this.get('console').performAjaxAction('hidecategory', catarg, this.hide, this);
128
                    break;
129
                }
130
                var warningStr = courseCount === '1' ? 'hidecategoryone' : 'hidecategorymany';
131
                var warningParams = {
132
                    category: this.get('node').getData('category-name'),
133
                    coursecount: courseCount,
134
                };
135
                require(['core/notification', 'core/str'], function(Notification, Str) {
136
                    Notification.saveCancelPromise(
137
                        Str.get_string('hidecategory'),
138
                        Str.get_string(warningStr, 'core', warningParams),
139
                        Str.get_string('hide')
140
                    ).then(function() {
141
                        this.get('console').performAjaxAction('hidecategory', catarg, this.hide, this);
142
                    }.bind(this)
143
                    ).catch(function() {
144
                        // User cancelled, no action needed.
145
                    });
146
                }.bind(this));
1 efrain 147
                break;
148
            case 'expand':
149
                e.preventDefault();
150
                if (this.get('node').getData('expanded') === '0') {
151
                    this.get('node').setAttribute('data-expanded', '1').setData('expanded', 'true');
152
                    this.get('console').performAjaxAction('getsubcategorieshtml', catarg, this.loadSubcategories, this);
153
                }
154
                this.expand();
155
                break;
156
            case 'collapse':
157
                e.preventDefault();
158
                this.collapse();
159
                break;
160
            case 'select':
161
                var c = this.get('console'),
162
                    movecategoryto = c.get('categorylisting').one('#menumovecategoriesto');
163
                // If any category is selected and there are more then one categories.
164
                if (movecategoryto) {
165
                    if (c.isCategorySelected(e.currentTarget) &&
166
                            c.get('categories').length > 1) {
167
                        movecategoryto.removeAttribute('disabled');
168
                    } else {
169
                        movecategoryto.setAttribute('disabled', true);
170
                    }
171
                    c.handleBulkSortByaction();
172
                }
173
                break;
174
            default:
175
                Y.log('Invalid AJAX action requested of managed category.', 'warn', 'moodle-course-management');
176
                return false;
177
        }
178
    },
179
 
180
    /**
181
     * Expands the category making its sub categories visible.
182
     * @method expand
183
     */
184
    expand: function() {
185
        var node = this.get('node'),
186
            action = node.one('a[data-action=expand]'),
187
            ul = node.one('ul[role=group]');
188
        node.removeClass('collapsed').setAttribute('aria-expanded', 'true');
189
        action.setAttribute('data-action', 'collapse').setAttrs({
190
            title: M.util.get_string('collapsecategory', 'moodle', this.getName())
191
        });
192
 
193
        require(['core/str', 'core/templates', 'core/notification'], function(Str, Templates, Notification) {
194
            Str.get_string('collapse', 'core')
195
                .then(function(string) {
196
                    return Templates.renderPix('t/switch_minus', 'core', string);
197
                })
198
                .then(function(html) {
199
                    html = Y.Node.create(html).addClass('tree-icon').getDOMNode().outerHTML;
200
                    return action.set('innerHTML', html);
201
                }).fail(Notification.exception);
202
        });
203
 
204
        if (ul) {
205
            ul.setAttribute('aria-hidden', 'false');
206
        }
207
        this.get('console').performAjaxAction('expandcategory', {categoryid: this.get('categoryid')}, null, this);
208
    },
209
 
210
    /**
211
     * Collapses the category making its sub categories hidden.
212
     * @method collapse
213
     */
214
    collapse: function() {
215
        var node = this.get('node'),
216
            action = node.one('a[data-action=collapse]'),
217
            ul = node.one('ul[role=group]');
218
        node.addClass('collapsed').setAttribute('aria-expanded', 'false');
219
        action.setAttribute('data-action', 'expand').setAttrs({
220
            title: M.util.get_string('expandcategory', 'moodle', this.getName())
221
        });
222
 
223
        require(['core/str', 'core/templates', 'core/notification'], function(Str, Templates, Notification) {
224
            Str.get_string('expand', 'core')
225
                .then(function(string) {
226
                    return Templates.renderPix('t/switch_plus', 'core', string);
227
                })
228
                .then(function(html) {
229
                    html = Y.Node.create(html).addClass('tree-icon').getDOMNode().outerHTML;
230
                    return action.set('innerHTML', html);
231
                }).fail(Notification.exception);
232
        });
233
 
234
        if (ul) {
235
            ul.setAttribute('aria-hidden', 'true');
236
        }
237
        this.get('console').performAjaxAction('collapsecategory', {categoryid: this.get('categoryid')}, null, this);
238
    },
239
 
240
    /**
241
     * Loads sub categories provided by an AJAX request..
242
     *
243
     * @method loadSubcategories
244
     * @protected
245
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
246
     * @param {Object} response The response from the AJAX request.
247
     * @param {Object} args The arguments given to the request.
248
     * @return {Boolean} Returns true on success - false otherwise.
249
     */
250
    loadSubcategories: function(transactionid, response, args) {
251
        var outcome = this.checkAjaxResponse(transactionid, response, args),
252
            node = this.get('node'),
253
            managementconsole = this.get('console'),
254
            ul,
255
            actionnode;
256
        if (outcome === false) {
257
            Y.log('AJAX failed to load sub categories for ' + this.get('itemname'), 'warn', 'moodle-course-management');
258
            return false;
259
        }
260
        Y.log('AJAX loaded subcategories for ' + this.get('itemname'), 'info', 'moodle-course-management');
261
        node.append(outcome.html);
262
        managementconsole.initialiseCategories(node);
263
        if (M.core && M.core.actionmenu && M.core.actionmenu.newDOMNode) {
264
            M.core.actionmenu.newDOMNode(node);
265
        }
266
        ul = node.one('ul[role=group]');
267
        actionnode = node.one('a[data-action=collapse]');
268
        if (ul && actionnode) {
269
            actionnode.setAttribute('aria-controls', ul.generateID());
270
        }
271
        return true;
272
    },
273
 
274
    /**
275
     * Moves the course to this category.
276
     *
277
     * @method moveCourseTo
278
     * @param {Course} course
279
     */
280
    moveCourseTo: function(course) {
281
        require(['core/notification'], function(Notification) {
282
            Notification.saveCancelPromise(
283
                M.util.get_string('confirmation', 'admin'),
284
                M.util.get_string('confirmcoursemove', 'moodle',
285
                {
286
                    course: course.getName(),
287
                    category: this.getName(),
288
                }),
289
                M.util.get_string('move', 'moodle')
290
            ).then(function() {
291
                this.get('console').performAjaxAction('movecourseintocategory', {
292
                    courseid: course.get('courseid'),
293
                    categoryid: this.get('categoryid'),
294
                }, this.completeMoveCourse, this);
295
                return;
296
            }.bind(this)).catch(function() {
297
                // User cancelled.
298
            });
299
        }.bind(this));
300
    },
301
 
302
    /**
303
     * Completes moving a course to this category.
304
     * @method completeMoveCourse
305
     * @protected
306
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
307
     * @param {Object} response The response from the AJAX request.
308
     * @param {Object} args The arguments given to the request.
309
     * @return {Boolean}
310
     */
311
    completeMoveCourse: function(transactionid, response, args) {
312
        var outcome = this.checkAjaxResponse(transactionid, response, args),
313
            managementconsole = this.get('console'),
314
            category,
315
            course,
316
            totals;
317
        if (outcome === false) {
318
            Y.log('AJAX failed to move courses into this category: ' + this.get('itemname'), 'warn', 'moodle-course-management');
319
            return false;
320
        }
321
        course = managementconsole.getCourseById(args.courseid);
322
        if (!course) {
323
            Y.log('Course was moved but the course listing could not be found to reflect this', 'warn', 'moodle-course-management');
324
            return false;
325
        }
326
        Y.log('Moved the course (' + course.getName() + ') into this category (' + this.getName() + ')',
327
            'debug', 'moodle-course-management');
328
        this.highlight();
329
        if (course) {
330
            if (outcome.paginationtotals) {
331
                totals = managementconsole.get('courselisting').one('.listing-pagination-totals');
332
                if (totals) {
333
                    totals.set('innerHTML', outcome.paginationtotals);
334
                }
335
            }
336
            if (outcome.totalcatcourses !== 'undefined') {
337
                totals = this.get('node').one('.course-count span');
338
                if (totals) {
339
                    totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.totalcatcourses));
340
                }
341
            }
342
            if (typeof outcome.fromcatcoursecount !== 'undefined') {
343
                category = managementconsole.get('activecategoryid');
344
                category = managementconsole.getCategoryById(category);
345
                if (category) {
346
                    totals = category.get('node').one('.course-count span');
347
                    if (totals) {
348
                        totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.fromcatcoursecount));
349
                    }
350
                }
351
            }
352
            course.remove();
353
        }
354
        return true;
355
    },
356
 
357
    /**
358
     * Makes an item visible.
359
     *
360
     * @method show
361
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
362
     * @param {Object} response The response from the AJAX request.
363
     * @param {Object} args The arguments given to the request.
364
     * @return {Boolean}
365
     */
366
    show: function(transactionid, response, args) {
367
        var outcome = this.checkAjaxResponse(transactionid, response, args),
368
            hidebtn;
369
        if (outcome === false) {
370
            Y.log('AJAX request to show ' + this.get('itemname') + ' by outcome.', 'warn', 'moodle-course-management');
371
            return false;
372
        }
373
 
374
        this.markVisible();
375
        hidebtn = this.get('node').one('a[data-action=hide]');
376
        if (hidebtn) {
377
            hidebtn.focus();
378
        }
379
        if (outcome.categoryvisibility) {
380
            this.updateChildVisibility(outcome.categoryvisibility);
381
        }
382
        if (outcome.coursevisibility) {
383
            this.updateCourseVisiblity(outcome.coursevisibility);
384
        }
385
        this.updated();
386
        Y.log('Success: category made visible by AJAX.', 'info', 'moodle-course-management');
387
    },
388
 
389
    /**
390
     * Hides an item.
391
     *
392
     * @method hide
393
     * @param {Number} transactionid The transaction ID of the AJAX request (unique)
394
     * @param {Object} response The response from the AJAX request.
395
     * @param {Object} args The arguments given to the request.
396
     * @return {Boolean}
397
     */
398
    hide: function(transactionid, response, args) {
399
        var outcome = this.checkAjaxResponse(transactionid, response, args),
400
            showbtn;
401
        if (outcome === false) {
402
            Y.log('AJAX request to hide ' + this.get('itemname') + ' by outcome.', 'warn', 'moodle-course-management');
403
            return false;
404
        }
405
        this.markHidden();
406
        showbtn = this.get('node').one('a[data-action=show]');
407
        if (showbtn) {
408
            showbtn.focus();
409
        }
410
        if (outcome.categoryvisibility) {
411
            this.updateChildVisibility(outcome.categoryvisibility);
412
        }
413
        if (outcome.coursevisibility) {
414
            this.updateCourseVisiblity(outcome.coursevisibility);
415
        }
416
        this.updated();
417
        Y.log('Success: ' + this.get('itemname') + ' made hidden by AJAX.', 'info', 'moodle-course-management');
418
    },
419
 
420
    /**
421
     * Updates the visibility of child courses if required.
422
     * @method updateCourseVisiblity
423
     * @chainable
424
     * @param courses
425
     */
426
    updateCourseVisiblity: function(courses) {
427
        var managementconsole = this.get('console'),
428
            key,
429
            course;
430
        Y.log('Changing categories course visibility', 'info', 'moodle-course-management');
431
        try {
432
            for (key in courses) {
433
                if (typeof courses[key] === 'object') {
434
                    course = managementconsole.getCourseById(courses[key].id);
435
                    if (course) {
436
                        if (courses[key].visible === "1") {
437
                            course.markVisible();
438
                        } else {
439
                            course.markHidden();
440
                        }
441
                    }
442
                }
443
            }
444
        } catch (err) {
445
            Y.log('Error trying to update course visibility: ' + err.message, 'warn', 'moodle-course-management');
446
        }
447
        return this;
448
    },
449
 
450
    /**
451
     * Updates the visibility of subcategories if required.
452
     * @method updateChildVisibility
453
     * @chainable
454
     * @param categories
455
     */
456
    updateChildVisibility: function(categories) {
457
        var managementconsole = this.get('console'),
458
            key,
459
            category;
460
        Y.log('Changing categories subcategory visibility', 'info', 'moodle-course-management');
461
        try {
462
            for (key in categories) {
463
                if (typeof categories[key] === 'object') {
464
                    category = managementconsole.getCategoryById(categories[key].id);
465
                    if (category) {
466
                        if (categories[key].visible === "1") {
467
                            category.markVisible();
468
                        } else {
469
                            category.markHidden();
470
                        }
471
                    }
472
                }
473
            }
474
        } catch (err) {
475
            Y.log('Error trying to update category visibility: ' + err.message, 'warn', 'moodle-course-management');
476
        }
477
        return this;
478
    }
479
};
480
Y.extend(Category, Item, Category.prototype);