Commit 1736df85 authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic Committed by Robert Lyon
Browse files

Bug 1724797: Creating status headers for SmartEvidence matrix

- Make all counts for assessment statuses available in the evidence
  matrix page.
- Select in the site administration area, which statuses you want to make
  available for a particular standard.

Sponsored by: PH Bern for SWITCHportfolio
behatnotneeded

Change-Id: I815e9de6c02b3f503e637c01d0083519b95f09a3
parent 5a911c57
......@@ -100,5 +100,17 @@
<KEY NAME="usrfk" TYPE="foreign" FIELDS="usr" REFTABLE="usr" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="framework_config">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
<FIELD NAME="framework" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="field" TYPE="char" LENGTH="255" NOTNULL="true" />
<FIELD NAME="value" TYPE="text" LENGTH="small" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
<KEY NAME="frameworkfk" TYPE="foreign" FIELDS="framework" REFTABLE="framework" REFFIELDS="id" />
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
\ No newline at end of file
</XMLDB>
......@@ -66,5 +66,25 @@ function xmldb_module_framework_upgrade($oldversion=0) {
}
}
if ($oldversion < 2017101600) {
log_debug('Add new Smart Evidence framework_config table and status heading properties');
$table = new XMLDBTable('framework_config');
$table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
$table->addFieldInfo('framework', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL);
$table->addFieldInfo('field', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL);
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->addKeyInfo('frameworkidfk', XMLDB_KEY_FOREIGN, array('framework'), 'framework', array('id'));
create_table($table);
$frameworks = get_column('framework', 'id');
$status = new StdClass;
foreach ($frameworks as $key => $frameworkid) {
$framework = new Framework($frameworkid);
$framework->set_config_fields();
}
}
return true;
}
<?php
/**
*
* @package mahara
* @subpackage module-framework
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('ADMIN', 1);
define('MENUITEM', 'configextensions/frameworks');
define('SECTION_PLUGINTYPE', 'module');
define('SECTION_PLUGINNAME', 'framework');
define('SECTION_PAGE', 'frameworks');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
define('TITLE', get_string('Framework', 'module.framework'));
safe_require('module', 'framework');
$frameworkid = param_integer('id', 0);
$framework = new Framework($frameworkid);
$plugintype = 'module';
$pluginname = 'framework';
$classname = 'Framework';
$form = $framework->get_framework_config_options();
if (!array_key_exists('class', $form)) {
$form['class'] = 'panel panel-body';
}
$form['name'] = 'frameworkconfig';
$form['frameworkconfigform'] = true;
$form['jsform'] = true;
$form['successcallback'] = 'frameworkconfig_submit';
$form['elements']['plugintype'] = array(
'type' => 'hidden',
'value' => $plugintype
);
$form['elements']['pluginname'] = array(
'type' => 'hidden',
'value' => $pluginname
);
$form['elements']['framework'] = array(
'type' => 'hidden',
'value' => $frameworkid
);
$form['elements']['save'] = array(
'type' => 'submitcancel',
'class' => 'btn-primary',
'value' => array(
get_string('save'),
get_string('cancel')
),
'goto' => get_config('wwwroot') . 'module/framework/frameworks.php',
);
$form = pieform($form);
$smarty = smarty();
$smarty->assign('form', $form);
$smarty->assign('plugintype', $plugintype);
$smarty->assign('pluginname', $pluginname);
$heading = get_string('pluginadmin', 'admin') . ': ' . $plugintype . ': ' . $pluginname;
$smarty->assign('PAGEHEADING', $heading);
$smarty->display('module:framework:frameworkmanager.tpl');
function frameworkconfig_submit(Pieform $form, $values) {
$success = false;
global $plugintype, $pluginname, $classname, $USER;
if (!is_plugin_active($pluginname, $plugintype)) {
$SESSION->add_error_msg(get_string('needtoactivate', 'module.framework'));
}
if (!$USER->get('admin')) {
$SESSION->add_error_msg(get_string('accessdenied'));
}
try {
$frameworkid = $values['framework'];
$framework = new Framework($frameworkid);
$framework->save_config_options($form, $values);
$success = true;
}
catch (Exception $e) {
$success = false;
}
if ($success) {
$form->json_reply(PIEFORM_OK, get_string('settingssaved'));
}
else {
$form->json_reply(PIEFORM_ERR, array('message' => get_string('settingssavefailed')));
}
}
<?php
/**
*
* @package mahara
* @subpackage module-framework
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('JSON', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('module', 'framework');
global $USER;
if (!is_plugin_active('framework', 'module')) {
json_reply(true, get_string('needtoactivate', 'module.framework'));
}
if (!$USER->get('admin')) {
json_reply(true, get_string('accessdenied'));
}
else {
form_validate(param_variable('sesskey', null));
$id = param_integer('id');
$enabledval = param_alphanum('enabled', false);
$enabled = ($enabledval == 'on' || $enabledval == 1) ? 1 : 0;
// need to update the active status
if (set_field('framework', 'active', $enabled, 'id', $id)) {
json_reply(false, array('data' => array('ok' => true)));
}
}
......@@ -36,35 +36,19 @@ if ($upload) {
$frameworks = Framework::get_frameworks('any');
if ($frameworks) {
foreach ($frameworks as $framework) {
$framework->activationswitch = pieform(
array(
'name' => 'framework' . $framework->id,
'successcallback' => 'framework_update_submit',
'renderer' => 'div',
'class' => 'form-inline pull-left framework',
'jsform' => false,
'checkdirtychange' => false,
'elements' => array(
'plugintype' => array(
'type' => 'hidden',
'value' => 'module'
),
'pluginname' => array(
'type' => 'hidden',
'value' => 'framework'
),
'id' => array(
'type' => 'hidden',
'value' => $framework->id
),
'enabled' => array(
'type' => 'switchbox',
'value' => $framework->active,
),
),
)
);
$fk = new Framework($framework->id);
if ($fk->get('active')) {
$framework->active = array(
'title' => 'Enabled',
'classes' => 'icon icon-lg icon-check text-success displayicon'
);
}
else {
$framework->active = array(
'title' => 'Disabled',
'classes' => 'icon icon-lg icon-times text-danger displayicon'
);
}
$framework->collections = count($fk->get_collectionids());
$framework->delete = false;
if (empty($framework->collections)) {
......@@ -73,7 +57,7 @@ if ($frameworks) {
'name' => 'framework_delete_' . $framework->id,
'successcallback' => 'framework_delete_submit',
'renderer' => 'div',
'class' => 'form-inline form-as-button pull-right framework',
'class' => 'form-inline pull-right framework',
'elements' => array(
'submit' => array(
'type' => 'button',
......@@ -90,30 +74,28 @@ if ($frameworks) {
)
);
}
}
}
$framework->config = pieform(
array(
'name' => 'framework_config_' . $framework->id,
'successcallback' => 'framework_config_submit',
'renderer' => 'div',
'class' => 'form-inline pull-right framework',
'elements' => array(
'submit' => array(
'type' => 'button',
'class' => 'btn-default btn-sm',
'usebuttontag' => true,
'value' => '<span class="icon icon-cog icon-lg" role="presentation" aria-hidden="true"></span><span class="sr-only">'. get_string('delete') . '</span>',
function framework_update_submit(Pieform $form, $values) {
global $SESSION;
// Should not normally get here as the form has no submit button and is updated via ajax/frameworks.json.php
// but in case one does
if (!is_plugin_active('framework', 'module')) {
$SESSION->add_error_msg(get_string('needtoactivate', 'module.framework'));
}
if (!$USER->get('admin')) {
$SESSION->add_error_msg(get_string('accessdenied'));
}
else {
$id = $values['id'];
$enabledval = param_alphanum('enabled', false);
$enabled = ($enabledval == 'on' || $enabledval == 1) ? 1 : 0;
// need to update the active status
if (set_field('framework', 'active', $enabled, 'id', $id)) {
$SESSION->add_ok_msg(get_string('frameworkupdated', 'module.framework'));
}
),
'framework' => array(
'type' => 'hidden',
'value' => $framework->id,
)
),
)
);
}
redirect('/module/framework/frameworks.php');
}
function framework_delete_submit(Pieform $form, $values) {
......@@ -131,6 +113,10 @@ function framework_delete_submit(Pieform $form, $values) {
redirect('/module/framework/frameworks.php');
}
function framework_config_submit(Pieform $form, $values) {
redirect(get_config('wwwroot') . 'module/framework/frameworkmanager.php?id=' . $values['framework']);
}
$smarty = smarty();
setpageicon($smarty, 'icon-th');
$smarty->assign('frameworks', $frameworks);
......
jQuery(function($) {
// Variable to adjust for the hiding/showing of columns
var minstart = 1; // The index of the last column before first page column, indexes start at zero so 1 = two columns
var curstart = 2; // The index of first page currently being displayed
var statusheaders = $('.statusheader').length;
var dashes = $('th.smartevidencedash').length;
var minstart = statusheaders + dashes; // The index of the last column before first page column, indexes start at zero so 1 = two columns
var curstart = 1 + statusheaders + dashes; // The index of first page currently being displayed
var range = 4; // The number of pages to display
var curend = curstart + range; // The index of last page currently being displayed
var maxend = $( "#tablematrix tr th" ).length; // The number of columns in the table
......@@ -287,8 +289,23 @@ jQuery(function($) {
.attr('title', results.data.title)
.data('option', results.data.option)
.data('view', results.data.view).empty();
var completed = parseInt($('#tablematrix tr:eq(' + celly + ') td.completedcount span:nth-child(2)').text(), 10);
$('#tablematrix tr:eq(' + celly + ') td.completedcount span:nth-child(2)').text(completed + results.data.completed);
if (results.data.readyforassessment) {
var readyforassessment = parseInt($('#tablematrix tr:eq(' + celly + ') td.completedcount.readyforassessment span:nth-child(2)').text(), 10);
$('#tablematrix tr:eq(' + celly + ') td.completedcount.readyforassessment span:nth-child(2)').text(readyforassessment + results.data.readyforassessment);
}
if (results.data.dontmatch) {
var dontmatch = parseInt($('#tablematrix tr:eq(' + celly + ') td.completedcount.dontmatch span:nth-child(2)').text(), 10);
$('#tablematrix tr:eq(' + celly + ') td.completedcount.dontmatch span:nth-child(2)').text(dontmatch + results.data.dontmatch);
}
if (results.data.partiallycomplete) {
var partiallycomplete = parseInt($('#tablematrix tr:eq(' + celly + ') td.completedcount.partiallycomplete span:nth-child(2)').text(), 10);
$('#tablematrix tr:eq(' + celly + ') td.completedcount.partiallycomplete span:nth-child(2)').text(partiallycomplete + results.data.partiallycomplete);
}
if (results.data.completed) {
var completed = parseInt($('#tablematrix tr:eq(' + celly + ') td.completedcount.completed span:nth-child(2)').text(), 10);
$('#tablematrix tr:eq(' + celly + ') td.completedcount.completed span:nth-child(2)').text(completed + results.data.completed);
}
}
if (results.data.tablerows) {
if ($("#matrixfeedbacklist").has(".annotationfeedbacktable").length == 0) {
......
......@@ -53,10 +53,17 @@ $string['selfassess'] = 'Self-assess';
$string['uploadframeworkdesc1'] = 'Upload a JSON encoded .matrix file. See the <a href="https://git.mahara.org/mahara/mahara/blob/16.10_STABLE/test/behat/upload_files/example.matrix">Mahara git repository</a> for an example of the markup and the <a href="http://manual.mahara.org/en/16.10/administration/smartevidence.html#create-a-framework-file">Mahara user manual</a> for an explanation of the individual components.';
$string['savematrix'] = 'Upload matrix';
$string['frameworkmissing'] = 'Framework not found';
$string['activeframework'] = 'Active framework';
$string['displaystatusestitle'] = 'Display assessment statuses';
$string['displaystatusestitledetail'] = 'Decide which of the assessment statuses you want to display.';
$string['upgradeplugin'] = 'The SmartEvidence plugin needs to be upgraded to enable these settings.';
$string['noannotation'] = 'There are no annotations on page "%s" for standard element "%s".';
$string['addannotation'] = 'Add an annotation for standard "%s" to page "%s".';
$string['completedcount'] = 'Number of pages that contain the completed standard element:';
$string['readyforassessmentcount'] = 'Number of pages that contain the standard element ready for assessment:';
$string['dontmatchcount'] = 'Number of pages that contain the incompleted standard element:';
$string['partiallycompletecount'] = 'Number of pages that contain the partially completed standard element:';
$string['completedcount'] = 'Number of pages that contain the complete standard element:';
$string['tabledesc'] = 'Below is the structure for the collection\'s SmartEvidence matrix.';
$string['standardbegin'] = 'Beginning of a standard section';
$string['uncollapsesection'] = 'Click to show the table section for standard "%s".';
......@@ -65,6 +72,9 @@ $string['collapsedsection'] = 'This table section for the standard is hidden.';
$string['gonextpages'] = 'Click the "Next" button to display more pages of the collection in the SmartEvidence matrix.';
$string['goprevpages'] = 'Click the "Previous" button to display pages in the SmartEvidence matrix that come earlier in the collection.';
$string['headerelements'] = 'Column header: Standard elements';
$string['headerreadyforassessmentcount'] = 'Column header: Number of pages that contain the standard element ready for assessment';
$string['headernotmatchcount'] = 'Column header: Number of pages that contain the incomplete standard element';
$string['headerpartiallycompletecount'] = 'Column header: Number of pages that contain the partially completed standard element';
$string['headercompletedcount'] = 'Column header: Number of pages that contain the completed standard element';
$string['headerpage'] = 'Column header: Page title';
$string['headerrow'] = 'Row header: Standard element';
......
......@@ -111,6 +111,7 @@ class PluginModuleFramework extends PluginModule {
else {
$framework = new Framework(null, $ok['content']->framework);
$framework->commit();
$framework->set_config_fields();
}
}
......@@ -239,6 +240,7 @@ class Framework {
delete_records('framework_assessment_feedback', 'framework', $this->id);
delete_records_sql('DELETE FROM {framework_standard_element} WHERE standard IN (' . join(',', array_map('intval', $standards)) . ')');
delete_records('framework_standard', 'framework', $this->id);
delete_records('framework_config', 'framework', $this->id);
delete_records('framework', 'id', $this->id);
db_commit();
......@@ -371,6 +373,32 @@ class Framework {
db_commit();
}
function set_config_fields() {
if (table_exists(new XMLDBTable('framework_config'))) {
$status = new StdClass;
$status->framework = $this->get('id');
$status->field = 'completed_field_enabled';
$status->value = 1;
insert_record('framework_config', $status);
$status->framework = $this->get('id');
$status->field = 'readyforassesment_field_enabled';
$status->value = 0;
insert_record('framework_config', $status);
$status->framework = $this->get('id');
$status->field = 'dontmatch_field_enabled';
$status->value = 0;
insert_record('framework_config', $status);
$status->framework = $this->get('id');
$status->field = 'partiallycomplete_field_enabled';
$status->value = 0;
insert_record('framework_config', $status);
}
}
/**
* Returns array of standards in the current framework
*
......@@ -1003,6 +1031,162 @@ class Framework {
}
return $statuses;
}
function get_config($value) {
$record = false;
if (table_exists(new XMLDBTable('framework_config')) &&
$record = get_record('framework_config', 'framework', $this->id, 'field', $value)) {
return $record->value;
}
return $record;
}
function set_config($field, $value) {
set_field('framework_config', 'value', $value, 'field', $field, 'framework', $this->id);
}
public function config_option_enabled($configoption) {
$enabled = false;
if ($configoption == 'active_framework') {
$enabled = $this->get('active');
}
else {
$enabled = $this->get_config($configoption);
}
return $enabled;
}
public function get_config_option_fields() {
$options = array(
'active_framework',
'readyforassesment_field_enabled',
'dontmatch_field_enabled',
'partiallycomplete_field_enabled',
'completed_field_enabled',
);
return $options;
}
public function get_framework_config_options() {
// check if the plugin has been upgraded
// if not, all status settings should be greyed out
$disabled = !table_exists(new XMLDBTable('framework_config'));
$warning = array();
if ($disabled) {
$warning['plugin_warning'] = array(
'type' => 'markup',
'value' => '<div class="admin-warning alert alert-warning">' .
'<p>' . get_string('upgradeplugin', 'module.framework') . '</p></div>',
);
}
$choices = Framework::get_evidence_statuses($this->get('id'));
$options = array(
'active_framework' => array(
'type' => 'switchbox',
'title' => get_string('activeframework','module.framework'),
'defaultvalue' => $this->config_option_enabled('active_framework'),
),
'statusestitle' => array(
'type' => 'html',
'value' => "<h4>" . get_string('displaystatusestitle','module.framework') . "</h4>" .
"<p>" . get_string('displaystatusestitledetail','module.framework') . "</p>",
),
'readyforassesment_container' => array(
'type' => 'fieldset',
'class' => 'form-inline',
'elements' => array(
'label' => array(
'type'=> 'html',
'value' => '<div class="pseudolabel statusheader"><span>' . $choices[Framework::EVIDENCE_BEGUN] . '</span>' .
'<span class="' . $this->get_state_array(Framework::EVIDENCE_BEGUN)['begun']['classes'] . '"></span></div>',
),
'readyforassesment_field_enabled' => array(
'type' => 'switchbox',
'title' => '',
'defaultvalue' => $this->config_option_enabled('readyforassesment_field_enabled'),
'disabled' => $disabled,
),
),
),
'dontmatch_container' => array(
'type' => 'fieldset',
'class' => 'form-inline',
'elements' => array(
'label' => array(
'type'=> 'html',
'value' => '<div class="pseudolabel statusheader"><span>' . $choices[Framework::EVIDENCE_INCOMPLETE] . '</span>' .
'<span class="' . $this->get_state_array(Framework::EVIDENCE_INCOMPLETE)['incomplete']['classes'] . '"></span></div>',
),
'dontmatch_field_enabled' => array(
'type' => 'switchbox',
'title' => '',
'defaultvalue' => $this->config_option_enabled('dontmatch_field_enabled'),
'disabled' => $disabled,
),
),
),
'partiallycomplete_container' => array(
'type' => 'fieldset',
'class' => 'form-inline',
'elements' => array(
'label' => array(
'type'=> 'html',
'value' => '<div class="pseudolabel statusheader"><span>' . $choices[Framework::EVIDENCE_PARTIALCOMPLETE] . '</span>' .
'<span class="' . $this->get_state_array(Framework::EVIDENCE_PARTIALCOMPLETE)['partialcomplete']['classes'] . '"></span></div>',
),
'partiallycomplete_field_enabled' => array(
'type' => 'switchbox',
'title' => '',
'defaultvalue' => $this->config_option_enabled('partiallycomplete_field_enabled'),
'disabled' => $disabled,
),
),
),
'completed_container' => array(
'type' => 'fieldset',
'class' => 'form-inline',
'elements' => array(
'label' => array(
'type'=> 'html',
'value' => '<div class="pseudolabel statusheader"><span>' . $choices[Framework::EVIDENCE_COMPLETED] . '</span>' .
'<span class="' . $this->get_state_array(Framework::EVIDENCE_COMPLETED)['completed']['classes'] . '"></span></div>',
),
'completed_field_enabled' => array(
'type' => 'switchbox',
'title' => '',
'value' => $disabled || $this->config_option_enabled('completed_field_enabled'),
'disabled' => true,
),
),
),
);
return array(
'elements' => array_merge($warning, $options),
);
}
public function save_config_options(Pieform $form, $values) {
$configoptions = $this->get_config_option_fields();
foreach ($configoptions as $option) {
if (isset($values[$option])) {
$enabled = ($values[$option] == true || $values[$option] == 1) ? 1 : 0;
if ($option === 'active_framework') {
$this->set('active', $enabled);
$this->commit();
}
else {
if ($option != 'completed_field_enabled')
$this->set_config($option, $enabled);
}
}
}
}
}
class FrameworkNotFoundException extends NotFoundException {}
......
......@@ -125,17 +125,69 @@ $evidence = $framework->get_evidence($collection->get('id'));
if (!$evidence) {
$evidence = array();
}
$evidencematrix = $completed = array();
$evidencematrix = array();
$statuscounts = new StdClass();
$enabled = new StdClass();