Commit 2d54d56b authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic Committed by Gerrit Code Review
Browse files

Merge changes I86648649,If35431aa,If4c93629,I4b462f44

* changes:
  Bug 1723961: Allow update status of plan task via normal page display
  Bug 1723961: Allow user to edit tasks from blocktype
  Bug 1723961: Add edit links for each plan in a block instance
  Bug 1723961: Allow plan blocktypes to display more than one plan
parents 25953766 f94180b4
function rewriteTaskTitles(blockid) {
jQuery('tasktable_' + blockid + ' a.task-title').each(function() {
function rewriteTaskTitles(blockid, planid) {
jQuery('tasklist_' + blockid + '_plan' + planid + ' a.task-title').each(function() {
jQuery(this).off();
jQuery(this).on('click', function(e) {
e.preventDefault();
......@@ -8,18 +8,55 @@ function rewriteTaskTitles(blockid) {
});
});
}
function TaskPager(blockid) {
function TaskPager(blockid, planid) {
var self = this;
paginatorProxy.addObserver(self);
jQuery(self).on('pagechanged', rewriteTaskTitles.bind(null, blockid));
jQuery(self).on('pagechanged', rewriteTaskTitles.bind(null, blockid, planid));
}
var taskPagers = [];
function changeCheckBox(taskid, state) {
if (state == 1) {
function initNewPlansBlock(blockid) {
if (jQuery('#plans_page_container_' + blockid)) {
new Paginator('block' + blockid + '_pagination', 'tasktable_' + blockid, null, 'artefact/plans/viewtasks.json.php', null);
taskPagers.push(new TaskPager(blockid));
$('.task' + taskid).next('span').removeClass('text-danger').addClass('text-success');
$('.task' + taskid).removeClass('text-midtone icon-square-o icon-times text-danger').addClass('icon-check-square-o text-success');
}
rewriteTaskTitles(blockid);
else if (state == -1) {
$('.task' + taskid).next('span').removeClass('text-success').addClass('text-danger');
$('.task' + taskid).removeClass('icon-check-square-o icon-square-o text-success').addClass('icon-times text-danger');
}
else {
$('.task' + taskid).next('span').removeClass('text-success text-danger');
$('.task' + taskid).removeClass('icon-check-square-o icon-times text-success text-danger').addClass('icon-square-o text-midtone');
}
}
function saveCheckBoxChange(taskid) {
var params = {};
params.taskid = taskid;
sendjsonrequest(config.wwwroot + 'artefact/plans/checktask.json.php', params, 'POST', function(data) {
if (data.data) {
changeCheckBox(data.data.artefact, data.data.state);
}
});
}
function enableCheckBoxes() {
jQuery('.plan-task-icon').off('click');
jQuery('.plan-task-icon').on('click', function(e) {
e.stopPropagation();
e.preventDefault();
var taskid = jQuery(e.target).data('task');
saveCheckBoxChange(taskid);
});
}
// Wire up the checkboxes
jQuery(document).on('pageupdated', function(e, data) {
// When using pagination
enableCheckBoxes();
});
jQuery(function() {
// On page load
enableCheckBoxes();
});
......@@ -32,8 +32,13 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
public static function get_instance_title(BlockInstance $bi) {
$configdata = $bi->get('configdata');
if (!empty($configdata['artefactid'])) {
return $bi->get_artefact_instance($configdata['artefactid'])->get('title');
if (!empty($configdata['artefactids']) && is_array($configdata['artefactids'])) {
if (count($configdata['artefactids']) > 1) {
return get_string('title', 'blocktype.plans/plans');
}
else if (count($configdata['artefactids']) == 1) {
return $bi->get_artefact_instance($configdata['artefactids'][0])->get('title');
}
}
return '';
}
......@@ -43,7 +48,6 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
return array(
array(
'file' => 'js/plansblock.js',
'initjs' => "initNewPlansBlock($blockid);",
)
);
}
......@@ -58,37 +62,53 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
$limit = (!empty($configdata['count'])) ? $configdata['count'] : 10;
$smarty = smarty_core();
if (isset($configdata['artefactid'])) {
$plan = artefact_instance_from_id($configdata['artefactid']);
$tasks = ArtefactTypeTask::get_tasks($configdata['artefactid'], 0, $limit);
$template = 'artefact:plans:taskrows.tpl';
$blockid = $instance->get('id');
if ($exporter) {
$pagination = false;
}
else {
$baseurl = $instance->get_view()->get_url();
$baseurl .= ((false === strpos($baseurl, '?')) ? '?' : '&') . 'block=' . $blockid;
$pagination = array(
'baseurl' => $baseurl,
'id' => 'block' . $blockid . '_pagination',
'datatable' => 'tasklist_' . $blockid,
'jsonscript' => 'artefact/plans/viewtasks.json.php',
);
}
$configdata['view'] = $instance->get('view');
ArtefactTypeTask::render_tasks($tasks, $template, $configdata, $pagination);
if ($exporter && $tasks['count'] > $tasks['limit']) {
$artefacturl = get_config('wwwroot') . 'artefact/artefact.php?artefact=' . $configdata['artefactid']
. '&view=' . $instance->get('view');
$tasks['pagination'] = '<a href="' . $artefacturl . '">' . get_string('alltasks', 'artefact.plans') . '</a>';
if (isset($configdata['artefactids']) && is_array($configdata['artefactids']) && count($configdata['artefactids']) > 0) {
$plans = array();
$alltasks = array();
foreach ($configdata['artefactids'] as $planid) {
$plan = artefact_instance_from_id($planid);
$tasks = ArtefactTypeTask::get_tasks($planid, 0, $limit);
$template = 'artefact:plans:taskrows.tpl';
$blockid = $instance->get('id');
if ($exporter) {
$pagination = false;
}
else {
$baseurl = $instance->get_view()->get_url();
$baseurl .= ((false === strpos($baseurl, '?')) ? '?' : '&') . 'block=' . $blockid . '&planid=' . $planid . '&editing=' . $editing;
$pagination = array(
'baseurl' => $baseurl,
'id' => 'block' . $blockid . '_plan' . $planid . '_pagination',
'datatable' => 'tasklist_' . $blockid . '_plan' . $planid,
'jsonscript' => 'artefact/plans/viewtasks.json.php',
);
}
$configdata['view'] = $instance->get('view');
$configdata['block'] = $blockid;
ArtefactTypeTask::render_tasks($tasks, $template, $configdata, $pagination, $editing);
if ($exporter && $tasks['count'] > $tasks['limit']) {
$artefacturl = get_config('wwwroot') . 'artefact/artefact.php?artefact=' . $planid
. '&view=' . $instance->get('view');
$tasks['pagination'] = '<a href="' . $artefacturl . '">' . get_string('alltasks', 'artefact.plans') . '</a>';
}
$plans[$planid]['id'] = $planid;
$plans[$planid]['title'] = $plan->get('title');
$plans[$planid]['description'] = $plan->get('description');
$plans[$planid]['owner'] = $plan->get('owner');
$plans[$planid]['tags'] = $plan->get('tags');
$plans[$planid]['view'] = $instance->get('view');
$plans[$planid]['details'] = get_config('wwwroot') . 'artefact/artefact.php?artefact=' . $plan->get('id') . '&view=' .
$instance->get_view()->get('id') . '&block=' . $blockid;
$plans[$planid]['numtasks'] = $tasks['count'];
$tasks['planid'] = $planid;
array_push($alltasks, $tasks);
}
$smarty->assign('description', $plan->get('description'));
$smarty->assign('owner', $plan->get('owner'));
$smarty->assign('tags', $plan->get('tags'));
$smarty->assign('tasks', $tasks);
$smarty->assign('view', $instance->get('view'));
$smarty->assign('editing', $editing);
$smarty->assign('plans', $plans);
$smarty->assign('alltasks', $alltasks);
}
else {
$smarty->assign('noplans','blocktype.plans/plans');
......@@ -109,7 +129,7 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
$form = array();
// Which resume field does the user want
$form[] = self::artefactchooser_element((isset($configdata['artefactid'])) ? $configdata['artefactid'] : null);
$form[] = self::artefactchooser_element((isset($configdata['artefactids'])) ? $configdata['artefactids'] : null);
$form['count'] = array(
'type' => 'text',
'title' => get_string('taskstodisplay', 'blocktype.plans/plans'),
......@@ -123,12 +143,12 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
public static function artefactchooser_element($default=null) {
safe_require('artefact', 'plans');
return array(
'name' => 'artefactid',
'name' => 'artefactids',
'type' => 'artefactchooser',
'title' => get_string('planstoshow', 'blocktype.plans/plans'),
'defaultvalue' => $default,
'blocktype' => 'plans',
'selectone' => true,
'selectone' => false,
'search' => false,
'artefacttypes' => array('plan'),
'template' => 'artefact:plans:artefactchooser-element.tpl',
......
<?php
/**
*
* @package mahara
* @subpackage core
* @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('SECTION_PLUGINTYPE', 'core');
require(dirname(dirname(dirname(__FILE__))). '/init.php');
$taskid = param_integer('taskid');
$task = get_record_sql('SELECT *, CASE WHEN completiondate < NOW() THEN -1 ELSE 1 END AS state
FROM {artefact_plans_task}
WHERE artefact = ?', array($taskid));
$artefacttask = get_record('artefact', 'id', $task->artefact);
// Check if the user checking the task is the owner of the plan.
if ($artefacttask->owner == $USER->get('id')) {
if ($task->completed) {
$task->completed = 0;
$task->state = ($task->state == 1) ? 0 : -1; // Set state to not done (to do in future) vs not done (in past)
update_record('artefact_plans_task', $task, 'artefact');
}
else {
$task->completed = 1;
$task->state = 1;
update_record('artefact_plans_task', $task, 'artefact');
}
json_reply(false, (object) array('message' => false, 'data' => $task));
}
else {
json_reply(true, get_string('accessdenied', 'error'));
}
......@@ -22,6 +22,21 @@ $todelete = new ArtefactTypePlan($id);
if (!$USER->can_edit_artefact($todelete)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
$viewid = param_integer('view', 0);
if ($viewid) {
require_once('view.php');
$view = new View($viewid);
}
else {
$view = null;
}
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . '/artefact/plans/index.php';
}
$deleteform = array(
'name' => 'deleteplanform',
......@@ -34,7 +49,7 @@ $deleteform = array(
'type' => 'submitcancel',
'class' => 'btn-default',
'value' => array(get_string('deleteplan','artefact.plans'), get_string('cancel')),
'goto' => get_config('wwwroot') . '/artefact/plans/index.php',
'goto' => $returnurl,
),
)
);
......@@ -49,10 +64,18 @@ $smarty->display('artefact:plans:delete.tpl');
// calls this function first so that we can get the artefact and call delete on it
function deleteplanform_submit(Pieform $form, $values) {
global $SESSION, $todelete;
global $SESSION, $USER, $todelete, $view;
$todelete->delete();
$SESSION->add_ok_msg(get_string('plandeletedsuccessfully', 'artefact.plans'));
redirect('/artefact/plans/index.php');
// Redirect to view edit screen if plan was deleted from a block.
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . 'artefact/plans/index.php';
}
redirect($returnurl);
}
......@@ -22,6 +22,21 @@ $todelete = new ArtefactTypeTask($id);
if (!$USER->can_edit_artefact($todelete)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
$viewid = param_integer('view', 0);
if ($viewid) {
require_once('view.php');
$view = new View($viewid);
}
else {
$view = null;
}
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . '/artefact/plans/plan.php?id=' . $todelete->get('parent');
}
$deleteform = array(
'name' => 'deletetaskform',
......@@ -34,7 +49,7 @@ $deleteform = array(
'type' => 'submitcancel',
'class' => 'btn-default',
'value' => array(get_string('deletetask','artefact.plans'), get_string('cancel')),
'goto' => get_config('wwwroot') . '/artefact/plans/plan.php?id='.$todelete->get('parent'),
'goto' => $returnurl,
),
)
);
......@@ -49,10 +64,17 @@ $smarty->display('artefact:plans:delete.tpl');
// calls this function first so that we can get the artefact and call delete on it
function deletetaskform_submit(Pieform $form, $values) {
global $SESSION, $todelete;
global $SESSION, $todelete, $view, $USER;
$todelete->delete();
$SESSION->add_ok_msg(get_string('taskdeletedsuccessfully', 'artefact.plans'));
redirect('/artefact/plans/plan.php?id='.$todelete->get('parent'));
// Redirect to view edit screen if task was deleted from a block.
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . 'artefact/plans/plan.php?id=' . $todelete->get('parent');
}
redirect($returnurl);
}
......@@ -23,12 +23,18 @@ if (!PluginArtefactPlans::is_active()) {
define('TITLE', get_string('editplan','artefact.plans'));
$id = param_integer('id');
$viewid = param_integer('view', 0);
if ($viewid) {
require_once('view.php');
$view = new View($viewid);
}
else {
$view = null;
}
$artefact = new ArtefactTypePlan($id);
if (!$USER->can_edit_artefact($artefact)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
$editform = ArtefactTypePlan::get_form($artefact);
$smarty = smarty();
......
......@@ -28,6 +28,14 @@ $task = new ArtefactTypeTask($id);
if (!$USER->can_edit_artefact($task)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
$viewid = param_integer('view', 0);
if ($viewid) {
require_once('view.php');
$view = new View($viewid);
}
else {
$view = null;
}
$form = ArtefactTypeTask::get_form($task->get('parent'), $task);
......
......@@ -45,6 +45,8 @@ $string['youhavenplan'] = array(
);
/* Tasks */
$string['addtask'] = 'Add task';
$string['addtaskspecific'] = 'Add task to "%s"';
$string['alltasks'] = 'All tasks';
$string['canteditdontowntask'] = 'You cannot edit this task because you do not own it.';
$string['completed'] = 'Completed';
......@@ -57,6 +59,7 @@ $string['deletetask'] = 'Delete task';
$string['deletethistask'] = 'Delete task: \'%s\'';
$string['edittask'] = 'Edit task';
$string['editingtask'] = 'Editing task';
$string['editthistask'] = 'Edit task: \'%s\'';
$string['mytasks'] = 'My tasks';
$string['newtask'] = 'New task';
$string['notasks'] = 'No tasks to display.';
......
......@@ -159,7 +159,7 @@ class ArtefactTypePlan extends ArtefactType {
}
public static function submit(Pieform $form, $values) {
global $USER, $SESSION;
global $USER, $SESSION, $view;
$new = false;
......@@ -185,12 +185,17 @@ class ArtefactTypePlan extends ArtefactType {
$SESSION->add_ok_msg(get_string('plansavedsuccessfully', 'artefact.plans'));
if ($new) {
redirect('/artefact/plans/plan.php?id='.$artefact->get('id'));
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else if ($new) {
$returnurl = get_config('wwwroot') . 'artefact/plans/plan.php?id=' . $artefact->get('id');
}
else {
redirect('/artefact/plans/index.php');
$returnurl = get_config('wwwroot') . 'artefact/plans/index.php';
}
redirect($returnurl);
}
/**
......@@ -198,13 +203,22 @@ class ArtefactTypePlan extends ArtefactType {
*
*/
public static function get_form($plan=null) {
global $USER, $view;
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . 'artefact/plans/index.php';
}
require_once('license.php');
$elements = call_static_method(generate_artefact_class_name('plan'), 'get_planform_elements', $plan);
$elements['submit'] = array(
'type' => 'submitcancel',
'class' => 'btn-primary',
'value' => array(get_string('saveplan','artefact.plans'), get_string('cancel')),
'goto' => get_config('wwwroot') . 'artefact/plans/index.php',
'goto' => $returnurl,
);
$planform = array(
'name' => empty($plan) ? 'addplan' : 'editplan',
......@@ -279,11 +293,12 @@ class ArtefactTypePlan extends ArtefactType {
if (!empty($options['viewid'])) {
$baseurl .= '&view=' . $options['viewid'];
}
$baseurl .= '&planid=' . $this->id;
$pagination = array(
'baseurl' => $baseurl,
'id' => 'task_pagination',
'datatable' => 'tasktable',
'datatable' => 'tasklist',
'jsonscript' => 'artefact/plans/viewtasks.json.php',
);
......@@ -308,7 +323,6 @@ class ArtefactTypePlan extends ArtefactType {
$smarty->assign('view', (!empty($options['viewid']) ? $options['viewid'] : null));
$smarty->assign('owner', $this->get('owner'));
$smarty->assign('tags', $this->get('tags'));
return array('html' => $smarty->fetch('artefact:plans:viewplan.tpl'), 'javascript' => '');
}
......@@ -440,13 +454,22 @@ class ArtefactTypeTask extends ArtefactType {
*
*/
public static function get_form($parent, $task=null) {
global $USER, $view;
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . 'artefact/plans/plan.php?id=' . $parent;
}
require_once('license.php');
$elements = call_static_method(generate_artefact_class_name('task'), 'get_taskform_elements', $parent, $task);
$elements['submit'] = array(
'type' => 'submitcancel',
'class' => 'btn-primary',
'value' => array(get_string('savetask','artefact.plans'), get_string('cancel')),
'goto' => get_config('wwwroot') . 'artefact/plans/plan.php?id=' . $parent,
'goto' => $returnurl,
);
$taskform = array(
'name' => empty($task) ? 'addtasks' : 'edittask',
......@@ -545,7 +568,7 @@ class ArtefactTypeTask extends ArtefactType {
}
public static function submit(Pieform $form, $values) {
global $USER, $SESSION;
global $USER, $SESSION, $view;
if (!empty($values['task'])) {
$id = (int) $values['task'];
......@@ -571,7 +594,14 @@ class ArtefactTypeTask extends ArtefactType {
$SESSION->add_ok_msg(get_string('plansavedsuccessfully', 'artefact.plans'));
redirect('/artefact/plans/plan.php?id='.$values['parent']);
if ($view && $USER->can_edit_view($view)) {
$returnurl = get_config('wwwroot') . 'view/blocks.php?id=' . $view->get('id');
}
else {
$returnurl = get_config('wwwroot') . 'artefact/plans/plan.php?id=' . $values['parent'];
}
redirect($returnurl);
}
/**
......@@ -590,7 +620,7 @@ class ArtefactTypeTask extends ArtefactType {
FROM {artefact} a
JOIN {artefact_plans_task} at ON at.artefact = a.id
WHERE a.artefacttype = 'task' AND a.parent = ?
ORDER BY at.completiondate ASC, a.id", array($plan), $offset, $limit))
ORDER BY at.completed, at.completiondate ASC, a.id", array($plan), $offset, $limit))
|| ($results = array());
// format the date and setup completed for display if task is incomplete
......@@ -655,15 +685,28 @@ class ArtefactTypeTask extends ArtefactType {
* @param string $template The name of the template to use for rendering
* @param array $options The block instance options
* @param array $pagination The pagination data
* @param boolean $editing True if page is being edited
*
* @return array $tasks The tasks array updated with rendered table html
*/
public function render_tasks(&$tasks, $template, $options, $pagination) {
public function render_tasks(&$tasks, $template, $options, $pagination, $editing=false) {
global $USER;
$smarty = smarty_core();
$smarty->assign('tasks', $tasks);
$smarty->assign('options', $options);
$smarty->assign('view', (!empty($options['view']) ? $options['view'] : null));
$smarty->assign('block', (!empty($options['block']) ? $options['block'] : null));
$smarty->assign('editing', $editing);
if (!empty($options['view'])) {
require_once('view.php');
$view = new View($options['view']);
$owner = $view->get('owner');
if ($owner && $owner == $USER->get('id')) {
$smarty->assign('canedit', true);
}
}
$tasks['tablerows'] = $smarty->fetch($template);
if ($tasks['limit'] && $pagination) {
......
......@@ -20,7 +20,15 @@ if (!PluginArtefactPlans::is_active()) {
throw new AccessDeniedException(get_string('plugindisableduser', 'mahara', get_string('plans','artefact.plans')));
}
$id = param_integer('id',0);
$id = param_integer('id', 0);
$viewid = param_integer('view', 0);
if ($viewid) {
require_once('view.php');
$view = new View($viewid);
}
else {
$view = null;
}
if ($id) {
define('SECTION_PAGE', 'newtask');
$plan = new ArtefactTypePlan($id);
......
......@@ -10,6 +10,7 @@
*/
define('INTERNAL', 1);
define('PUBLIC', 1);
define('JSON', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
......@@ -19,24 +20,30 @@ require_once(get_config('docroot') . 'artefact/plans/blocktype/plans/lib.php');