// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Competency picker from user plans.
*
* To handle 'save' events use: picker.on('save').
*
* This will receive a object with either a single 'competencyId', or an array in 'competencyIds'
* depending on the value of multiSelect.
*
* @module tool_lp/competencypicker_user_plans
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery',
'core/notification',
'core/ajax',
'core/templates',
'core/str',
'tool_lp/tree',
'tool_lp/competencypicker'
],
function($, Notification, Ajax, Templates, Str, Tree, PickerBase) {
/**
* Competency picker in plan class.
*
* @class tool_lp/competencypicker_user_plans
* @param {Number} userId
* @param {Number|false} singlePlan The ID of the plan when limited to one.
* @param {Boolean} multiSelect Support multi-select in the tree.
*/
var Picker = function(userId, singlePlan, multiSelect) {
PickerBase.prototype.constructor.apply(this, [1, false, 'self', multiSelect]);
this._userId = userId;
this._plans = [];
if (singlePlan) {
this._planId = singlePlan;
this._singlePlan = true;
}
};
Picker.prototype = Object.create(PickerBase.prototype);
/** @property {Array} The list of plans fetched. */
Picker.prototype._plans = null;
/** @property {Number} The current plan ID. */
Picker.prototype._planId = null;
/** @property {Boolean} Whether we can browse plans or not. */
Picker.prototype._singlePlan = false;
/** @property {Number} The user the plans belongs to. */
Picker.prototype._userId = null;
/**
* Hook to executed after the view is rendered.
*
* @method _afterRender
*/
Picker.prototype._afterRender = function() {
var self = this;
PickerBase.prototype._afterRender.apply(self, arguments);
// Add listener for framework change.
if (!self._singlePlan) {
self._find('[data-action="chooseplan"]').change(function(e) {
self._planId = $(e.target).val();
self._loadCompetencies().then(self._refresh.bind(self))
.catch(Notification.exception);
});
}
};
/**
* Fetch the competencies.
*
* @param {Number} planId The planId.
* @param {String} searchText Limit the competencies to those matching the text.
* @method _fetchCompetencies
* @return {Promise} The promise object.
*/
Picker.prototype._fetchCompetencies = function(planId, searchText) {
var self = this;
return Ajax.call([
{methodname: 'core_competency_list_plan_competencies', args: {
id: planId
}}
])[0].done(function(competencies) {
// Expand the list of competencies into a fake tree.
var i, comp;
var tree = [];
for (i = 0; i < competencies.length; i++) {
comp = competencies[i].competency;
if (comp.shortname.toLowerCase().indexOf(searchText.toLowerCase()) < 0) {
continue;
}
comp.children = [];
comp.haschildren = 0;
tree.push(comp);
}
self._competencies = tree;
}).fail(Notification.exception);
};
/**
* Convenience method to get a plan object.
*
* @param {Number} id The plan ID.
* @return {Object|undefined} The plan.
* @method _getPlan
*/
Picker.prototype._getPlan = function(id) {
var plan;
$.each(this._plans, function(i, f) {
if (f.id == id) {
plan = f;
return;
}
});
return plan;
};
/**
* Load the competencies.
*
* @method _loadCompetencies
* @return {Promise}
*/
Picker.prototype._loadCompetencies = function() {
return this._fetchCompetencies(this._planId, this._searchText);
};
/**
* Load the plans.
*
* @method _loadPlans
* @return {Promise}
*/
Picker.prototype._loadPlans = function() {
var promise,
self = this;
// Quit early because we already have the data.
if (self._plans.length > 0) {
return $.when();
}
if (self._singlePlan) {
promise = Ajax.call([
{methodname: 'core_competency_read_plan', args: {
id: this._planId
}}
])[0].then(function(plan) {
return [plan];
});
} else {
promise = Ajax.call([
{methodname: 'core_competency_list_user_plans', args: {
userid: self._userId
}}
])[0];
}
return promise.done(function(plans) {
self._plans = plans;
}).fail(Notification.exception);
};
/**
* Hook to executed before render.
*
* @method _preRender
* @return {Promise}
*/
Picker.prototype._preRender = function() {
var self = this;
return self._loadPlans().then(function() {
if (!self._planId && self._plans.length > 0) {
self._planId = self._plans[0].id;
}
// We could not set a framework ID, that probably means there are no frameworks accessible.
if (!self._planId) {
self._plans = [];
return $.when();
}
return self._loadCompetencies();
});
};
/**
* Render the dialogue.
*
* @method _render
* @return {Promise}
*/
Picker.prototype._render = function() {
var self = this;
return self._preRender().then(function() {
if (!self._singlePlan) {
$.each(self._plans, function(i, plan) {
if (plan.id == self._planId) {
plan.selected = true;
} else {
plan.selected = false;
}
});
}
var context = {
competencies: self._competencies,
plan: self._getPlan(self._planId),
plans: self._plans,
search: self._searchText,
singlePlan: self._singlePlan,
};
return Templates.render('tool_lp/competency_picker_user_plans', context);
});
};
return Picker;
});