diff --git a/config/zentaopms.php b/config/zentaopms.php index 04b1f89ca2..5f202f3f39 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -216,6 +216,7 @@ $config->openMethods[] = 'kanban.importexecution'; $config->openMethods[] = 'kanban.importbuild'; $config->openMethods[] = 'kanban.activatecard'; $config->openMethods[] = 'kanban.finishcard'; +$config->openMethods[] = 'kanban.deleteobjectcard'; /* Define the tables. */ define('TABLE_COMPANY', '`' . $config->db->prefix . 'company`'); diff --git a/module/bug/control.php b/module/bug/control.php index 3844061cd9..b8dc031971 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -1864,6 +1864,16 @@ class bug extends control if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess)); + if($this->app->tab == 'execution') + { + $execution = $this->loadModel('execution')->getByID($bug->execution); + if($execution->type == 'kanban') + { + $locateLink = $this->createLink("execution", "kanban", "executionID={$bug->execution}"); + return print(js::locate($locateLink, 'parent.parent')); + } + } + $locateLink = $this->session->bugList ? $this->session->bugList : inlink('browse', "productID={$bug->product}"); return print(js::locate($locateLink, 'parent')); } diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index 62f68d60af..45efbbbd1f 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -117,7 +117,7 @@ { common::printIcon('bug', 'create', $copyParams, $bug, 'button', 'copy'); } - common::printIcon('bug', 'delete', $params, $bug, 'button', 'trash', 'hiddenwin'); + common::printIcon('bug', 'delete', $params, $bug, 'button', 'trash', 'hiddenwin', 'showinonlybody'); ?> diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 4a5d8f3740..7c6e707a2c 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -548,7 +548,7 @@ function renderBugItem(item, $item, col) if(scaleSize <= 1) { var $actions = $item.find('.actions'); - if(!$actions.length && (priv.canEditBug || priv.canResolveBug || priv.canConfirmBug || priv.canCopyBug || priv.canToStoryBug)) + if(!$actions.length && (priv.canEditBug || priv.canResolveBug || priv.canConfirmBug || priv.canCopyBug || priv.canToStoryBug || priv.canDeleteBug)) { $actions = $([ '
', @@ -969,6 +969,35 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car modalTrigger.show(); } } +/** + * Delete a card. + * + * @param string objectType + * @param int objectID + * @param int regionID + * @access public + * @return void + */ +function deleteCard(objectType, objectID, regionID) +{ + var objectLang = objectType + 'Lang'; + var result = confirm(window[objectLang].confirmDelete) ? true : false; + + if(!result) return false; + if(!objectID) return false; + + var url = createLink('kanban', 'deleteObjectCard', 'objectType=' + objectType + '&objectID=' + objectID + '®ionID=' + regionID); + return $.ajax( + { + method: 'post', + dataType: 'json', + url: url, + success: function(data) + { + updateRegion(regionID, data[regionID]); + } + }); +} /** * Close modal and update kanban data. @@ -1070,6 +1099,7 @@ function createStoryMenu(options) if(priv.canBatchCreateTask && showAction) items.push({label: executionLang.batchWBS, icon: 'pluses', url: createLink('task', 'batchCreate', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canActivateStory && story.$col.type == 'closed') items.push({label: executionLang.activate, icon: 'magic', url: createLink('story', 'activate', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canUnlinkStory) items.push({label: executionLang.unlinkStory, icon: 'unlink', url: createLink('execution', 'unlinkStory', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'false'), attrs: {target: 'hiddenwin'}}); + if(priv.canDeleteStory) items.push({label: storyLang.delete, icon: 'trash', onClick: function(){deleteCard('story', story.id, story.$lane.region)}}); return items; } @@ -1090,6 +1120,7 @@ function createTaskMenu(options) if(priv.canActivateTask && (task.$col.type == 'developed' || task.$col.type == 'canceled' || task.$col.type == 'closed')) items.push({label: executionLang.activate, icon: 'magic', url: createLink('task', 'activate', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canCreateTask) items.push({label: taskLang.copy, icon: 'copy', url: createLink('task', 'create', 'executionID=' + executionID + '&storyID=' + '0' + '&moduleID=' + '0' + '&taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canCancelTask && (task.$col.type == 'wait' || task.$col.type == 'developing' || task.$col.type == 'pause')) items.push({label: taskLang.cancel, icon: 'cancel', url: createLink('task', 'cancel', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canDeleteTask) items.push({label: taskLang.delete, icon: 'trash', onClick: function(){deleteCard('task', task.id, task.$lane.region)}}); return items; } @@ -1109,6 +1140,7 @@ function createBugMenu(options) if(priv.canCopyBug) items.push({label: bugLang.copy, icon: 'copy', url: createLink('bug', 'create', 'productID=' + productID + '&branch=' + '' + '&extras=bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canToStoryBug && (bug.$col.type != 'closed')) items.push({label: bugLang.toStory, icon: 'lightbulb', url: createLink('story', 'create', 'product=' + productID + '&branch=' + '0' + '&module=' + '0' + '&story=' + '0' + '&execution=' + '0' + '&bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canActivateBug && (bug.$col.type == 'fixed') || bug.$col.type == 'testing' || bug.$col.type == 'tested' || bug.$col.type == 'closed') items.push({label: bugLang.activate, icon: 'magic', url: createLink('bug', 'activate', 'bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canDeleteBug) items.push({label: bugLang.delete, icon: 'trash', onClick: function(){deleteCard('bug', bug.id, bug.$lane.region)}}); return items; } diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index cc5d7bbb0d..b24108db0e 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -85,6 +85,7 @@ js::set('priv', 'canResolveBug' => common::hasPriv('bug', 'resolve'), 'canCopyBug' => common::hasPriv('bug', 'create'), 'canEditBug' => common::hasPriv('bug', 'edit'), + 'canDeleteBug' => common::hasPriv('bug', 'delete'), 'canActivateBug' => common::hasPriv('bug', 'activate'), 'canAssignTask' => common::hasPriv('task', 'assignto'), 'canFinishTask' => common::hasPriv('task', 'finish'), @@ -96,10 +97,12 @@ js::set('priv', 'canStartTask' => common::hasPriv('task', 'start'), 'canRestartTask' => common::hasPriv('task', 'restart'), 'canEditTask' => common::hasPriv('task', 'edit'), + 'canDeleteTask' => common::hasPriv('task', 'delete'), 'canRecordEstimateTask' => common::hasPriv('task', 'recordEstimate'), 'canToStoryBug' => common::hasPriv('story', 'create'), 'canAssignStory' => common::hasPriv('story', 'assignto'), 'canEditStory' => common::hasPriv('story', 'edit'), + 'canDeleteStory' => common::hasPriv('story', 'delete'), 'canChangeStory' => common::hasPriv('story', 'change'), 'canUnlinkStory' => common::hasPriv('execution', 'unlinkStory'), ) diff --git a/module/kanban/control.php b/module/kanban/control.php index a8d23ab49b..55e64fb918 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -1380,6 +1380,28 @@ class kanban extends control } } + /** + * Delete a card. + * + * @param string $objectType story|task|bug + * @param int $objectID + * @param int $regionID + * @access public + * @return void + */ + public function deleteObjectCard($objectType, $objectID, $regionID) + { + if(!($objectType == 'task' or $objectType == 'story' or $objectType == 'bug')) return false; + $table = 'TABLE_' . strtoupper($objectType); + $this->loadModel($objectType)->delete(constant($table), $objectID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + $kanbanID = $this->kanban->getKanbanIDByregion($regionID); + $kanbanGroup = $this->kanban->getRDKanban($kanbanID); + + return print(json_encode($kanbanGroup)); + } + /** * Set WIP. * diff --git a/module/kanban/model.php b/module/kanban/model.php index b2fec43d2c..d11fc61feb 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -888,6 +888,18 @@ class kanbanModel extends model ->fetchPairs(); } + /** + * Get kanban id by region id. + * + * @param int $regionID + * @access public + * @return int + */ + public function getKanbanIDByRegion($regionID) + { + return $this->dao->select('kanban')->from(TABLE_KANBANREGION)->where('id')->eq($regionID)->fetch('kanban'); + } + /** * Get kanban group by regions. * diff --git a/module/story/control.php b/module/story/control.php index 691333d69a..36c3037388 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -1177,6 +1177,14 @@ class story extends control $this->executeHooks($storyID); if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success')); + if($this->app->tab == 'execution') + { + $execution = $this->loadModel('execution')->getByID(key($story->executions)); + if($execution->type == 'kanban') + { + return print(js::reload('parent.parent')); + } + } $locateLink = $this->session->storyList ? $this->session->storyList : $this->createLink('product', 'browse', "productID={$story->product}"); return print(js::locate($locateLink, 'parent')); diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index ab0cdd413f..608e3c5b45 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -244,7 +244,7 @@ echo "
"; common::printIcon('story', 'edit', "storyID=$story->id", $story); common::printIcon('story', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id&executionID=0&bugID=0&planID=0&todoID=0&extra=&type=$story->type", $story, 'button', 'copy', '', '', '', "data-width='1050'"); - common::printIcon('story', 'delete', "storyID=$story->id", $story, 'button', 'trash', 'hiddenwin'); + common::printIcon('story', 'delete', "storyID=$story->id", $story, 'button', 'trash', 'hiddenwin', 'showinonlybody',true); ?>
diff --git a/module/task/control.php b/module/task/control.php index 3a077b1610..6aaa7d46bf 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -1583,6 +1583,14 @@ class task extends control if($task->story) $this->loadModel('story')->setStage($task->story); $this->executeHooks($taskID); + if($this->app->tab == 'execution') + { + $execution = $this->loadModel('execution')->getByID($task->execution); + if($execution->type == 'kanban') + { + return print(js::reload('parent.parent')); + } + } $locateLink = $this->session->taskList ? $this->session->taskList : $this->createLink('execution', 'task', "executionID={$task->execution}"); return print(js::locate($locateLink, 'parent')); diff --git a/module/task/view/view.html.php b/module/task/view/view.html.php index 495e9739f3..b3b99dd751 100644 --- a/module/task/view/view.html.php +++ b/module/task/view/view.html.php @@ -187,7 +187,7 @@ if(!isonlybody()) echo "
"; common::printIcon('task', 'edit', "taskID=$task->id", $task, 'button', '', '', 'showinonlybody'); common::printIcon('task', 'create', "projctID={$task->execution}&storyID=0&moduleID=0&taskID=$task->id", $task, 'button', 'copy'); - common::printIcon('task', 'delete', "executionID=$task->execution&taskID=$task->id", $task, 'button', 'trash', 'hiddenwin'); + common::printIcon('task', 'delete', "executionID=$task->execution&taskID=$task->id", $task, 'button', 'trash', 'hiddenwin', 'showinonlybody', true); if($task->parent > 0) echo html::a(helper::createLink('task', 'view', "taskID=$task->parent"), "", '', "class='btn btn-link' title='{$lang->task->parent}'"); ?>