MDL-51869 tool_lp: Linking evidence of prior learning with competencies

This commit is contained in:
Frederic Massart
2016-04-18 10:58:46 +08:00
parent 156675ed3d
commit 52eda87637
24 changed files with 1015 additions and 63 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
define(["jquery","core/notification","core/ajax","core/templates","core/str","tool_lp/tree","tool_lp/competencypicker"],function(a,b,c,d,e,f,g){var h=function(a,b,c){g.prototype.constructor.apply(this,[1,!1,"self",c]),this._userId=a,this._plans=[],b&&(this._planId=b,this._singlePlan=!0)};return h.prototype=Object.create(g.prototype),h.prototype._plans=null,h.prototype._planId=null,h.prototype._singlePlan=!1,h.prototype._userId=null,h.prototype._afterRender=function(){var b=this;g.prototype._afterRender.apply(b,arguments),b._singlePlan||b._find('[data-action="chooseplan"]').change(function(c){b._planId=a(c.target).val(),b._loadCompetencies().then(b._refresh.bind(b))}.bind(b))},h.prototype._fetchCompetencies=function(a,d){var e=this;return c.call([{methodname:"tool_lp_list_plan_competencies",args:{id:a}}])[0].done(function(a){var b,c,f=[];for(b=0;b<a.length;b++)c=a[b].competency,c.shortname.toLowerCase().indexOf(d.toLowerCase())<0||(c.children=[],c.haschildren=0,f.push(c));e._competencies=f}).fail(b.exception)},h.prototype._getPlan=function(b){var c;return a.each(this._plans,function(a,d){return d.id==b?(c=d,!1):void 0}),c},h.prototype._loadCompetencies=function(){return this._fetchCompetencies(this._planId,this._searchText)},h.prototype._loadPlans=function(){var d,e=this;return e._plans.length>0?a.when():(d=e._singlePlan?c.call([{methodname:"tool_lp_read_plan",args:{id:this._planId}}])[0].then(function(a){return[a]}):c.call([{methodname:"tool_lp_list_user_plans",args:{userid:e._userId}}])[0],d.done(function(a){e._plans=a}).fail(b.exception))},h.prototype._preRender=function(){var b=this;return b._loadPlans().then(function(){return!b._planId&&b._plans.length>0&&(b._planId=b._plans[0].id),b._planId?b._loadCompetencies():(b._plans=[],a.when())}.bind(b))},h.prototype._render=function(){var b=this;return b._preRender().then(function(){b._singlePlan||a.each(b._plans,function(a,c){c.id==b._planId?c.selected=!0:c.selected=!1});var c={competencies:b._competencies,plan:b._getPlan(b._planId),plans:b._plans,search:b._searchText,singlePlan:b._singlePlan};return d.render("tool_lp/competency_picker_user_plans",c)}.bind(b))},h});
+1
View File
@@ -0,0 +1 @@
define(["jquery","core/templates","core/ajax","core/notification","core/str","tool_lp/menubar","tool_lp/competencypicker_user_plans"],function(a,b,c,d,e,f,g){var h=function(a){if(this._type=a,"evidence"===a)this._region='[data-region="user-evidence-page"]',this._evidenceNode='[data-region="user-evidence-page"]',this._template="tool_lp/user_evidence_page",this._contextMethod="tool_lp_data_for_user_evidence_page";else{if("list"!==a)throw new TypeError("Unexpected type.");this._region='[data-region="user-evidence-list"]',this._evidenceNode='[data-region="user-evidence-node"]',this._template="tool_lp/user_evidence_list_page",this._contextMethod="tool_lp_data_for_user_evidence_list_page"}};return h.prototype._contextMethod=null,h.prototype._evidenceNode=null,h.prototype._region=null,h.prototype._template=null,h.prototype._type=null,h.prototype._getContextArgs=function(a){var b=this,c={};return"evidence"===b._type?c={id:a.id}:"list"===b._type&&(c={userid:a.userid}),c},h.prototype._renderView=function(c){var e=this;b.render(e._template,c).done(function(c,d){b.replaceNode(a(e._region),c,d)}.bind(e)).fail(d.exception)},h.prototype._callAndRefresh=function(b,e){var f=this;return b.push({methodname:f._contextMethod,args:f._getContextArgs(e)}),a.when.apply(a.when,c.call(b)).then(function(){f._renderView.call(f,arguments[arguments.length-1])}).fail(d.exception)},h.prototype._doDelete=function(a){var b=this,c=[{methodname:"tool_lp_delete_user_evidence",args:{id:a.id}}];b._callAndRefresh(c,a)},h.prototype.deleteEvidence=function(a){var b,f=this;b=c.call([{methodname:"tool_lp_read_user_evidence",args:{id:a.id}}]),b[0].done(function(b){e.get_strings([{key:"confirm",component:"moodle"},{key:"deleteuserevidence",component:"tool_lp",param:b.name},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(b){d.confirm(b[0],b[1],b[2],b[3],function(){f._doDelete(a)}.bind(f))}).fail(d.exception)}).fail(d.exception)},h.prototype._deleteEvidenceHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.deleteEvidence(c)},h.prototype._doCreateUserEvidenceCompetency=function(b,c){var d=this,e=[];a.each(c,function(a,c){e.push({methodname:"tool_lp_create_user_evidence_competency",args:{userevidenceid:b.id,competencyid:c}})}),d._callAndRefresh(e,b)},h.prototype.createUserEvidenceCompetency=function(a){var b=this,c=new g(a.userid);c.on("save",function(c,d){var e=d.competencyIds;b._doCreateUserEvidenceCompetency(a,e)}.bind(b)),c.display()},h.prototype._createUserEvidenceCompetencyHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.createUserEvidenceCompetency(c)},h.prototype._doDeleteUserEvidenceCompetency=function(a,b){var c=this,d=[];d.push({methodname:"tool_lp_delete_user_evidence_competency",args:{userevidenceid:a.id,competencyid:b}}),c._callAndRefresh(d,a)},h.prototype.deleteUserEvidenceCompetency=function(a,b){this._doDeleteUserEvidenceCompetency(a,b)},h.prototype._deleteUserEvidenceCompetencyHandler=function(b){var c=this._findEvidenceData(a(b.currentTarget)),d=a(b.currentTarget).data("id");b.preventDefault(),this.deleteUserEvidenceCompetency(c,d)},h.prototype._findEvidenceData=function(b){var c,d=b.parentsUntil(a(this._region).parent(),this._evidenceNode);if(1!=d.length)throw new Error("The evidence node was not located.");if(c=d.data(),"undefined"==typeof c||"undefined"==typeof c.id)throw new Error("Evidence data could not be found.");return c},h.prototype.enhanceMenubar=function(a){var b=this;f.enhance(a,{'[data-action="user-evidence-delete"]':b._deleteEvidenceHandler.bind(b),'[data-action="link-competency"]':b._createUserEvidenceCompetencyHandler.bind(b)})},h.prototype.registerEvents=function(){var b=a(this._region),c=this;b.find('[data-action="user-evidence-delete"]').click(c._deleteEvidenceHandler.bind(c)),b.find('[data-action="link-competency"]').click(c._createUserEvidenceCompetencyHandler.bind(c)),b.find('[data-action="delete-competency-link"]').click(c._deleteUserEvidenceCompetencyHandler.bind(c))},h});
+38 -31
View File
@@ -34,8 +34,6 @@ define(['jquery',
'tool_lp/tree'],
function($, Notification, Ajax, Templates, Dialogue, Str, Tree) {
var self;
/**
* Competency picker class.
* @param {Number} pageContextId The page context ID.
@@ -44,7 +42,7 @@ define(['jquery',
* @param {Boolean} multiSelect Support multi-select in the tree.
*/
var Picker = function(pageContextId, singleFramework, pageContextIncludes, multiSelect) {
self = this;
var self = this;
self._eventNode = $('<div></div>');
self._frameworks = [];
self._reset();
@@ -89,6 +87,7 @@ define(['jquery',
* @method _afterRender
*/
Picker.prototype._afterRender = function() {
var self = this;
// Initialise the tree.
var tree = new Tree(self._find('[data-enhance=linktree]'), self._multiSelect);
@@ -117,7 +116,7 @@ define(['jquery',
if (valid) {
validIds.push(compId);
}
});
}.bind(self));
self._selectedCompetencies = validIds;
@@ -127,14 +126,14 @@ define(['jquery',
} else {
self._find('[data-region="competencylinktree"] [data-action="add"]').removeAttr('disabled');
}
});
}.bind(self));
// Add listener for framework change.
if (!self._singleFramework) {
self._find('[data-action="chooseframework"]').change(function(e) {
self._frameworkId = $(e.target).val();
self._loadCompetencies().then(self._refresh);
});
self._loadCompetencies().then(self._refresh.bind(self));
}.bind(self));
}
// Add listener for search.
@@ -145,13 +144,13 @@ define(['jquery',
return self._refresh().always(function() {
$(e.target).removeAttr('disabled');
});
});
}.bind(self));
// Add listener for cancel.
self._find('[data-region="competencylinktree"] [data-action="cancel"]').click(function(e) {
e.preventDefault();
self.close();
});
}.bind(self));
// Add listener for add.
self._find('[data-region="competencylinktree"] [data-action="add"]').click(function(e) {
@@ -168,7 +167,7 @@ define(['jquery',
}
self.close();
});
}.bind(self));
// The list of selected competencies will be modified while looping (because of the listeners above).
var currentItems = self._selectedCompetencies.slice(0);
@@ -179,7 +178,7 @@ define(['jquery',
tree.toggleItem(node);
tree.updateFocus(node);
}
});
}.bind(self));
};
@@ -189,6 +188,7 @@ define(['jquery',
* @method close
*/
Picker.prototype.close = function() {
var self = this;
self._popup.close();
self._reset();
};
@@ -200,15 +200,16 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype.display = function() {
return self._render().done(function(html) {
return Str.get_string('competencypicker', 'tool_lp').done(function(title) {
var self = this;
return self._render().then(function(html) {
return Str.get_string('competencypicker', 'tool_lp').then(function(title) {
self._popup = new Dialogue(
title,
html,
self._afterRender.bind(self)
);
});
}).fail(Notification.exception);
}.bind(self));
}.bind(self)).fail(Notification.exception);
};
/**
@@ -220,6 +221,8 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._fetchCompetencies = function(frameworkId, searchText) {
var self = this;
return Ajax.call([
{ methodname: 'tool_lp_search_competencies', args: {
searchtext: searchText,
@@ -253,7 +256,7 @@ define(['jquery',
self._competencies = tree;
}).fail(Notification.exception);
}.bind(self)).fail(Notification.exception);
};
/**
@@ -263,7 +266,7 @@ define(['jquery',
* @method _find
*/
Picker.prototype._find = function(selector) {
return $(self._popup.getContent()).find(selector);
return $(this._popup.getContent()).find(selector);
};
/**
@@ -274,7 +277,7 @@ define(['jquery',
*/
Picker.prototype._getFramework = function(fid) {
var frm;
$.each(self._frameworks, function(i, f) {
$.each(this._frameworks, function(i, f) {
if (f.id == fid) {
frm = f;
return false;
@@ -290,7 +293,7 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._loadCompetencies = function() {
return self._fetchCompetencies(self._frameworkId, self._searchText);
return this._fetchCompetencies(this._frameworkId, this._searchText);
};
/**
@@ -300,7 +303,8 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._loadFrameworks = function() {
var promise;
var promise,
self = this;
// Quit early because we already have the data.
if (self._frameworks.length > 0) {
@@ -338,7 +342,7 @@ define(['jquery',
* @method on
*/
Picker.prototype.on = function(type, handler) {
self._eventNode.on(type, handler);
this._eventNode.on(type, handler);
};
/**
@@ -348,6 +352,7 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._preRender = function() {
var self = this;
return self._loadFrameworks().then(function() {
if (!self._frameworkId && self._frameworks.length > 0) {
self._frameworkId = self._frameworks[0].id;
@@ -360,7 +365,7 @@ define(['jquery',
}
return self._loadCompetencies();
});
}.bind(self));
};
/**
@@ -370,10 +375,11 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._refresh = function() {
var self = this;
return self._render().then(function(html) {
self._find('[data-region="competencylinktree"]').replaceWith(html);
self._afterRender();
});
}.bind(self));
};
/**
@@ -383,6 +389,7 @@ define(['jquery',
* @return {Promise}
*/
Picker.prototype._render = function() {
var self = this;
return self._preRender().then(function() {
if (!self._singleFramework) {
@@ -404,7 +411,7 @@ define(['jquery',
};
return Templates.render('tool_lp/competency_picker', context);
});
}.bind(self));
};
/**
@@ -415,11 +422,11 @@ define(['jquery',
* @method _reset
*/
Picker.prototype._reset = function() {
self._competencies = [];
self._disallowedCompetencyIDs = [];
self._popup = null;
self._searchText = '';
self._selectedCompetencies = [];
this._competencies = [];
this._disallowedCompetencyIDs = [];
this._popup = null;
this._searchText = '';
this._selectedCompetencies = [];
};
/**
@@ -431,7 +438,7 @@ define(['jquery',
* @method _setDisallowedCompetencyIDs
*/
Picker.prototype.setDisallowedCompetencyIDs = function(ids) {
self._disallowedCompetencyIDs = ids;
this._disallowedCompetencyIDs = ids;
};
/**
@@ -442,7 +449,7 @@ define(['jquery',
* @method _reset
*/
Picker.prototype._trigger = function(type, data) {
self._eventNode.trigger(type, [data]);
this._eventNode.trigger(type, [data]);
};
return /** @alias module:tool_lp/competencypicker */ Picker;
@@ -0,0 +1,241 @@
// 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.
*
* @package tool_lp
* @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.
*
* @param {Number|false} singlePlan The ID of the plan when limited to one.
* @param {String} pageContextIncludes One of 'children', 'parents', 'self'.
* @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);
/** @type {Array} The list of plans fetched. */
Picker.prototype._plans = null;
/** @type {Number} The current plan ID. */
Picker.prototype._planId = null;
/** @type {Boolean} Whether we can browse plans or not. */
Picker.prototype._singlePlan = false;
/** @type {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));
}.bind(self));
}
};
/**
* Fetch the competencies.
*
* @param {Number} planId The planId.
* @param {String} searchText Limit the competencies to those matching the text.
* @method _fetchCompetencies
* @return {Promise}
*/
Picker.prototype._fetchCompetencies = function(planId, searchText) {
var self = this;
return Ajax.call([
{ methodname: 'tool_lp_list_plan_competencies', args: {
id: planId
}}
])[0].done(function(competencies) {
// Expand the list of competencies into a fake tree.
var i, tree = [], comp;
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 false;
}
});
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: 'tool_lp_read_plan', args: {
id: this._planId
}}
])[0].then(function(plan) {
return [plan];
});
} else {
promise = Ajax.call([
{ methodname: 'tool_lp_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();
}.bind(self));
};
/**
* 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);
}.bind(self));
};
return /** @alias module:tool_lp/competencypicker_user_plans */ Picker;
});
+100 -2
View File
@@ -26,8 +26,9 @@ define(['jquery',
'core/ajax',
'core/notification',
'core/str',
'tool_lp/menubar'],
function($, templates, ajax, notification, str, Menubar) {
'tool_lp/menubar',
'tool_lp/competencypicker_user_plans'],
function($, templates, ajax, notification, str, Menubar, PickerUserPlans) {
/**
* UserEvidenceActions class.
@@ -190,6 +191,100 @@ define(['jquery',
this.deleteEvidence(data);
};
/**
* Link a competency and reload.
*
* @param {Object} evidenceData Evidence data from evidence node.
* @param {Number} competencyIds The competency IDs.
*/
UserEvidenceActions.prototype._doCreateUserEvidenceCompetency = function(evidenceData, competencyIds) {
var self = this,
calls = [];
$.each(competencyIds, function(index, competencyId) {
calls.push({
methodname: 'tool_lp_create_user_evidence_competency',
args: {
userevidenceid: evidenceData.id,
competencyid: competencyId,
}
});
});
self._callAndRefresh(calls, evidenceData);
};
/**
* Create a user evidence competency.
*
* @param {Object} evidenceData Evidence data from evidence node.
*/
UserEvidenceActions.prototype.createUserEvidenceCompetency = function(evidenceData) {
var self = this,
picker = new PickerUserPlans(evidenceData.userid);
picker.on('save', function(e, data) {
var competencyIds = data.competencyIds;
self._doCreateUserEvidenceCompetency(evidenceData, competencyIds);
}.bind(self));
picker.display();
};
/**
* Create user evidence competency handler.
*
* @param {Event} e The event.
*/
UserEvidenceActions.prototype._createUserEvidenceCompetencyHandler = function(e) {
e.preventDefault();
var data = this._findEvidenceData($(e.target));
this.createUserEvidenceCompetency(data);
};
/**
* Remove a linked competency and reload.
*
* @param {Object} evidenceData Evidence data from evidence node.
* @param {Number} competencyId The competency ID.
*/
UserEvidenceActions.prototype._doDeleteUserEvidenceCompetency = function(evidenceData, competencyId) {
var self = this,
calls = [];
calls.push({
methodname: 'tool_lp_delete_user_evidence_competency',
args: {
userevidenceid: evidenceData.id,
competencyid: competencyId,
}
});
self._callAndRefresh(calls, evidenceData);
};
/**
* Delete a user evidence competency.
*
* @param {Object} evidenceData Evidence data from evidence node.
* @param {Number} competencyId The competency ID.
*/
UserEvidenceActions.prototype.deleteUserEvidenceCompetency = function(evidenceData, competencyId) {
this._doDeleteUserEvidenceCompetency(evidenceData, competencyId);
};
/**
* Delete user evidence competency handler.
*
* @param {Event} e The event.
*/
UserEvidenceActions.prototype._deleteUserEvidenceCompetencyHandler = function(e) {
var data = this._findEvidenceData($(e.currentTarget)),
competencyId = $(e.currentTarget).data('id');
e.preventDefault();
this.deleteUserEvidenceCompetency(data, competencyId);
};
/**
* Find the evidence data from the evidence node.
*
@@ -221,6 +316,7 @@ define(['jquery',
var self = this;
Menubar.enhance(selector, {
'[data-action="user-evidence-delete"]': self._deleteEvidenceHandler.bind(self),
'[data-action="link-competency"]': self._createUserEvidenceCompetencyHandler.bind(self),
});
};
@@ -235,6 +331,8 @@ define(['jquery',
self = this;
wrapper.find('[data-action="user-evidence-delete"]').click(self._deleteEvidenceHandler.bind(self));
wrapper.find('[data-action="link-competency"]').click(self._createUserEvidenceCompetencyHandler.bind(self));
wrapper.find('[data-action="delete-competency-link"]').click(self._deleteUserEvidenceCompetencyHandler.bind(self));
};
return /** @alias module:tool_lp/user_evidence_actions */ UserEvidenceActions;
+110 -3
View File
@@ -1418,7 +1418,7 @@ class api {
$params['statusdraft'] = plan::STATUS_DRAFT;
}
return plan::get_records_select($select, $params, 'name DESC');
return plan::get_records_select($select, $params, 'name ASC');
}
/**
@@ -2151,10 +2151,21 @@ class api {
throw new required_capability_exception($context, 'tool/lp:userevidencemanage', 'nopermissions', '');
}
// Delete the user evidence.
$userevidence->delete();
// Delete associated files.
$fs = get_file_storage();
$fs->delete_area_files($context->id, 'tool_lp', 'userevidence', $id);
// Delete relation between evidence and competencies.
$userevidence->set_id($id); // Restore the ID to fully mock the object.
$competencies = user_evidence_competency::get_competencies_by_userevidenceid($id);
foreach ($competencies as $competency) {
static::delete_user_evidence_competency($userevidence, $competency->get_id());
}
$userevidence->set_id(0); // Restore the object.
return true;
}
@@ -2174,6 +2185,101 @@ class api {
return $evidence;
}
/**
* Link a user evidence with a competency.
*
* @param user_evidence|int $userevidenceorid User evidence or its ID.
* @param int $competencyid Competency ID.
* @return user_evidence_competency
*/
public static function create_user_evidence_competency($userevidenceorid, $competencyid) {
global $USER;
$userevidence = $userevidenceorid;
if (!is_object($userevidence)) {
$userevidence = self::read_user_evidence($userevidence);
}
// Perform user evidence capability checks.
if (!$userevidence->can_manage()) {
$context = $userevidence->get_context();
throw new required_capability_exception($context, 'tool/lp:userevidencemanage', 'nopermissions', '');
}
// Perform competency capability checks.
$competency = self::read_competency($competencyid);
// Get (and create) the relation.
$relation = user_evidence_competency::get_relation($userevidence->get_id(), $competency->get_id());
if (!$relation->get_id()) {
$relation->create();
$link = new moodle_url('/admin/tool/lp/user_evidence.php', array('id' => $userevidence->get_id()));
self::add_evidence(
$userevidence->get_userid(),
$competency,
$userevidence->get_context(),
evidence::ACTION_LOG,
'evidence_evidenceofpriorlearninglinked',
'tool_lp',
$userevidence->get_name(),
false,
$link->out(false),
null,
$USER->id
);
}
return $relation;
}
/**
* Delete a relationship between a user evidence and a competency.
*
* @param user_evidence|int $userevidenceorid User evidence or its ID.
* @param int $competencyid Competency ID.
* @return bool
*/
public static function delete_user_evidence_competency($userevidenceorid, $competencyid) {
global $USER;
$userevidence = $userevidenceorid;
if (!is_object($userevidence)) {
$userevidence = self::read_user_evidence($userevidence);
}
// Perform user evidence capability checks.
if (!$userevidence->can_manage()) {
$context = $userevidence->get_context();
throw new required_capability_exception($context, 'tool/lp:userevidencemanage', 'nopermissions', '');
}
// Get (and delete) the relation.
$relation = user_evidence_competency::get_relation($userevidence->get_id(), $competencyid);
if (!$relation->get_id()) {
return true;
}
$success = $relation->delete();
if ($success) {
self::add_evidence(
$userevidence->get_userid(),
$competencyid,
$userevidence->get_context(),
evidence::ACTION_LOG,
'evidence_evidenceofpriorlearningunlinked',
'tool_lp',
$userevidence->get_name(),
false,
null,
null,
$USER->id
);
}
return $success;
}
/**
* Recursively duplicate competencies from a tree, we start duplicating from parents to children to have a correct path.
* This method does not copy the related competencies.
@@ -2274,7 +2380,7 @@ class api {
*
* @param int $userid The user id for which evidence is added.
* @param int $competencyid The competency, or its id for which evidence is added.
* @param int $contextid The context in which the evidence took place.
* @param context|int $contextorid The context in which the evidence took place.
* @param int $action The type of action to take on the competency. \tool_lp\evidence::ACTION_*.
* @param string $descidentifier The strings identifier.
* @param string $desccomponent The strings component.
@@ -2289,7 +2395,7 @@ class api {
*/
public static function add_evidence($userid,
$competencyorid,
$contextid,
$contextorid,
$action,
$descidentifier,
$desccomponent,
@@ -2307,6 +2413,7 @@ class api {
$competency = $competencyid;
$competencyid = $competency->get_id();
}
$contextid = is_object($contextorid) ? $contextorid->id : $contextorid;
$setucgrade = false;
$ucgrade = null;
$ucproficiency = null;
+176 -4
View File
@@ -48,6 +48,7 @@ use tool_lp\external\user_summary_exporter;
use tool_lp\external\user_competency_exporter;
use tool_lp\external\user_competency_plan_exporter;
use tool_lp\external\user_evidence_exporter;
use tool_lp\external\user_evidence_competency_exporter;
use tool_lp\external\competency_exporter;
use tool_lp\external\course_competency_exporter;
use tool_lp\external\course_summary_exporter;
@@ -3195,11 +3196,59 @@ class external extends external_api {
);
}
/**
/**
* Returns description of external function parameters.
*
* @return \external_function_parameters
*/
public static function list_user_plans_parameters() {
return new external_function_parameters(array(
'userid' => new external_value(PARAM_INT, 'The user ID'),
));
}
/**
* External function list_user_plans.
*
* @param int $userid The user ID.
* @return boolean
*/
public static function list_user_plans($userid) {
global $PAGE;
$params = self::validate_parameters(self::list_user_plans_parameters(), array(
'userid' => $userid
));
$context = context_user::instance($params['userid']);
self::validate_context($context);
$output = $PAGE->get_renderer('tool_lp');
$response = array();
$plans = api::list_user_plans($params['userid']);
foreach ($plans as $plan) {
$exporter = new plan_exporter($plan, array('template' => $plan->get_template()));
$response[] = $exporter->export($output);
}
return $response;
}
/**
* Returns description of external function result value.
*
* @return \external_function_parameters
*/
public static function list_user_plans_returns() {
return new external_multiple_structure(
plan_exporter::get_read_structure()
);
}
/**
* Returns description of external function parameters.
*
* @return \external_description
*/
public static function read_user_evidence_parameters() {
return new external_function_parameters(array(
'id' => new external_value(PARAM_INT, 'The user evidence ID.'),
@@ -3221,8 +3270,8 @@ class external extends external_api {
self::validate_context($context);
$output = $PAGE->get_renderer('tool_lp');
// TODO MDL-51869.
$exporter = new user_evidence_exporter($userevidence, array('context' => $context, 'competencies' => array()));
$exporter = new user_evidence_exporter($userevidence, array('context' => $context,
'competencies' => $userevidence->get_competencies()));
return $exporter->export($output);
}
@@ -3270,7 +3319,6 @@ class external extends external_api {
return new external_value(PARAM_BOOL, 'True if the delete was successful');
}
/**
* Returns description of external function parameters.
*
@@ -3320,6 +3368,130 @@ class external extends external_api {
));
}
/**
* Returns description of external function parameters.
*
* @return \external_function_parameters
*/
public static function data_for_user_evidence_page_parameters() {
return new external_function_parameters(array(
'id' => new external_value(PARAM_INT, 'The user evidence ID')
));
}
/**
* Loads the data required to render the user_evidence_page template.
*
* @param int $userid User id.
* @return boolean
*/
public static function data_for_user_evidence_page($id) {
global $PAGE;
$params = self::validate_parameters(self::data_for_user_evidence_page_parameters(),
array('id' => $id));
$userevidence = api::read_user_evidence($id);
self::validate_context($userevidence->get_context());
$output = $PAGE->get_renderer('tool_lp');
$renderable = new \tool_lp\output\user_evidence_page($userevidence);
return $renderable->export_for_template($output);
}
/**
* Returns description of external function result value.
*
* @return \external_description
*/
public static function data_for_user_evidence_page_returns() {
return new external_single_structure(array(
'userevidence' => user_evidence_exporter::get_read_structure(),
'pluginbaseurl' => new external_value(PARAM_LOCALURL, 'Url to the tool_lp plugin folder on this Moodle site'),
));
}
/**
* Returns description of external function parameters.
*
* @return \external_function_parameters
*/
public static function create_user_evidence_competency_parameters() {
return new external_function_parameters(array(
'userevidenceid' => new external_value(PARAM_INT, 'The user evidence ID.'),
'competencyid' => new external_value(PARAM_INT, 'The competency ID.'),
));
}
/**
* Delete a user evidence competency relationship.
*
* @param int $userevidenceid The user evidence id.
* @param int $competencyid The competency id.
* @return boolean
*/
public static function create_user_evidence_competency($userevidenceid, $competencyid) {
global $PAGE;
$params = self::validate_parameters(self::create_user_evidence_competency_parameters(), array(
'userevidenceid' => $userevidenceid,
'competencyid' => $competencyid,
));
$userevidence = api::read_user_evidence($params['userevidenceid']);
self::validate_context($userevidence->get_context());
$relation = api::create_user_evidence_competency($userevidence, $competencyid);
$exporter = new user_evidence_competency_exporter($relation);
return $exporter->export($PAGE->get_renderer('tool_lp'));
}
/**
* Returns description of external function result value.
*
* @return \external_description
*/
public static function create_user_evidence_competency_returns() {
return user_evidence_competency_exporter::get_read_structure();
}
/**
* Returns description of external function parameters.
*
* @return \external_function_parameters
*/
public static function delete_user_evidence_competency_parameters() {
return new external_function_parameters(array(
'userevidenceid' => new external_value(PARAM_INT, 'The user evidence ID.'),
'competencyid' => new external_value(PARAM_INT, 'The competency ID.'),
));
}
/**
* Delete a user evidence competency relationship.
*
* @param int $userevidenceid The user evidence id.
* @param int $competencyid The competency id.
* @return boolean
*/
public static function delete_user_evidence_competency($userevidenceid, $competencyid) {
$params = self::validate_parameters(self::delete_user_evidence_competency_parameters(), array(
'userevidenceid' => $userevidenceid,
'competencyid' => $competencyid,
));
$userevidence = api::read_user_evidence($params['userevidenceid']);
self::validate_context($userevidence->get_context());
return api::delete_user_evidence_competency($userevidence, $params['competencyid']);
}
/**
* Returns description of external function result value.
*
* @return \external_description
*/
public static function delete_user_evidence_competency_returns() {
return new external_value(PARAM_BOOL, 'True if the delete was successful');
}
/**
* Returns the description of the get_scale_values() parameters.
+1 -1
View File
@@ -162,7 +162,7 @@ class stored_file_exporter extends exporter {
'filenameshort' => $filenameshort,
'filesizeformatted' => display_size((int) $this->file->get_filesize()),
'icon' => $icon,
'iconurl' => $iconurl,
'iconurl' => $iconurl->out(false),
'url' => $url->out(false),
'timecreatedformatted' => userdate($this->file->get_timecreated()),
'timemodifiedformatted' => userdate($this->file->get_timemodified()),
@@ -0,0 +1,41 @@
<?php
// 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/>.
/**
* User evidence competency exporter.
*
* @package tool_lp
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp\external;
defined('MOODLE_INTERNAL') || die();
/**
* User evidence competency exporter class.
*
* @package tool_lp
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_evidence_competency_exporter extends persistent_exporter {
protected static function define_class() {
return 'tool_lp\\user_evidence_competency';
}
}
+11 -2
View File
@@ -44,6 +44,9 @@ class user_evidence_exporter extends persistent_exporter {
'canmanage' => array(
'type' => PARAM_BOOL
),
'competencycount' => array(
'type' => PARAM_INT
),
'competencies' => array(
'type' => competency_exporter::read_properties_definition(),
'multiple' => true
@@ -72,11 +75,16 @@ class user_evidence_exporter extends persistent_exporter {
}
protected function get_other_values(renderer_base $output) {
$contextcache = array();
$competencies = array();
foreach ($this->related['competencies'] as $competency) {
// TODO MDL-51869.
$compexporter = new competency_exporter($competency);
if (!isset($contextcache[$competency->get_competencyframeworkid()])) {
$contextcache[$competency->get_competencyframeworkid()] = $competency->get_context();
}
$context = $contextcache[$competency->get_competencyframeworkid()];
$compexporter = new competency_exporter($competency, array('context' => $context));
$competencies[] = $compexporter->export($output);
}
@@ -99,6 +107,7 @@ class user_evidence_exporter extends persistent_exporter {
$values = array(
'canmanage' => $this->persistent->can_manage(),
'competencycount' => count($competencies),
'competencies' => $competencies,
'filecount' => count($files),
'files' => $files,
@@ -95,8 +95,7 @@ class user_evidence_list_page implements renderable, templatable {
foreach ($this->evidence as $evidence) {
$evidenceexporter = new user_evidence_exporter($evidence, array(
'context' => $this->context,
// TODO MDL-51869.
'competencies' => array()
'competencies' => $evidence->get_competencies()
));
$record = $evidenceexporter->export($output);
$data->evidence[] = $record;
@@ -66,8 +66,7 @@ class user_evidence_page implements renderable, templatable {
$data = new stdClass();
$evidenceexporter = new user_evidence_exporter($this->userevidence, array(
'context' => $this->context,
// TODO MDL-51869.
'competencies' => array()
'competencies' => $this->userevidence->get_competencies()
));
$data->userevidence = $evidenceexporter->export($output);
$data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true);
+7
View File
@@ -96,6 +96,13 @@ class user_evidence extends persistent {
return context_user::instance($this->get_userid());
}
/**
* Get link competencies.
*/
public function get_competencies() {
return user_evidence_competency::get_competencies_by_userevidenceid($this->get_id());
}
/**
* Return the files associated with this evidence.
*
@@ -0,0 +1,134 @@
<?php
// 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/>.
/**
* User evidence competency persistent.
*
* This represent the many to many relationship between evidence of prior
* learning and competencies.
*
* @package tool_lp
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp;
defined('MOODLE_INTERNAL') || die();
use stdClass;
/**
* User evidence competency persistent class.
*
* @package tool_lp
* @copyright 2015 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_evidence_competency extends persistent {
const TABLE = 'tool_lp_user_evidence_comp';
/**
* Return the definition of the properties of this model.
*
* @return array
*/
protected static function define_properties() {
return array(
'userevidenceid' => array(
'type' => PARAM_INT
),
'competencyid' => array(
'type' => PARAM_INT,
),
);
}
/**
* Validate competency ID.
*
* @param int $value ID.
* @return true|lang_string
*/
protected function validate_competencyid($value) {
if (!competency::record_exists($value)) {
return new lang_string('invaliddata', 'error');
}
return true;
}
/**
* Validate user evidence ID.
*
* @param int $value ID.
* @return true|lang_string
*/
protected function validate_userevidenceid($value) {
if (!user_evidence::record_exists($value)) {
return new lang_string('invaliddata', 'error');
}
return true;
}
/**
* Get competencies by user evidence ID.
*
* @param int $userevidenceid The user evidence ID.
* @return competency[]
*/
public static function get_competencies_by_userevidenceid($userevidenceid) {
global $DB;
$sql = "SELECT c.*
FROM {" . self::TABLE . "} uec
JOIN {" . competency::TABLE . "} c
ON uec.userevidenceid = ?
AND uec.competencyid = c.id
ORDER BY c.shortname";
$competencies = array();
$records = $DB->get_recordset_sql($sql, array($userevidenceid));
foreach ($records as $record) {
$competencies[] = new competency(0, $record);
}
$records->close();
return $competencies;
}
/**
* Get a relation.
*
* This does not perform any validation on the data passed. If the relation exists in the database
* then it is loaded in a the model, if not then it is up to the developer to save the model.
*
* @param int $userevidenceid
* @param int $competencyid
* @return template_cohort
*/
public static function get_relation($userevidenceid, $competencyid) {
global $DB;
$params = array(
'userevidenceid' => $userevidenceid,
'competencyid' => $competencyid
);
$relation = new static(null, (object) $params);
if ($record = $DB->get_record(static::TABLE, $params)) {
$relation->from_record($record);
}
return $relation;
}
}
+18 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="admin/tool/lp/db" VERSION="20151208" COMMENT="XMLDB file for Moodle admin/tool/lp"
<XMLDB PATH="admin/tool/lp/db" VERSION="20151214" COMMENT="XMLDB file for Moodle admin/tool/lp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
@@ -261,5 +261,22 @@
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
</INDEXES>
</TABLE>
<TABLE NAME="tool_lp_user_evidence_comp" COMMENT="Relationship between user evidence and competencies">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="userevidenceid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="competencyid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="userevidenceid" UNIQUE="false" FIELDS="userevidenceid"/>
<INDEX NAME="userevidencecompids" UNIQUE="true" FIELDS="userevidenceid, competencyid"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
+36
View File
@@ -489,6 +489,15 @@ $functions = array(
'capabilities' => 'tool/lp:planmanage',
'ajax' => true,
),
'tool_lp_list_user_plans' => array(
'classname' => 'tool_lp\external',
'methodname' => 'list_user_plans',
'classpath' => '',
'description' => 'List a user\'s learning plans.',
'type' => 'read',
'capabilities' => 'tool/lp:planviewown',
'ajax' => true,
),
'tool_lp_data_for_plans_page' => array(
'classname' => 'tool_lp\external',
'methodname' => 'data_for_plans_page',
@@ -626,5 +635,32 @@ $functions = array(
'capabilities' => 'tool/lp:userevidenceread',
'ajax' => true,
),
'tool_lp_data_for_user_evidence_page' => array(
'classname' => 'tool_lp\external',
'methodname' => 'data_for_user_evidence_page',
'classpath' => '',
'description' => 'Load the data for the user evidence page template',
'type' => 'read',
'capabilities' => 'tool/lp:userevidenceread',
'ajax' => true,
),
'tool_lp_create_user_evidence_competency' => array(
'classname' => 'tool_lp\external',
'methodname' => 'create_user_evidence_competency',
'classpath' => '',
'description' => 'Create an evidence of prior learning relationship with a competency.',
'type' => 'read',
'capabilities' => 'tool/lp:userevidencemanageown, tool/lp:competencyread',
'ajax' => true,
),
'tool_lp_delete_user_evidence_competency' => array(
'classname' => 'tool_lp\external',
'methodname' => 'delete_user_evidence_competency',
'classpath' => '',
'description' => 'Delete an evidence of prior learning relationship with a competency.',
'type' => 'write',
'capabilities' => 'tool/lp:userevidencemanageown',
'ajax' => true,
),
);
+28
View File
@@ -607,6 +607,34 @@ function xmldb_tool_lp_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2015111027, 'tool', 'lp');
}
if ($oldversion < 2015111029) {
// Define table tool_lp_user_evidence_comp to be created.
$table = new xmldb_table('tool_lp_user_evidence_comp');
// Adding fields to table tool_lp_user_evidence_comp.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('userevidenceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('competencyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table tool_lp_user_evidence_comp.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
// Adding indexes to table tool_lp_user_evidence_comp.
$table->add_index('userevidenceid', XMLDB_INDEX_NOTUNIQUE, array('userevidenceid'));
$table->add_index('userevidencecompids', XMLDB_INDEX_UNIQUE, array('userevidenceid', 'competencyid'));
// Conditionally launch create table for tool_lp_user_evidence_comp.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Lp savepoint reached.
upgrade_plugin_savepoint(true, 2015111029, 'tool', 'lp');
}
return true;
}
+3
View File
@@ -85,6 +85,8 @@ $string['editthisplan'] = 'Edit this learning plan';
$string['editthisuserevidence'] = 'Edit this evidence';
$string['edituserevidence'] = 'Edit evidence';
$string['evidence_coursecompleted'] = 'The course \'{$a}\' was completed.';
$string['evidence_evidenceofpriorlearninglinked'] = 'The evidence of prior learning \'{$a}\' was linked.';
$string['evidence_evidenceofpriorlearningunlinked'] = 'The evidence of prior learning \'{$a}\' was unlinked.';
$string['errorcannotsetduedateinthepast'] = 'The due date cannot be set in the past.';
$string['errorcannotchangeapastduedate'] = 'The due date has passed, it cannot be changed.';
$string['errornocompetency'] = '{$a} competency can not be found';
@@ -106,6 +108,7 @@ $string['learningplancompetencies'] = 'Learning plan competencies';
$string['learningplans'] = 'Learning plans';
$string['levela'] = 'Level {$a}';
$string['linkcompetency'] = 'Link competency';
$string['linkcompetencies'] = 'Link competencies';
$string['linkcoursecompetencies'] = 'Link course competencies';
$string['linkedcompetencies'] = 'Linked competencies';
$string['linkedcourses'] = 'Linked courses:';
+7
View File
@@ -111,6 +111,10 @@
/** Styles required for menubar js */
.tool-lp-menu {
margin: 0;
}
.tool-lp-menu li {
float: left;
display: inline;
@@ -170,10 +174,13 @@ input[type="checkbox"].tool_lp_scale_proficient {
margin: 10px 20px;
list-style: none;
}
.user-evidence-competencies,
.user-evidence-documents li {
margin-bottom: 5px;
word-break: break-all;
}
[data-region="user-evidence-list"] .user-evidence-competencies,
[data-region="user-evidence-list"] .user-evidence-documents {
margin: 0;
list-style: none;
}
@@ -0,0 +1,34 @@
<div data-region="competencylinktree">
{{^singlePlan}}
<h3>{{#str}}learningplans, tool_lp{{/str}}</h3>
<select data-action="chooseplan">
{{#plans}}
<option value="{{id}}" {{#selected}}selected="selected"{{/selected}}>{{name}}</em></option>
{{/plans}}
</select>
{{/singlePlan}}
<h3>{{#str}}locatecompetency, tool_lp{{/str}}</h3>
<form data-region="filtercompetencies" data-planid="{{plan.id}}">
<label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
<input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
<button>{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
</form>
<ul data-enhance="linktree" style="display: none;">
<li><span>{{plan.name}}</span>
<ul>
{{#competencies}}
{{> tool_lp/competencies_tree }}
{{/competencies}}
</ul>
</li>
</ul>
<div data-region="link-buttons">
<input type="button" data-action="add" value="{{#str}}add{{/str}}"/>
<input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
</div>
</div>
@@ -66,12 +66,18 @@
{{/hasurlorfiles}}
</td>
<td>
{{^competencies}}
{{^competencycount}}
-
{{/competencies}}
{{#competencies}}
{{! TODO MDL-51869 }}
{{/competencies}}
{{/competencycount}}
{{#competencycount}}
<ul class="user-evidence-competencies">
{{#competencies}}
<li>
{{shortname}} <small><em>{{idnumber}}</em></small>
</li>
{{/competencies}}
</ul>
{{/competencycount}}
</td>
{{#canmanage}}
<td>
@@ -85,6 +91,11 @@
{{#pix}}t/edit{{/pix}} {{#str}}editthisuserevidence, tool_lp{{/str}}
</a>
</li>
<li>
<a href="#" data-action="link-competency">
{{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}}
</a>
</li>
<li>
<a data-action="user-evidence-delete" href="#">
{{#pix}}t/delete{{/pix}} {{#str}}deletethisuserevidence, tool_lp{{/str}}
@@ -18,7 +18,7 @@
User evidence page template.
Data attributes required for JS:
* data-action = add
* data-action = link-competency
* data-action = delete-competency-link
* data-region = user-evidence-page
* data-id = user evidence ID, or competency ID
@@ -29,7 +29,7 @@
* pluginbaseurl - The plugin base URL
}}
{{#userevidence}}
<div data-region="user-evidence-page" data-id="{{evidence.id}}" data-userid="{{evidence.userid}}">
<div data-region="user-evidence-page" data-id="{{id}}" data-userid="{{userid}}">
<h2>
{{name}}
{{#canmanage}}
@@ -48,7 +48,7 @@
<li>{{#pix}}url, tool_lp{{/pix}} <a href="{{url}}" title="{{url}}">{{urlshort}}</a></li>
{{/url}}
{{#files}}
<li>{{#pix}}{{icon}}{{/pix}} <a href="{{url}}">{{filename}}</a></li>
<li><img src="{{iconurl}}" alt=""> <a href="{{url}}">{{filename}}</a></li>
{{/files}}
</ul>
</div>
@@ -70,13 +70,13 @@
<td>
<a href="#" data-action="competency-dialogue" data-id="{{id}}">{{shortname}}</a>
</td>
{{#canmanage}}
{{#userevidence.canmanage}}
<td>
<div class="pull-left">
<a href="#" data-action="delete-competency-link" data-id="{{id}}">{{#pix}}t/delete, core{{#str}}delete{{/str}}{{/pix}}</a>
<a href="#" data-action="delete-competency-link" data-id="{{id}}">{{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}</a>
</div>
</td>
{{/canmanage}}
{{/userevidence.canmanage}}
</tr>
{{/competencies}}
</tbody>
@@ -85,7 +85,7 @@
<div data-region="actions">
<div class="pull-right">
{{#canmanage}}
<button class="btn" data-action="add">{{#pix}}t/add{{/pix}} {{#str}}linkcompetency, tool_lp{{/str}}</button>
<button class="btn" data-action="link-competency">{{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}}</button>
{{/canmanage}}
</div>
</div>
@@ -97,7 +97,7 @@
require(['tool_lp/user_evidence_actions'], function(UserEvidenceActions) {
var uea = new UserEvidenceActions('evidence');
planActions.registerEvents();
uea.registerEvents();
});
{{/js}}
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2015111028; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2015111029; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014110400; // Requires this Moodle version.
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).