Commit c788dcc0 authored by Maria Sorica's avatar Maria Sorica Committed by Robert Lyon
Browse files

Bug 1723961: Allow user to edit tasks from blocktype

1. Each tasks has an edit, delete icon group.
2. Tasks can be marked as complete from
the blocktype when the view is in edit mode.

behatnotneeded

Change-Id: If35431aa438802c3e299af05c84bf3c45cc8a8ac
parent 01e988c2
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,34 @@ 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(el, 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);
}
});
}
......@@ -48,7 +48,6 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
return array(
array(
'file' => 'js/plansblock.js',
'initjs' => "initNewPlansBlock($blockid);",
)
);
}
......
<?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,14 @@ $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;
}
$deleteform = array(
'name' => 'deletetaskform',
......@@ -49,10 +57,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);
}
......@@ -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);
......
......@@ -59,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.';
......
......@@ -293,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',
);
......@@ -322,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' => '');
}
......@@ -620,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
......@@ -685,16 +685,18 @@ 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) {
$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);
$tasks['tablerows'] = $smarty->fetch($template);
if ($tasks['limit'] && $pagination) {
......
......@@ -20,13 +20,16 @@ require_once(get_config('docroot') . 'artefact/plans/blocktype/plans/lib.php');
$offset = param_integer('offset', 0);
$limit = param_integer('limit', 10);
$editing = param_variable('editing', false);
$artefactid = param_integer('artefact', null);
$blockid = param_integer('block', null);
if ($blockid = param_integer('block', null)) {
if ($blockid && !$artefactid) {
$bi = new BlockInstance($blockid);
if (!can_view_view($bi->get('view'))) {
json_reply(true, get_string('accessdenied', 'error'));
}
$options = $configdata = $bi->get('configdata');
// If block sets limit use that instead
$limit = !empty($configdata['count']) ? $configdata['count'] : $limit;
$planid = param_integer('planid');
......@@ -56,11 +59,11 @@ else {
$pagination = array(
'baseurl' => $baseurl,
'id' => 'task_pagination',
'datatable' => 'tasktable',
'datatable' => 'tasklist',
'jsonscript' => 'artefact/plans/viewtasks.json.php',
);
}
ArtefactTypeTask::render_tasks($tasks, $template, $options, $pagination);
ArtefactTypeTask::render_tasks($tasks, $template, $options, $pagination, $editing);
json_reply(false, (object) array('message' => false, 'data' => $tasks));
......@@ -16,7 +16,9 @@
</a>
</div>
{/if}
<strong>{$plan.title}</strong>
{if count($plans) > 1}
<h4>{$plan.title}</h4>
{/if}
<p>{$plan.description}</p>
{if $plan.tags}
......@@ -35,7 +37,7 @@
<div id="plans_page_container_{$blockid}_plan{$tasks.planid}" class="hidden">
{$tasks.pagination|safe}
</div>
<script>
<script type="application/javascript">
jQuery(function($) {literal}{{/literal}
{$tasks.pagination_js|safe}
$('#plans_page_container_{$blockid}_plan{$tasks.planid}').removeClass('hidden');
......
{foreach from=$tasks.data item=task}
{if $task->completed == -1}
<div class="task-item plan_incomplete list-group-item {if $task->description || $task->tags}list-group-item-default{/if}">
{if $editing}
<div class="pull-right btn-group">
<a class="btn btn-default btn-sm" href="{$WWWROOT}artefact/plans/edit/task.php?id={$task->id}{if $view}&view={$view}{/if}" title="{str tag='editthistask' section='artefact.plans' arg1=$task->title}"><span class="icon icon-pencil text-default"></span></a>
<a class="btn btn-default btn-sm" href="{$WWWROOT}artefact/plans/delete/task.php?id={$task->id}{if $view}&view={$view}{/if}" title="{str tag='deletethistask' section='artefact.plans' arg1=$task->title}"><span class="icon icon-trash text-danger"></span></a>
</div>
{/if}
{if $task->description || $task->tags}<a class="link-block collapsed" href="#expand-task-{$task->id}{if $block}-{$block}{/if}" data-toggle="collapse" aria-expanded="false" aria-controls="expand-task-{$task->id}{if $block}-{$block}{/if}">{/if}
<span class="overdue-task">
<span class="icon icon-times text-danger icon-lg left" role="presentation" aria-hidden="true"></span>
<span class="icon icon-times text-danger icon-lg left task{$task->id}" role="presentation" aria-hidden="true" {if $editing}onclick="saveCheckBoxChange(this, '{$task->id}')"{/if}></span>
<span class="text-danger">{$task->title}</span> -
<span class="text-small text-midtone">
{str tag='completiondate' section='artefact.plans'}: {$task->completiondate}
......@@ -33,15 +37,19 @@
</div>
{else}
<div class="task-item list-group-item {if $task->description || $task->tags}list-group-item-default{/if}">
{if $editing}
<div class="pull-right btn-group">
<a class="btn btn-default btn-sm" href="{$WWWROOT}artefact/plans/edit/task.php?id={$task->id}{if $view}&view={$view}{/if}" title="{str tag='editthistask' section='artefact.plans' arg1=$task->title}"><span class="icon icon-pencil text-default"></span></a>
<a class="btn btn-default btn-sm" href="{$WWWROOT}artefact/plans/delete/task.php?id={$task->id}{if $view}&view={$view}{/if}" title="{str tag='deletethistask' section='artefact.plans' arg1=$task->title}"><span class="icon icon-trash text-danger"></span></a>
</div>
{/if}
{if $task->description || $task->tags}<a class="link-block collapsed" href="#expand-task-{$task->id}{if $block}-{$block}{/if}" data-toggle="collapse" aria-expanded="false" aria-controls="expand-task-{$task->id}{if $block}-{$block}{/if}">{/if}
<span class="complete-task">
{if $task->completed == 1}
<span class="icon icon-check-square-o icon-lg text-success left" role="presentation" aria-hidden="true"></span>
<span class="icon icon-check-square-o icon-lg text-success left task{$task->id}" role="presentation" aria-hidden="true" {if $editing}onclick="saveCheckBoxChange(this, '{$task->id}')"{/if}></span>
<span class="sr-only">{str tag=completed section=artefact.plans}</span>
{else}
<span class="icon-square-o icon icon-lg text-midtone left" role="presentation" aria-hidden="true"></span>
<span class="icon-square-o icon icon-lg text-midtone left task{$task->id}" role="presentation" aria-hidden="true" {if $editing}onclick="saveCheckBoxChange(this, '{$task->id}')"{/if}></span>
<span class="sr-only">{str tag=incomplete section=artefact.plans}</span>
{/if}
......
......@@ -8,7 +8,12 @@
<div id="plans_page_container">
{$tasks.pagination|safe}
</div>
<script type="application/javascript">
jQuery(function($) {literal}{{/literal}
{$tasks.pagination_js|safe}
$('#plans_page_container_{$blockid}_plan{$tasks.planid}').removeClass('hidden');
{literal}}{/literal});
</script>
{if $license}
<div class="license">
{$license|safe}
......
......@@ -14,7 +14,11 @@
.task-item .complete-task .icon,
.task-item .overdue-task .icon {
margin-left: -8px; //correct alignment
margin-left: -8px; // correct alignment
}
.task-item .btn-group {
margin-right: -8px; // correct alignment
}
.no-results {
......
Supports Markdown
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