Commit bb84ffc2 authored by Robert Lyon's avatar Robert Lyon

Bug 1409546: Restricting annotation assessment options

To those that should see the select dropdown
To those that can self-assess vs cannot self-assess

Change-Id: I37c0fff459c0131c420d34e52e45d7d199c71167
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent eb3ec9c1
......@@ -1251,24 +1251,28 @@ class ArtefactTypeAnnotationfeedback extends ArtefactType {
if (is_object($collection) && $collection->get('framework')) {
foreach ($view->get_artefact_metadata() as $metadata) {
if ($metadata->id === $annotation->get('id')) {
safe_require('module', 'framework');
$evidence = get_record('framework_evidence', 'annotation', $metadata->block);
$defaultval = $evidence->state;
$form['elements']['assessment'] = array(
'type' => 'select',
'title' => get_string('assessment', 'module.framework'),
'options' => array(
'0' => get_string('begun','module.framework'),
'1' => get_string('incomplete','module.framework'),
'2' => get_string('partialcomplete','module.framework'),
'3' => get_string('completed','module.framework'),
),
'defaultvalue' => $defaultval,
'width' => '280px',
);
$form['elements']['evidence'] = array(
'type' => 'hidden',
'value' => $evidence->id,
);
if ($options = Framework::allow_assessment($view->get('owner'), true, $evidence->framework)) {
if (!array_key_exists($defaultval, $options)) {
$defaultval = null;
}
$form['elements']['assessment'] = array(
'type' => 'select',
'title' => get_string('assessment', 'module.framework'),
'options' => $options,
'defaultvalue' => $defaultval,
'width' => '280px',
);
$form['elements']['evidence'] = array(
'type' => 'hidden',
'value' => $evidence->id,
);
}
}
}
}
......
......@@ -447,6 +447,9 @@ class Framework {
public static function annotation_config_form($data) {
require_once(get_config('docroot') . 'blocktype/lib.php');
if (empty($data->annotation)) {
// Get the title for the option
$title = get_field('framework_standard_element', 'shortname', 'id', $data->option);
// Find out how many blocks already exist for the view.
$maxorder = get_field_sql(
'SELECT MAX("order") FROM {block_instance} WHERE "view"=? AND "row"=? AND "column"=?',
......@@ -455,7 +458,7 @@ class Framework {
// Create the block at the end of the cell.
$annotation = new BlockInstance(0, array(
'blocktype' => 'annotation',
'title' => get_string('Annotation', 'artefact.annotation'),
'title' => (get_string('Annotation', 'artefact.annotation') . ': ' . $title),
'view' => $data->view,
'row' => 1,
'column' => 1,
......@@ -515,7 +518,7 @@ class Framework {
if (!empty($element)) {
$fordb['element'] = $element;
}
$fordb['reviewer'] = ($completed === 1) ? $reviewer : null;
$fordb['reviewer'] = ((int) $state === Self::EVIDENCE_COMPLETED) ? $reviewer : null;
update_record('framework_evidence', (object) $fordb, (object) array('id' => $id));
}
else {
......@@ -577,6 +580,8 @@ class Framework {
* This uses a feedback style config form with some extra bits.
*/
public function annotation_feedback_form($data) {
global $USER;
require_once(get_config('docroot') . 'blocktype/lib.php');
$annotation = new BlockInstance($data->annotation);
$configdata = $annotation->get('configdata');
......@@ -591,11 +596,36 @@ class Framework {
$text = $artefact->get('description');
$collection = $view->get('collection');
$evidence = get_record('framework_evidence', 'annotation', $annotation->get('id'));
$defaultval = $evidence->state;
if (!is_object($collection) || !$collection->get('framework')) {
return false;
}
$options = self::allow_assessment($view->get('owner'), true, $evidence->framework);
if (!$options) {
$choices = Self::get_choices();
$assessment = array(
'type' => 'html',
'title' => get_string('assessment', 'module.framework'),
'value' => $choices[$defaultval],
'class' => 'top-line',
);
}
else {
if (!array_key_exists($defaultval, $options)) {
$defaultval = null;
}
$assessment = array(
'type' => 'select',
'title' => get_string('assessment', 'module.framework'),
'options' => $options,
'defaultvalue' => $defaultval,
'width' => '280px',
'class' => 'top-line',
);
}
$form = array(
'name' => 'annotationfeedback',
'jsform' => true,
......@@ -606,30 +636,25 @@ class Framework {
'elements' => array(
'annotation' => array(
'type' => 'html',
'title' => get_string('studentannotation', 'module.framework'),
'value' => $text,
),
'assessment' => array(
'type' => 'select',
'title' => get_string('assessment', 'module.framework'),
'options' => array(
'0' => get_string('begun','module.framework'),
'1' => get_string('incomplete','module.framework'),
'2' => get_string('partialcomplete','module.framework'),
'3' => get_string('completed','module.framework'),
),
'defaultvalue' => $evidence->state,
'width' => '280px',
'class' => 'top-line',
),
'submitcancel' => array(
'type' => 'submitcancel',
'class' => 'btn-default',
'value' => array(get_string('save'), get_string('cancel')),
'goto' => get_string('docroot') . 'module/framework/matrix.php?id=' . $collection->get('id'),
),
),
);
if ($options || (!$options && $view->get('owner') == $USER->get('id'))) {
$form['elements']['annotationdiv'] = array(
'type' => 'html',
'value' => '<div class="modal-header modal-section">' . get_string("assessment", "module.framework") . '</div>',
);
$form['elements']['assessment'] = $assessment;
}
if ($options) {
$form['elements']['submitcancel'] = array(
'type' => 'submitcancel',
'class' => 'btn-default',
'value' => array(get_string('save'), get_string('cancel')),
'goto' => get_string('docroot') . 'module/framework/matrix.php?id=' . $collection->get('id'),
);
}
$content = pieform($form);
list($feedbackcount, $annotationfeedback) = ArtefactTypeAnnotationfeedback::get_annotation_feedback_for_matrix($artefact, $view, $annotation->get('id'));
$content .= $annotationfeedback;
......@@ -642,6 +667,107 @@ class Framework {
);
return $return;
}
/**
* Check to see if a user can add an annotation via the matrix page. Currently only view owner
*
* @param string $viewid The view the matrix point is associated with
*
* @return bool
*/
public static function allow_annotation($viewid) {
global $USER;
if (empty($viewid) || !is_numeric($viewid)) {
return false;
}
require_once(get_config('libroot') . 'view.php');
$view = new View($viewid);
$collection = $view->get('collection');
if (!is_object($collection)) {
return false;
}
$framework = $collection->get('framework');
if (empty($framework)) {
return false;
}
$userid = $USER->get('id');
if ($USER->get('id') == $view->get('owner')) {
// Is owner
return true;
}
return false;
}
/**
* Check to see if a user can set the assessment status for a piece of evidence.
* If $options is set to true return the valid options for a select dropdown
*
* @param string $ownerid The owner of the smart evidence annotation
* @param bool $options Whether to return the valid options (on true) or just true/false
* @param string $framework ID of the framework
*
* @return mixed either bool or array for select dropdown
*/
public static function allow_assessment($ownerid, $options = false, $framework = null) {
global $USER;
if (empty($ownerid) || !is_numeric($ownerid)) {
return false;
}
$owner = new User();
$owner->find_by_id($ownerid);
$ownerinstitutions = array_keys($owner->get('institutions'));
$institution = (!empty($ownerinstitutions)) ? $ownerinstitutions[0] : 'mahara';
$isowner = ($owner->get('id') === $USER->get('id'));
$isadminofowner = $selfcomplete = false;
if ($USER->get('admin') || $USER->get('staff')) {
$isadminofowner = true;
}
else if ($institution != 'mahara' && ($USER->is_institutional_admin($institution) || $USER->is_institutional_staff($institution))) {
$isadminofowner = true;
}
require_once(get_config('libroot') . 'institution.php');
$institution = new Institution($institution);
// Check that smart evidence self assessment is enabled for the framework
if ($framework) {
$framework = new Framework($framework);
if ($framework->selfassess) {
$selfcomplete = true;
}
}
if ($isowner || $isadminofowner) {
if ($options) {
$reply = Self::get_choices();
if (($isowner && $selfcomplete === false) ||
($isadminofowner && $selfcomplete === true)) {
unset($reply[1]);
unset($reply[2]);
unset($reply[3]);
}
return $reply;
}
else {
return true;
}
}
return false;
}
public static function get_choices() {
return array(
Self::EVIDENCE_BEGUN => get_string('begun','module.framework'),
Self::EVIDENCE_INCOMPLETE => get_string('incomplete','module.framework'),
Self::EVIDENCE_PARTIALCOMPLETE => get_string('partialcomplete','module.framework'),
Self::EVIDENCE_COMPLETED => get_string('completed','module.framework'),
);
}
}
class FrameworkNotFoundException extends NotFoundException {}
......@@ -166,7 +166,7 @@ jQuery(function($) {
});
var cellx = celly = 0;
$('#tablematrix td.mid span').on('click', function(e) {
$('#tablematrix td.mid span:not(.disabled)').on('click', function(e) {
e.preventDefault();
cellx = $(this).closest('td').index();
celly = $(this).closest('tr').index();
......@@ -273,6 +273,10 @@ jQuery(function($) {
values['action'] = 'evidence';
editmatrix_update(values);
tinyMCE.execCommand('mceRemoveEditor', false, "instconf_text");
feedbacktextarea = $("#addfeedbackmatrix textarea");
if (feedbacktextarea.length) {
tinyMCE.execCommand('mceRemoveEditor', false, feedbacktextarea.attr('id'));
}
dock.hide();
});
// When we are saving the annotation feedback form - adding new feedback
......@@ -344,6 +348,7 @@ $smarty->assign('description', $framework->get('description'));
$smarty->assign('standards', $standards['standards']);
$smarty->assign('evidence', $evidencematrix);
$smarty->assign('completed', $completed);
$smarty->assign('canaddannotation', Framework::allow_annotation($view->get('id')));
$smarty->assign('standardscount', $standards['count']);
$smarty->assign('framework', $collection->get('framework'));
$smarty->assign('views', $views['views']);
......
......@@ -33,7 +33,7 @@ $evidence = get_record('framework_evidence', 'framework', $framework, 'element',
if ($action == 'update') {
// When we click a dot on the matrix and add an annotation
require_once(get_config('docroot') . 'blocktype/lib.php');
$title = param_alphanumext('title', 'Annotation');
$title = param_variable('title', 'Annotation');
$text = param_variable('text', '');
$allowfeedback = param_boolean('allowfeedback');
$retractable = param_integer('retractable', 0);
......@@ -67,7 +67,7 @@ if ($action == 'update') {
$message = get_string('matrixpointinserted', 'module.framework');
}
$class = 'icon icon-circle-o danger';
$class = 'icon icon-circle-o begun';
$data = (object) array('id' => $id,
'class' => $class,
'view' => $view,
......@@ -77,36 +77,30 @@ if ($action == 'update') {
}
else if ($action == 'evidence') {
global $USER;
// When we click on one of the begun/ready/completed symbols and submit that form
// When we click on one of the begun/incomplete/partialcomplete/completed symbols and submit that form
if (!$evidence->id) {
// problem need to return error
}
$begun = $ready = $completed = 0;
$reviewer = null;
$assessment = param_alpha('assessment', 'begun');
switch ($assessment) {
case 'completed':
$begun = $ready = $completed = 1;
$reviewer = $USER->get('id');
break;
case 'ready':
$begun = $ready = 1;
break;
default:
$begun = 1;
$assessment = param_alphanum('assessment', 0);
if (Framework::EVIDENCE_COMPLETED === (int) $assessment) {
$reviewer = $USER->get('id');
}
$id = Framework::save_evidence($evidence->id, null, null, null, $evidence->annotation, $assessment, $USER->get('id'));
$message = get_string('matrixpointupdated', 'module.framework');
if ($completed) {
$class = 'icon icon-circle success';
if (Framework::EVIDENCE_COMPLETED === (int) $assessment) {
$class = 'icon icon-circle completed';
}
else if ($ready) {
$class = 'icon icon-adjust warning';
else if (Framework::EVIDENCE_PARTIALCOMPLETE === (int) $assessment) {
$class = 'icon icon-adjust partial';
}
else if (Framework::EVIDENCE_INCOMPLETE === (int) $assessment) {
$class = 'icon icon-circle-o incomplete';
}
else {
$class = 'icon icon-circle-o danger';
$class = 'icon icon-circle-o begun';
}
$data = (object) array('id' => $id,
......@@ -156,7 +150,7 @@ else {
'partialcomplete' => $states['partialcomplete'],
'completed' => $states['completed'],
);
if ($evidence && !empty($params->begun)) {
if ($evidence) {
// There is an annotation in play
$form = Framework::annotation_feedback_form($params);
}
......
......@@ -411,6 +411,27 @@ class BehatForms extends BehatBase {
}
}
/**
* Checks if a field is present
*
* @When /^I should not see the field "(?P<fieldlabel>(?:[^"]|\\")*)"$/
*
* @param string $fieldlabel the label of the field
* @throws ExpectationException
*/
public function field_not_found($fieldlabel) {
$fieldlocator = $this->unescapeDoubleQuotes($fieldlabel);
try {
$field = BehatFieldManager::get_form_field_from_label($fieldlocator, $this);
// Field exists so we need to thow exception
throw new ExpectationException(
"The '" . $fieldlabel . "' field exists, expected to be absent", $this->getSession());
}
catch (ElementNotFoundException $fieldexception) {
// field doesn't exist so all is good
}
}
/**
* Generic field setter.
*
......
......@@ -42,15 +42,15 @@
{foreach from=$views key=vk item=view}
<td class="mid"><span data-view="{$view->id}" data-option="{$option->id}"
{if $evidence[$framework][$option->id][$view->id].completed}
class="icon icon-circle completed">
class="icon icon-circle completed" title="{str tag='completed' section='module.framework'}">
{elseif $evidence[$framework][$option->id][$view->id].partialcomplete}
class="icon icon-adjust partial">
class="icon icon-adjust partial" title="{str tag='partialcomplete' section='module.framework'}">
{elseif $evidence[$framework][$option->id][$view->id].incomplete}
class="icon icon-circle-o incomplete">
class="icon icon-circle-o incomplete" title="{str tag='incomplete' section='module.framework'}">
{elseif $evidence[$framework][$option->id][$view->id].begun}
class="icon icon-circle-o begun">
class="icon icon-circle-o begun" title="{str tag='begun' section='module.framework'}">
{else}
>&bull;
class="dot{if !$canaddannotation} disabled{/if}">&bull;
{/if}
</span>
</td>
......
......@@ -30,6 +30,12 @@
&.completed {
color: $brand-success;
}
&.dot {
padding: 5px 10px;
&.disabled {
cursor: not-allowed;
}
}
}
}
......
......@@ -89,5 +89,5 @@ Scenario: Installing framework module and activating for an institution
| Feedback | This is annotation feedback |
And I press "Place feedback"
# And change assessment status
And I select "Partially meets the standard" from "Assessment"
And I should not see the field "Assessment"
And I press "Save"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment