MDL-49462 tool_lp: added template competencies page
authorMark Nelson <markn@moodle.com>
Fri, 15 May 2015 01:15:04 +0000 (18:15 -0700)
committerFrederic Massart <fred@moodle.com>
Mon, 18 Apr 2016 02:58:32 +0000 (10:58 +0800)
13 files changed:
admin/tool/lp/amd/src/competencies.js [moved from admin/tool/lp/amd/src/coursecompetencies.js with 66% similarity]
admin/tool/lp/classes/api.php
admin/tool/lp/classes/external.php
admin/tool/lp/classes/output/renderer.php
admin/tool/lp/classes/output/template_competencies_page.php
admin/tool/lp/classes/template_competency.php
admin/tool/lp/db/access.php
admin/tool/lp/db/services.php
admin/tool/lp/lang/en/tool_lp.php
admin/tool/lp/templatecompetencies.php [new file with mode: 0644]
admin/tool/lp/templates/course_competencies_page.mustache
admin/tool/lp/templates/template_competencies_page.mustache [new file with mode: 0644]
admin/tool/lp/version.php

similarity index 66%
rename from admin/tool/lp/amd/src/coursecompetencies.js
rename to admin/tool/lp/amd/src/competencies.js
index 8f6b153..5e9d348 100644 (file)
@@ -14,9 +14,9 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Handle add/remove course competency links.
+ * Handle add/remove competency links.
  *
- * @module     tool_lp/coursecompetencies
+ * @module     tool_lp/competencies
  * @package    tool_lp
  * @copyright  2015 Damyon Wiese <damyon@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -27,10 +27,12 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
     /**
      * Constructor
      *
-     * @param {int} courseid
+     * @param {int} itemid
+     * @param {string} itemtype
      */
-    var coursecompetencies = function(courseid) {
-        this.courseid = courseid;
+    var competencies = function(itemid, itemtype) {
+        this.itemid = itemid;
+        this.itemtype = itemtype;
         this.selectedCompetency = 0;
         var localthis = this;
         var loadframeworks = ajax.call([
@@ -53,15 +55,15 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
         }).fail(notification.exception);
     };
 
-    coursecompetencies.prototype.registerDragDrop = function() {
+    competencies.prototype.registerDragDrop = function() {
         var localthis = this;
         // Init this module.
-        str.get_string('movecoursecompetency', 'tool_lp').done(
+        str.get_string('movecompetency', 'tool_lp').done(
             function(movestring) {
-                dragdrop.dragdrop('movecoursecompetency',
+                dragdrop.dragdrop('movecompetency',
                                   movestring,
-                                  { identifier: 'movecoursecompetency', component: 'tool_lp'},
-                                  { identifier: 'movecoursecompetencyafter', component: 'tool_lp'},
+                                  { identifier: 'movecompetency', component: 'tool_lp'},
+                                  { identifier: 'movecompetencyafter', component: 'tool_lp'},
                                   'drag-samenode',
                                   'drag-parentnode',
                                   'drag-handlecontainer',
@@ -73,20 +75,29 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
 
     };
 
-    coursecompetencies.prototype.handleDrop = function(drag, drop) {
+    competencies.prototype.handleDrop = function(drag, drop) {
         var fromid = $(drag).data('id');
         var toid = $(drop).data('id');
         var localthis = this;
 
-        var requests = ajax.call([
-            { methodname: 'tool_lp_reorder_course_competency',
-                args: { courseid: localthis.courseid, competencyidfrom: fromid, competencyidto: toid } }
+        if (localthis.itemtype == 'course') {
+            var requests = ajax.call([
+                { methodname: 'tool_lp_reorder_course_competency',
+                    args: { courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid } }
+                ]);
+        } else if (localthis.itemtype == 'template') {
+            var requests = ajax.call([
+                { methodname: 'tool_lp_reorder_template_competency',
+                    args: { templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid } }
             ]);
-        requests[0].fail(notification.exception);
+        } else {
+            return null;
+        }
 
+        requests[0].fail(notification.exception);
     };
 
-    coursecompetencies.prototype.applyFilter = function(e) {
+    competencies.prototype.applyFilter = function(e) {
         e.preventDefault();
         var localthis = this;
         var searchInput = $('[data-region="filtercompetencies"] input');
@@ -115,7 +126,7 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
         }).fail(notification.exception);
     };
 
-    coursecompetencies.prototype.initLinkCourseCompetencies = function() {
+    competencies.prototype.initLinkCourseCompetencies = function() {
         var localthis = this;
 
         var competencytree = new ariatree('[data-enhance=linktree]', function(target) {
@@ -143,25 +154,41 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
             }
 
             $(e.target).attr('disabled', 'disabled');
+
             // Add the link and reload the page template.
-            var requests = ajax.call([
-                { methodname: 'tool_lp_add_competency_to_course',
-                  args: { courseid: localthis.courseid, competencyid: localthis.selectedCompetency } },
-                { methodname: 'tool_lp_data_for_course_competencies_page',
-                  args: { courseid: localthis.courseid } }
-            ]);
+            if (localthis.itemtype == 'course') {
+                var requests = ajax.call([
+                    { methodname: 'tool_lp_add_competency_to_course',
+                      args: { courseid: localthis.itemid, competencyid: localthis.selectedCompetency } },
+                    { methodname: 'tool_lp_data_for_course_competencies_page',
+                      args: { courseid: localthis.itemid } }
+                ]);
+                var pagerender = 'tool_lp/course_competencies_page';
+                var pageregion = 'coursecompetenciespage';
+            } else if (localthis.itemtype == 'template') {
+                var requests = ajax.call([
+                    { methodname: 'tool_lp_add_competency_to_template',
+                        args: { templateid: localthis.itemid, competencyid: localthis.selectedCompetency } },
+                    { methodname: 'tool_lp_data_for_template_competencies_page',
+                        args: { templateid: localthis.itemid } }
+                ]);
+                var pagerender = 'tool_lp/template_competencies_page';
+                var pageregion = 'templatecompetenciespage';
+            } else {
+                return null;
+            }
 
             requests[1].done(function(context) {
-                templates.render('tool_lp/course_competencies_page', context).done(function(html, js) {
+                templates.render(pagerender, context).done(function(html, js) {
                     localthis.popup.close();
-                    $('[data-region="coursecompetenciespage"]').replaceWith(html);
+                    $('[data-region="' + pageregion + '"]').replaceWith(html);
                     templates.runTemplateJS(js);
                 }).fail(notification.exception);
             }).fail(notification.exception);
         });
     };
 
-    coursecompetencies.prototype.registerEvents = function() {
+    competencies.prototype.registerEvents = function() {
         var localthis = this;
         $('[data-region="actions"] button').click(function(e) {
             return localthis.openCompetencySelector.call(localthis, e);
@@ -172,23 +199,36 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
             var deleteid = $(e.target).closest('[data-id]').data('id');
 
             // Delete the link and reload the page template.
-            var requests = ajax.call([
-                { methodname: 'tool_lp_remove_competency_from_course',
-                  args: { courseid: localthis.courseid, competencyid: deleteid } },
-                { methodname: 'tool_lp_data_for_course_competencies_page',
-                  args: { courseid: localthis.courseid } }
-            ]);
+            if (localthis.itemtype == 'course') {
+                var requests = ajax.call([
+                    { methodname: 'tool_lp_remove_competency_from_course',
+                      args: { courseid: localthis.itemid, competencyid: deleteid } },
+                    { methodname: 'tool_lp_data_for_course_competencies_page',
+                      args: { courseid: localthis.itemid } }
+                ]);
+                var pagerender = 'tool_lp/course_competencies_page';
+                var pageregion = 'coursecompetenciespage';
+            } else if (localthis.itemtype == 'template') {
+                var requests = ajax.call([
+                    { methodname: 'tool_lp_remove_competency_from_template',
+                        args: { templateid: localthis.itemid, competencyid: deleteid } },
+                    { methodname: 'tool_lp_data_for_template_competencies_page',
+                        args: { templateid: localthis.itemid } }
+                ]);
+                var pagerender = 'tool_lp/template_competencies_page';
+                var pageregion = 'templatecompetenciespage';
+            }
 
             requests[1].done(function(context) {
-                templates.render('tool_lp/course_competencies_page', context).done(function(html, js) {
-                    $('[data-region="coursecompetenciespage"]').replaceWith(html);
+                templates.render(pagerender, context).done(function(html, js) {
+                    $('[data-region="' + pageregion + '"]').replaceWith(html);
                     templates.runTemplateJS(js);
                 }).fail(notification.exception);
             }).fail(notification.exception);
         });
     };
 
-    coursecompetencies.prototype.addCompetencyChildren = function(parent, competencies) {
+    competencies.prototype.addCompetencyChildren = function(parent, competencies) {
         var i;
 
         for (i = 0; i < competencies.length; i++) {
@@ -202,7 +242,7 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
         }
     };
 
-    coursecompetencies.prototype.searchCompetencies = function() {
+    competencies.prototype.searchCompetencies = function() {
         var localthis = this;
         var deferred = $.Deferred();
         var searchInput = $('[data-region="filtercompetencies"] input');
@@ -238,7 +278,7 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
         return deferred.promise();
     };
 
-    coursecompetencies.prototype.openCompetencySelector = function(e) {
+    competencies.prototype.openCompetencySelector = function(e) {
         e.preventDefault();
         var localthis = this;
 
@@ -247,7 +287,7 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
             framework.selected = true;
             var context = { framework: framework, frameworks: localthis.frameworks, competencies: competencies, search: '' };
             templates.render('tool_lp/link_course_competencies', context).done(function(html) {
-                str.get_string('linkcoursecompetencies', 'tool_lp').done(function(title) {;
+                str.get_string('linkcompetencies', 'tool_lp').done(function(title) {;
                     localthis.popup = new dialogue(
                         title,
                         html, // The link UI.
@@ -258,5 +298,5 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates', 'core/dial
         }).fail(notification.exception);
     };
 
-    return /** @alias module:core/tree */ coursecompetencies;
+    return /** @alias module:core/tree */ competencies;
 });
index 27d6912..ed4f2b8 100644 (file)
@@ -962,9 +962,9 @@ class api {
      */
     public static function add_competency_to_template($templateid, $competencyid) {
         // First we do a permissions check.
-        $context = context_course::instance($courseid);
+        $context = context_system::instance();
 
-        require_capability('tool/lp:templatemanage', $context);
+        require_capability('tool/lp:templatecompetencymanage', $context);
 
         $record = new stdClass();
         $record->templateid = $templateid;
@@ -973,7 +973,7 @@ class api {
         $competency = new competency();
         $competency->set_id($competencyid);
         if (!$competency->read()) {
-             throw new coding_exception('The competency does not exist');
+            throw new coding_exception('The competency does not exist');
         }
 
         $templatecompetency = new template_competency();
@@ -998,7 +998,7 @@ class api {
         // First we do a permissions check.
         $context = context_system::instance();
 
-        require_capability('tool/lp:templatemanage', $context);
+        require_capability('tool/lp:templatecompetencymanage', $context);
 
         $record = new stdClass();
         $record->templateid = $templateid;
@@ -1010,12 +1010,6 @@ class api {
              throw new coding_exception('The competency does not exist');
         }
 
-        $template = new template();
-        $template->set_id($template);
-        if (!$template->read()) {
-             throw new coding_exception('The learning plan template does not exist');
-        }
-
         $templatecompetency = new template_competency();
         $exists = $templatecompetency->get_records(array('templateid' => $templateid, 'competencyid' => $competencyid));
         if ($exists) {
@@ -1188,4 +1182,56 @@ class api {
 
         return $plan->delete();
     }
+
+    /**
+     * Move the template competency up or down in the display list.
+     *
+     * Requires tool/lp:templatecompetencymanage capability at the system context.
+     *
+     * @param int $templateid The template id
+     * @param int $competencyidfrom The id of the competency we are moving.
+     * @param int $competencyidto The id of the competency we are moving to.
+     * @return boolean
+     */
+    public static function reorder_template_competency($templateid, $competencyidfrom, $competencyidto) {
+        // First we do a permissions check.
+        $context = context_system::instance();
+
+        require_capability('tool/lp:templatecompetencymanage', $context);
+
+        $down = true;
+        $templatecompetency = new template_competency();
+        $matches = $templatecompetency->get_records(array('templateid' => $templateid, 'competencyid' => $competencyidfrom));
+        if (count($matches) == 0) {
+            throw new coding_exception('The link does not exist');
+        }
+
+        $competencyfrom = array_pop($matches);
+        $matches = $templatecompetency->get_records(array('templateid' => $templateid, 'competencyid' => $competencyidto));
+        if (count($matches) == 0) {
+            throw new coding_exception('The link does not exist');
+        }
+
+        $competencyto = array_pop($matches);
+
+        $all = $templatecompetency->get_records(array('templateid' => $templateid), 'sortorder', 'ASC', 0, 0);
+
+        if ($competencyfrom->get_sortorder() > $competencyto->get_sortorder()) {
+            // We are moving up, so put it before the "to" item.
+            $down = false;
+        }
+
+        foreach ($all as $id => $templatecompetency) {
+            $sort = $templatecompetency->get_sortorder();
+            if ($down && $sort > $competencyfrom->get_sortorder() && $sort <= $competencyto->get_sortorder()) {
+                $templatecompetency->set_sortorder($templatecompetency->get_sortorder() - 1);
+                $templatecompetency->update();
+            } else if (!$down && $sort >= $competencyto->get_sortorder() && $sort < $competencyfrom->get_sortorder()) {
+                $templatecompetency->set_sortorder($templatecompetency->get_sortorder() + 1);
+                $templatecompetency->update();
+            }
+        }
+        $competencyfrom->set_sortorder($competencyto->get_sortorder());
+        return $competencyfrom->update();
+    }
 }
index 997fc7e..f9d2e8b 100644 (file)
@@ -1966,6 +1966,71 @@ class external extends external_api {
         return new external_value(PARAM_BOOL, 'True if successful.');
     }
 
+    /**
+     * Returns description of reorder_template_competency() parameters.
+     *
+     * @return external_function_parameters
+     */
+    public static function reorder_template_competency_parameters() {
+        $templateid = new external_value(
+            PARAM_INT,
+            'The template id',
+            VALUE_REQUIRED
+        );
+        $competencyidfrom = new external_value(
+            PARAM_INT,
+            'The competency id we are moving',
+            VALUE_REQUIRED
+        );
+        $competencyidto = new external_value(
+            PARAM_INT,
+            'The competency id we are moving to',
+            VALUE_REQUIRED
+        );
+        $params = array(
+            'templateid' => $templateid,
+            'competencyidfrom' => $competencyidfrom,
+            'competencyidto' => $competencyidto,
+        );
+        return new external_function_parameters($params);
+    }
+
+    /**
+     * Expose to AJAX
+     * @return boolean
+     */
+    public static function reorder_template_competency_is_allowed_from_ajax() {
+        return true;
+    }
+
+    /**
+     * Change the order of template competencies.
+     *
+     * @param int $templateid The template id
+     * @param int $competencyidfrom The competency to move.
+     * @param int $competencyidto The competency to move to.
+     * @return bool
+     */
+    public static function reorder_template_competency($templateid, $competencyidfrom, $competencyidto) {
+        $params = self::validate_parameters(self::reorder_template_competency_parameters(),
+            array(
+                'templateid' => $templateid,
+                'competencyidfrom' => $competencyidfrom,
+                'competencyidto' => $competencyidto,
+            ));
+
+        return api::reorder_template_competency($params['templateid'], $params['competencyidfrom'], $params['competencyidto']);
+    }
+
+    /**
+     * Returns description of reorder_template_competency() result value.
+     *
+     * @return external_description
+     */
+    public static function reorder_template_competency_returns() {
+        return new external_value(PARAM_BOOL, 'True if successful.');
+    }
+
     /**
      * Returns the external structure of a full template record.
      *
index b7f8849..318acb3 100644 (file)
@@ -74,6 +74,18 @@ class renderer extends plugin_renderer_base {
         return parent::render_from_template('tool_lp/course_competencies_page', $data);
     }
 
+    /**
+     * Defer to template.
+     *
+     * @param template_competencies_page $page
+     *
+     * @return string html for the page
+     */
+    public function render_template_competencies_page($page) {
+        $data = $page->export_for_template($this);
+        return parent::render_from_template('tool_lp/template_competencies_page', $data);
+    }
+
     /**
      * Defer to template.
      *
index 705d036..710eb3e 100644 (file)
@@ -44,16 +44,19 @@ class template_competencies_page implements renderable, templatable {
      * @param int $templateid The learning plan template id for this page.
      */
     public function __construct($templateid) {
-        $this->courseid = $templateid;
+        $context = context_system::instance();
+
+        $this->templateid = $templateid;
         $this->competencies = api::list_competencies_in_template($templateid);
-        $this->canmanagecompetencyframeworks = has_capability('tool/lp:competencymanage', context_system::instance());
-        $this->canmanagetemplates = has_capability('tool/lp:templatesmanage', $context);
+        $this->canmanagecompetencyframeworks = has_capability('tool/lp:competencymanage', $context);
+        $this->canmanagetemplatecompetencies = has_capability('tool/lp:templatecompetencymanage', $context);
         $this->manageurl = new moodle_url('/admin/tool/lp/competencyframeworks.php');
     }
 
     /**
      * Export this data so it can be used as the context for a mustache template.
      *
+     * @param \renderer_base $output
      * @return stdClass
      */
     public function export_for_template(renderer_base $output) {
@@ -65,7 +68,7 @@ class template_competencies_page implements renderable, templatable {
             array_push($data->competencies, $record);
         }
         $data->canmanagecompetencyframeworks = $this->canmanagecompetencyframeworks;
-        $data->canmanagecoursecompetencies = $this->canmanagecoursecompetencies;
+        $data->canmanagetemplatecompetencies = $this->canmanagetemplatecompetencies;
         $data->manageurl = $this->manageurl->out(true);
 
         return $data;
index 79bc4ae..b28d331 100644 (file)
@@ -40,6 +40,9 @@ class template_competency extends persistent {
     /** @var int $competencyid The competency id */
     private $competencyid = 0;
 
+    /** @var int $sortorder A number used to influence sorting */
+    private $sortorder = 0;
+
     /**
      * Method that provides the table name matching this class.
      *
@@ -67,6 +70,24 @@ class template_competency extends persistent {
         $this->competencyid = $competencyid;
     }
 
+    /**
+     * Get the sort order index.
+     *
+     * @return string The sort order index
+     */
+    public function get_sortorder() {
+        return $this->sortorder;
+    }
+
+    /**
+     * Set the sort order index.
+     *
+     * @param string $sortorder The sort order index
+     */
+    public function set_sortorder($sortorder) {
+        $this->sortorder = $sortorder;
+    }
+
     /**
      * Get the template id
      *
@@ -101,6 +122,9 @@ class template_competency extends persistent {
         if (isset($record->competencyid)) {
             $this->set_competencyid($record->competencyid);
         }
+        if (isset($record->sortorder)) {
+            $this->set_sortorder($record->sortorder);
+        }
         if (isset($record->timecreated)) {
             $this->set_timecreated($record->timecreated);
         }
@@ -123,6 +147,7 @@ class template_competency extends persistent {
         $record->id = $this->get_id();
         $record->templateid = $this->get_templateid();
         $record->competencyid = $this->get_competencyid();
+        $record->sortorder = $this->get_sortorder();
         $record->timecreated = $this->get_timecreated();
         $record->timemodified = $this->get_timemodified();
         $record->usermodified = $this->get_usermodified();
@@ -234,7 +259,7 @@ class template_competency extends persistent {
                 FROM {' . $competency->get_table_name() . '} comp
                 JOIN {' . self::get_table_name() . '} tplcomp
                 ON tplcomp.competencyid = comp.id
-                WHERE tplcomp.templateid = ? ';
+                WHERE tplcomp.templateid = ? ORDER BY tplcomp.sortorder ASC';
         $params = array($templateid);
 
         if ($onlyvisible) {
@@ -251,4 +276,14 @@ class template_competency extends persistent {
 
         return $instances;
     }
+
+    /**
+     * Add a default for the sortorder field to the default create logic.
+     *
+     * @return persistent
+     */
+    public function create() {
+        $this->sortorder = $this->count_records(array('templateid' => $this->get_templateid()));
+        return parent::create();
+    }
 }
index 0cc33e9..69a5fb5 100644 (file)
@@ -58,6 +58,21 @@ $capabilities = array(
         ),
         'clonepermissionsfrom' =>  'moodle/site:config'
     ),
+    'tool/lp:templatecompetencyread' => array(
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_COURSE,
+        'archetypes' => array(
+            'user' => CAP_ALLOW
+        ),
+        'clonepermissionsfrom' =>  'moodle/block:view'
+    ),
+    'tool/lp:templatecompetencymanage' => array(
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'archetypes' => array(
+        ),
+        'clonepermissionsfrom' =>  'moodle/site:config'
+    ),
     'tool/lp:plancreatedraft' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_SYSTEM,
@@ -93,7 +108,6 @@ $capabilities = array(
             'user' => CAP_ALLOW
         ),
         'clonepermissionsfrom' =>  'moodle/block:view'
-
     ),
     'tool/lp:coursecompetencyread' => array(
         'captype' => 'read',
index eca1297..7395d63 100644 (file)
@@ -220,6 +220,14 @@ $functions = array(
         'type'        => 'write',
         'capabilities'=> 'tool/lp:coursecompetencymanage',
     ),
+    'tool_lp_add_competency_to_template' => array(
+        'classname'   => 'tool_lp\external',
+        'methodname'  => 'add_competency_to_template',
+        'classpath'   => '',
+        'description' => 'Add the competency to a template',
+        'type'        => 'write',
+        'capabilities'=> 'tool/lp:templatecompetencymanage',
+    ),
     'tool_lp_remove_competency_from_course' => array(
         'classname'   => 'tool_lp\external',
         'methodname'  => 'remove_competency_from_course',
@@ -228,6 +236,14 @@ $functions = array(
         'type'        => 'write',
         'capabilities'=> 'tool/lp:coursecompetencymanage',
     ),
+    'tool_lp_remove_competency_from_template' => array(
+        'classname'   => 'tool_lp\external',
+        'methodname'  => 'remove_competency_from_template',
+        'classpath'   => '',
+        'description' => 'Remove a competency from a template',
+        'type'        => 'write',
+        'capabilities'=> 'tool/lp:templatecompetencymanage',
+    ),
     'tool_lp_data_for_course_competencies_page' => array(
         'classname'   => 'tool_lp\external',
         'methodname'  => 'data_for_course_competencies_page',
@@ -236,6 +252,14 @@ $functions = array(
         'type'        => 'read',
         'capabilities'=> 'tool/lp:coursecompetencyread',
     ),
+    'tool_lp_data_for_template_competencies_page' => array(
+        'classname'   => 'tool_lp\external',
+        'methodname'  => 'data_for_template_competencies_page',
+        'classpath'   => '',
+        'description' => 'Load the data for the template competencies page template.',
+        'type'        => 'read',
+        'capabilities'=> 'tool/lp:templatecompetencyread',
+    ),
     'tool_lp_reorder_course_competency' => array(
         'classname'   => 'tool_lp\external',
         'methodname'  => 'reorder_course_competency',
@@ -244,6 +268,14 @@ $functions = array(
         'type'        => 'write',
         'capabilities'=> 'tool/lp:coursecompetencymanage',
     ),
+    'tool_lp_reorder_template_competency' => array(
+        'classname'   => 'tool_lp\external',
+        'methodname'  => 'reorder_template_competency',
+        'classpath'   => '',
+        'description' => 'Move a template competency to a new relative sort order.',
+        'type'        => 'write',
+        'capabilities'=> 'tool/lp:templatecompetencymanage',
+    ),
     'tool_lp_create_template' => array(
         'classname'   => 'tool_lp\external',
         'methodname'  => 'create_template',
index fe163db..befbf78 100644 (file)
@@ -25,7 +25,6 @@
 $string['pluginname'] = 'Learning Plans';
 $string['lp:plancreatedraft'] = 'Create draft learning plans';
 $string['lp:planmanage'] = 'Manage learning plans';
-$string['lp:planmanage'] = 'Manage learning plans';
 $string['lp:planmanageown'] = 'Manage own learning plans';
 $string['lp:planviewall'] = 'View all learning plans';
 $string['lp:planviewown'] = 'View own learning plans';
@@ -33,6 +32,10 @@ $string['lp:competencymanage'] = 'Manage competency frameworks';
 $string['lp:competencyread'] = 'View competency frameworks';
 $string['lp:coursecompetencymanage'] = 'Manage course competencies';
 $string['lp:coursecompetencyread'] = 'View course competencies';
+$string['lp:templatecompetencymanage'] = 'Manage template competencies';
+$string['lp:templatecompetencyread'] = 'View template competencies';
+$string['lp:templatemanage'] = 'Manage templates';
+$string['lp:templateread'] = 'View template';
 $string['competencies'] = 'Competencies';
 $string['competenciesforframework'] = 'Competencies for {$a}';
 $string['competencyframeworks'] = 'Competency Frameworks';
@@ -56,6 +59,7 @@ $string['nocompetencyframeworks'] = 'No competency frameworks have been created
 $string['nocompetencies'] = 'No competencies have been created in this framework.';
 $string['nocompetenciesincourse'] = 'No competencies have been linked to this course.';
 $string['nouserplans'] = 'No learning plans have been created yet.';
+$string['nocompetenciesintemplate'] = 'No competencies have been linked to this template.';
 $string['shortname'] = 'Name';
 $string['savechanges'] = 'Save changes';
 $string['description'] = 'Description';
@@ -101,7 +105,9 @@ $string['move'] = 'Move';
 $string['movecompetency'] = 'Move competency: {$a}';
 $string['selectcompetencymovetarget'] = 'Select a location to move this competency to:';
 $string['coursecompetencies'] = 'Course competencies';
+$string['linkcompetencies'] = 'Link competencies';
 $string['linkcoursecompetencies'] = 'Link course competencies';
+$string['linktemplatecompetencies'] = 'Link template competencies';
 $string['managecompetenciesandframeworks'] = 'Manage competencies and frameworks';
 $string['locatecompetency'] = 'Locate competency';
 $string['itemstoadd'] = 'Items to add';
@@ -109,10 +115,11 @@ $string['linkedcourses'] = 'Linked courses';
 $string['nolinkedcourses'] = 'No courses are using this competency';
 $string['coursesusingthiscompetency'] = 'Courses using this competency';
 $string['learningplans'] = 'Learning plans';
-$string['movecoursecompetency'] = 'Move course competency';
-$string['movecoursecompetencyafter'] = 'Move course competency after {$a}';
 $string['plantemplate'] = 'Select template';
 $string['plantemplate_help'] = 'A learning plan created from a template will contain a list of competencies that match the template. Updates to the template will be reflected in any plan created from that template.';
+$string['movecompetency'] = 'Move competency';
+$string['movecompetencyafter'] = 'Move competency after {$a}';
+$string['templatecompetencies'] = 'Template competencies';
 $string['templates'] = 'Learning plan templates';
 $string['templatename'] = 'Name';
 $string['editthistemplate'] = 'Edit';
diff --git a/admin/tool/lp/templatecompetencies.php b/admin/tool/lp/templatecompetencies.php
new file mode 100644 (file)
index 0000000..c9d8423
--- /dev/null
@@ -0,0 +1,49 @@
+<?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/>.
+
+/**
+ * This page lets users to manage template competencies.
+ *
+ * @package    tool_lp
+ * @copyright  2015 Mark Nelson <markn@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+$id = required_param('templateid', PARAM_INT);
+
+$template = $DB->get_record('tool_lp_plan_template', array('id' => $id), '*', MUST_EXIST);
+
+admin_externalpage_setup('toollplearningplans');
+
+// Set up the page.
+$url = new moodle_url('/admin/tool/lp/templatecompetencies.php', array('templateid' => $id));
+$title = get_string('templatecompetencies', 'tool_lp');
+$templatename = format_text($template->shortname);
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($templatename);
+$PAGE->navbar->add($templatename, $url);
+
+// Display the page.
+$output = $PAGE->get_renderer('tool_lp');
+echo $output->header();
+echo $output->heading($title);
+$page = new \tool_lp\output\template_competencies_page($template->id);
+echo $output->render($page);
+echo $output->footer();
index f57a404..9dfca38 100644 (file)
@@ -50,7 +50,7 @@
 </div>
 </div>
 {{#js}}
-require(['tool_lp/coursecompetencies'], function(mod) {
-    (new mod({{courseid}}));
+require(['tool_lp/competencies'], function(mod) {
+    (new mod({{courseid}}, 'course'));
 });
 {{/js}}
diff --git a/admin/tool/lp/templates/template_competencies_page.mustache b/admin/tool/lp/templates/template_competencies_page.mustache
new file mode 100644 (file)
index 0000000..eeaf05a
--- /dev/null
@@ -0,0 +1,58 @@
+{{!
+    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/>.
+}}
+{{!
+    Template competencies template.
+}}
+<div data-region="templatecompetenciespage">
+    <div data-region="templatecompetencies">
+        <table class="generaltable fullwidth managecompetencies">
+            <tbody class="drag-parentnode">
+                {{#competencies}}
+                <tr class="drag-samenode" data-id="{{id}}">
+                    <td>
+                        <span class="drag-handlecontainer pull-left"></span>
+                        <div class="pull-right">
+                            <a href="#" data-action="delete-competency-link" data-id="{{id}}">{{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}</a>
+                        </div>
+                        {{> tool_lp/competency_summary }}
+                    </td>
+                </tr>
+                {{/competencies}}
+            </tbody>
+        </table>
+        {{^competencies}}
+        <p class="alert-info">
+            {{#str}}nocompetenciesintemplate, tool_lp{{/str}}
+        </p>
+        {{/competencies}}
+    </div>
+    <div data-region="actions">
+        <div class="pull-right">
+            {{#canmanagetemplatecompetencies}}
+            <button style="display: none">{{#str}}linktemplatecompetencies, tool_lp{{/str}}</button>
+            {{/canmanagetemplatecompetencies}}
+        </div>
+        {{#canmanagecompetencyframeworks}}
+        <p><a href="{{manageurl}}">{{#str}}managecompetenciesandframeworks, tool_lp{{/str}}</a></p>
+        {{/canmanagecompetencyframeworks}}
+    </div>
+</div>
+{{#js}}
+require(['tool_lp/competencies'], function(mod) {
+    (new mod({{templateid}}, 'template'));
+});
+{{/js}}
index bb37745..1fabe32 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2015021633; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version   = 2015052400; // 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).