diff --git a/module/bug/control.php b/module/bug/control.php index a21a6a0898..6245d24d50 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -322,6 +322,21 @@ class bug extends control if($this->app->tab == 'execution') { if(isset($output['executionID'])) $this->loadModel('execution')->setMenu($output['executionID']); + $execution = $this->dao->findById((int)$output['executionID'])->from(TABLE_EXECUTION)->fetch(); + if($execution->type == 'kanban') + { + $this->loadModel('kanban'); + $regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'bug'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->executionType = $execution->type; + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } } else if($this->app->tab == 'project') { @@ -662,6 +677,9 @@ class bug extends control */ public function batchCreate($productID, $branch = '', $executionID = 0, $moduleID = 0, $extra = '') { + $extra = str_replace(array(',', ' '), array('&', ''), $extra); + parse_str($extra, $output); + if(!empty($_POST)) { $actions = $this->bug->batchCreate($productID, $branch, $extra); @@ -675,9 +693,6 @@ class bug extends control setcookie('bugModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false); - $extra = str_replace(array(',', ' '), array('&', ''), $extra); - parse_str($extra, $output); - /* If link from no head then reload. */ if(isonlybody() and $executionID) { @@ -709,6 +724,20 @@ class bug extends control $builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty', $executionID, 'execution'); $stories = $this->story->getExecutionStoryPairs($executionID); $execution = $this->loadModel('execution')->getById($executionID); + if($execution->type == 'kanban') + { + $this->loadModel('kanban'); + $regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'bug'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->executionType = $execution->type; + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } } else { diff --git a/module/bug/js/batchcreate.js b/module/bug/js/batchcreate.js index 107911a375..e2b1645d6b 100644 --- a/module/bug/js/batchcreate.js +++ b/module/bug/js/batchcreate.js @@ -38,6 +38,27 @@ function setOpenedBuilds(link, index) }); } +/** + * Set lane. + * + * @param int $regionID + * @param int $num + * @access public + * @return void + */ +function setLane(regionID, num) +{ + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=bug&field=lanes&i=' + num); + $.get(laneLink, function(lanes) + { + if(!lanes) lanes = ''; + $('#lanes' + num).replaceWith(lanes); + $("#lanes" + num + "_chosen").remove(); + $("#lanes" + num).next('.picker').remove(); + $("#lanes" + num).chosen(); + }); +} + /** * Load execution builds * diff --git a/module/bug/js/create.js b/module/bug/js/create.js index 710b877545..2ef4daab45 100644 --- a/module/bug/js/create.js +++ b/module/bug/js/create.js @@ -54,6 +54,27 @@ function loadModuleRelated() setStories(moduleID, productID, storyID); } +/** + * Set lane. + * + * @param int $regionID + * @access public + * @return void + */ +function setLane(regionID) +{ + console.log(regionID); + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=bug&field=lane'); + $.get(laneLink, function(lane) + { + if(!lane) lane = ""; + $('#lane').replaceWith(lane); + $("#lane" + "_chosen").remove(); + $("#lane").next('.picker').remove(); + $("#lane").chosen(); + }); +} + /** * Set the assignedTo field. * diff --git a/module/bug/model.php b/module/bug/model.php index f021f4c71d..eede076e6e 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -76,7 +76,7 @@ class bugModel extends model ->trim('title') ->join('openedBuild', ',') ->join('mailto', ',') - ->remove('files, labels,uid,oldTaskID,contactListMenu') + ->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane') ->get(); if($bug->execution != 0) $bug->project = $this->dao->select('parent')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('parent'); @@ -107,8 +107,15 @@ class bugModel extends model if($bug->execution) { $this->loadModel('kanban'); - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($bug->execution, $output['laneID'], $output['columnID'], 'bug', $bugID); - if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($bug->execution, 'bug'); + + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(!empty($_POST['lane'])) $laneID = $_POST['lane']; + + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'unconfirmed'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($bug->execution, $laneID, $columnID, 'bug', $bugID); + if(empty($laneID) or empty($columnID)) $this->kanban->updateLane($bug->execution, 'bug'); } /* Callback the callable method to process the related data for object that is transfered to bug. */ @@ -201,6 +208,8 @@ class bugModel extends model $bug->browser = $data->browsers[$i]; $bug->keywords = $data->keywords[$i]; + if(isset($data->lanes[$i])) $bug->laneID = $data->lanes[$i]; + if($bug->execution != 0) $bug->project = $this->dao->select('parent')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('parent'); /* Assign the bug to the person in charge of the module. */ @@ -236,6 +245,13 @@ class bugModel extends model /* When the bug is created by uploading an image, add the image to the step of the bug. */ foreach($bugs as $i => $bug) { + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(isset($bug->laneID)) + { + $laneID = $bug->laneID; + unset($bug->laneID); + } + if(!empty($data->uploadImage[$i])) { $fileName = $data->uploadImage[$i]; @@ -274,8 +290,11 @@ class bugModel extends model if($bug->execution) { - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($bug->execution, $output['laneID'], $output['columnID'], 'bug', $bugID); - if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($bug->execution, 'bug'); + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'unconfirmed'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($bug->execution, $laneID, $columnID, 'bug', $bugID); + if(empty($laneID) or empty($columnID)) $this->kanban->updateLane($bug->execution, 'bug'); } /* When the bug is created by uploading the image, add the image to the file of the bug. */ @@ -290,7 +309,7 @@ class bugModel extends model unset($file); } - if(dao::isError()) return print(js::error('bug#' . ($i+1) . dao::getError(true))); + if(dao::isError()) return print(js::error('bug#' . ($i) . dao::getError(true))); $actions[$bugID] = $this->action->create('bug', $bugID, 'Opened'); } diff --git a/module/bug/view/batchcreate.html.php b/module/bug/view/batchcreate.html.php index 4d1154905b..5e412be2fa 100644 --- a/module/bug/view/batchcreate.html.php +++ b/module/bug/view/batchcreate.html.php @@ -51,6 +51,10 @@ '>model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->execution;?> bug->openedBuild;?> bug->title;?> + + kanbancard->region;?> + kanbancard->lane;?> + '>bug->deadline;?> '>bug->steps;?> '>typeAB;?> @@ -74,19 +78,19 @@ $lang->bug->osList += array('ditto' => $lang->bug->ditto); $lang->bug->browserList += array('ditto' => $lang->bug->ditto); ?> - + $fileName):?> - + ' style='overflow:visible'> ' style='overflow:visible'> @@ -105,6 +109,10 @@ + + + + '> '> ' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> @@ -119,7 +127,7 @@ - bug->batchCreate; $i++):?> + bug->batchCreate; $i++):?> - + ' style='overflow:visible'> ' style='overflow:visible'> @@ -148,6 +156,10 @@ + + + + '> '> ' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> diff --git a/module/bug/view/create.html.php b/module/bug/view/create.html.php index c33c1a9f2a..def2c34a4b 100644 --- a/module/bug/view/create.html.php +++ b/module/bug/view/create.html.php @@ -197,6 +197,18 @@ if($this->app->tab == 'project') js::set('objectID', $projectID); + + + kanbancard->region;?> + + +
+
kanbancard->lane;?>
+ +
+ + + bug->title;?> diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 5387fc1f5a..40a802e27e 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -265,31 +265,32 @@ function createColumnMenu(options) */ function createColumnCreateMenu(options) { - var $col = options.$trigger.closest('.kanban-col'); - var col = $col.data('col'); - var items = []; - var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0; + var $col = options.$trigger.closest('.kanban-col'); + var col = $col.data('col'); + var items = []; + var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0; + var regionID = col.$kanbanData.region; if(col.type == 'backlog') { - if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&objectID=' + executionID + '&bugID=0&planID=0&todoID=0&extra=laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); - if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStory, url: productCount > 1 ? '#batchCreateStory' : $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID + '&plan=0&type=story&extra=laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe',attrs: {'data-toggle': 'modal', 'data-width': '90%'}}); + if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&objectID=' + executionID + '&bugID=0&planID=0&todoID=0&extra=regionID=' + regionID + ',laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStory, url: productCount > 1 ? '#batchCreateStory' : $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID + '&plan=0&type=story&extra=regionID=' + regionID + ',laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe',attrs: {'data-toggle': 'modal', 'data-width': '90%'}}); if(priv.canLinkStory) items.push({label: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID + '&browseType=¶m=0&recTotal=0&recPerPage=50,&pageID=1&extra=laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '90%'}}); if(priv.canLinkStoryByPlan) items.push({label: executionLang.linkStoryByPlan, url: '#linkStoryByPlan', 'attrs' : {'data-toggle': 'modal', 'data-target': '#linkStoryByPlan','data-col' : col.id, 'data-lane' : laneID, 'class' : 'linkStoryByPlanButton'}}); } else if(col.type == 'unconfirmed') { - if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=laneID=' + laneID + ',columnID=' + col.id + ',executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=regionID=' + regionID + ',laneID=' + laneID + ',columnID=' + col.id + ',executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canBatchCreateBug) { if(productNum > 1) items.push({label: bugLang.batchCreate, url: '#batchCreateBug', 'attrs' : {'data-toggle': 'modal'}}); - else items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&branch=&executionID=' + executionID + '&module=0&extra=&laneID=' + laneID + '&columnID=' + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '90%'}}); + else items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&branch=&executionID=' + executionID + '&module=0&extra=regionID=' + regionID + ',laneID=' + laneID + ',columnID=' + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '90%'}}); } } else if(col.type == 'wait') { - if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); - if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&iframe=0&extra=laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=regionID=" + regionID + ",laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); + if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&iframe=0&extra=regionID=" + regionID + ",laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); if(priv.canImportBug && vision == 'rnd') items.push({label: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}}); } return items; diff --git a/module/execution/model.php b/module/execution/model.php index 3c6ad82e4d..3a206b53ab 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -2269,11 +2269,12 @@ class executionModel extends model * @param array $stories * @param array $products * @param string $extra + * @param array $lanes * * @access public * @return bool */ - public function linkStory($executionID, $stories = array(), $products = array(), $extra = '') + public function linkStory($executionID, $stories = array(), $products = array(), $extra = '', $lanes = array()) { if(empty($executionID)) return false; if(empty($stories)) $stories = $this->post->stories; @@ -2296,7 +2297,13 @@ class executionModel extends model if(strpos($notAllowedStatus, $storyList[$storyID]->status) !== false) continue; if(isset($linkedStories[$storyID])) continue; - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($executionID, $output['laneID'], $output['columnID'], 'story', $storyID); + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(!empty($lanes[$storyID])) $laneID = $lanes[$storyID]; + + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'backlog'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($executionID, $laneID, $columnID, 'story', $storyID); $data = new stdclass(); $data->project = $executionID; diff --git a/module/kanban/lang/en.php b/module/kanban/lang/en.php index 117c5f2d0d..be872062b8 100644 --- a/module/kanban/lang/en.php +++ b/module/kanban/lang/en.php @@ -333,6 +333,7 @@ $lang->kanbancard->name = 'Card Name'; $lang->kanbancard->legendBasicInfo = 'Basic Info'; $lang->kanbancard->legendLifeTime = 'Card Life'; $lang->kanbancard->space = 'Space'; +$lang->kanbancard->region = 'Region'; $lang->kanbancard->kanban = 'Kanban'; $lang->kanbancard->lane = 'Lane'; $lang->kanbancard->column = 'Column'; diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php index c2e491c1a0..3d25bcfa96 100644 --- a/module/kanban/lang/zh-cn.php +++ b/module/kanban/lang/zh-cn.php @@ -333,6 +333,7 @@ $lang->kanbancard->name = '卡片名称'; $lang->kanbancard->legendBasicInfo = '基本信息'; $lang->kanbancard->legendLifeTime = '卡片的一生'; $lang->kanbancard->space = '所属空间'; +$lang->kanbancard->region = '所属区域'; $lang->kanbancard->kanban = '所属看板'; $lang->kanbancard->lane = '所属泳道'; $lang->kanbancard->column = '所属看板列'; diff --git a/module/kanban/lang/zh-tw.php b/module/kanban/lang/zh-tw.php index b9d45101bc..4606239b55 100644 --- a/module/kanban/lang/zh-tw.php +++ b/module/kanban/lang/zh-tw.php @@ -267,6 +267,7 @@ $lang->kanbancard->name = '卡片名稱'; $lang->kanbancard->legendBasicInfo = '基本信息'; $lang->kanbancard->legendLifeTime = '卡片的一生'; $lang->kanbancard->space = '所屬空間'; +$lang->kanbancard->region = '所屬區域'; $lang->kanbancard->kanban = '所屬看板'; $lang->kanbancard->lane = '所屬泳道'; $lang->kanbancard->column = '所屬看板列'; diff --git a/module/kanban/model.php b/module/kanban/model.php index 65072b4b6f..2175a4abaa 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1838,8 +1838,8 @@ class kanbanModel extends model /** * Get lane pairs by region id. * - * @param array $regionID - * @param string $type all|story|task|bug|common + * @param array|int $regionID + * @param string $type all|story|task|bug|common * @access public * @return array */ @@ -3296,6 +3296,23 @@ class kanbanModel extends model ->fetchAll('id'); } + /** + * Get column ID by lane ID. + * + * @param int $laneID + * @param string $columnType + * @access public + * @return int + */ + public function getColumnIDByLaneID($laneID, $columnType) + { + return $this->dao->select('t1.column')->from(TABLE_KANBANCELL)->alias('t1') + ->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.column = t2.id') + ->where('t1.lane')->eq($laneID) + ->andWhere('t2.type')->eq($columnType) + ->fetch('column'); + } + /** * Get lane by id. * diff --git a/module/story/control.php b/module/story/control.php index 5565e779ad..7dece2cbe1 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -46,6 +46,10 @@ class story extends control */ public function create($productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $objectID = 0, $bugID = 0, $planID = 0, $todoID = 0, $extra = '', $type = 'story') { + /* Whether there is a object to transfer story, for example feedback. */ + $extra = str_replace(array(',', ' '), array('&', ''), $extra); + parse_str($extra, $output); + if($productID == 0 and $objectID == 0) $this->locate($this->createLink('product', 'create')); $this->story->replaceURLang($type); @@ -64,11 +68,23 @@ class story extends control { $objectID = empty($objectID) ? $this->session->execution : $objectID; $this->execution->setMenu($objectID); + $execution = $this->dao->findById((int)$objectID)->from(TABLE_EXECUTION)->fetch(); + if($execution->type == 'kanban') + { + $this->loadModel('kanban'); + $regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'story'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->executionType = $execution->type; + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } } - /* Whether there is a object to transfer story, for example feedback. */ - $extra = str_replace(array(',', ' '), array('&', ''), $extra); - parse_str($extra, $output); foreach($output as $paramKey => $paramValue) { if(isset($this->config->story->fromObjects[$paramKey])) @@ -394,6 +410,20 @@ class story extends control } else { + if($execution->type == 'kanban') + { + $this->loadModel('kanban'); + $regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'story'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } + $this->execution->setMenu($executionID); $this->app->rawModule = 'execution'; $this->lang->navGroup->story = 'execution'; @@ -426,12 +456,18 @@ class story extends control $stories = array(); foreach($mails as $mail) $stories[] = $mail->storyID; + $lanes = array(); + if(isset($_POST['lanes'])) + { + foreach($mails as $i => $mail) $lanes[$mail->storyID] = $_POST['lanes'][$i]; + } + /* Project or execution linked stories. */ if($executionID) { $products = array(); foreach($mails as $story) $products[$story->storyID] = $productID; - $this->execution->linkStory($executionID, $stories, $products, $extra); + $this->execution->linkStory($executionID, $stories, $products, $extra, $lanes); if($executionID != $this->session->project) $this->execution->linkStory($this->session->project, $stories, $products); } diff --git a/module/story/js/batchcreate.js b/module/story/js/batchcreate.js index 403e82113d..5660e14ee6 100644 --- a/module/story/js/batchcreate.js +++ b/module/story/js/batchcreate.js @@ -115,3 +115,24 @@ function toggleCheck(obj) $ditto.closest('.input-group-addon').hide(); } } + +/** + * Set lane. + * + * @param int $regionID + * @param int $num + * @access public + * @return void + */ +function setLane(regionID, num) +{ + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=story&field=lanes&i=' + num); + $.get(laneLink, function(lanes) + { + if(!lanes) lanes = ''; + $('#lanes' + num).replaceWith(lanes); + $("#lanes" + num + "_chosen").remove(); + $("#lanes" + num).next('.picker').remove(); + $("#lanes" + num).chosen(); + }); +} diff --git a/module/story/js/create.js b/module/story/js/create.js index 26b48b29d0..f164649ed0 100644 --- a/module/story/js/create.js +++ b/module/story/js/create.js @@ -48,6 +48,26 @@ function refreshPlan() $('a.refresh').click(); } +/** + * Set lane. + * + * @param int $regionID + * @access public + * @return void + */ +function setLane(regionID) +{ + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=story&field=lane'); + $.get(laneLink, function(lane) + { + if(!lane) lane = ""; + $('#lane').replaceWith(lane); + $('#lane' + "_chosen").remove(); + $('#lane').next('.picker').remove(); + $('#lane').chosen(); + }); +} + $(window).unload(function(){ if(blockID) window.parent.refreshBlock($('#block' + blockID)); }); diff --git a/module/story/model.php b/module/story/model.php index db7d6c0190..71772259f9 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -217,7 +217,7 @@ class storyModel extends model ->setIF($bugID > 0, 'fromBug', $bugID) ->join('mailto', ',') ->stripTags($this->config->story->editor->create['id'], $this->config->allowedTags) - ->remove('files,labels,reviewer,needNotReview,newStory,uid,contactListMenu,URS') + ->remove('files,labels,reviewer,needNotReview,newStory,uid,contactListMenu,URS,region,lane') ->get(); /* Check repeat story. */ @@ -286,8 +286,15 @@ class storyModel extends model if($this->config->systemMode == 'new' and $executionID != $this->session->project) $this->linkStory($this->session->project, $this->post->product, $storyID); $this->loadModel('kanban'); - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($executionID, $output['laneID'], $output['columnID'], 'story', $storyID); - if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($executionID, 'story'); + + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(isset($_POST['lane'])) $laneID = $_POST['lane']; + + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'backlog'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($executionID, $laneID, $columnID, 'story', $storyID); + if(empty($laneID) or empty($columnID)) $this->kanban->updateLane($executionID, 'story'); } if(is_array($this->post->URS)) diff --git a/module/story/view/batchcreate.html.php b/module/story/view/batchcreate.html.php index 945931e514..61d35f5d4b 100644 --- a/module/story/view/batchcreate.html.php +++ b/module/story/view/batchcreate.html.php @@ -48,6 +48,10 @@ '>story->plan;?> + type == 'kanban'):?> + kanbancard->region;?> + kanbancard->lane;?> + story->title;?> '>story->spec;?> '>story->source;?> @@ -71,6 +75,10 @@ ' style='overflow:visible'> + type == 'kanban'):?> + + +
@@ -125,15 +133,16 @@ $(function() $('#batchCreateForm').batchActionForm( { - idEnd: , + idStart: 1, + idEnd: , rowCreator: function($row, index) { $row.find('select.chosen,select.picker-select').each(function() { var $select = $(this); if($select.hasClass('picker-select')) $select.parent().find('.picker').remove(); - if(index == 0) $select.find("option[value='ditto']").remove(); - if(index > 0) $select.val('ditto'); + if(index == 1) $select.find("option[value='ditto']").remove(); + if(index > 1) $select.val('ditto'); if($select.attr('id').indexOf('branch') >= 0) $select.val('') $select.chosen(); setTimeout(function() diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php index 664459953f..031493edbd 100644 --- a/module/story/view/create.html.php +++ b/module/story/view/create.html.php @@ -155,9 +155,9 @@
story->parent;?>
-
+
- + story->parent;?> @@ -165,6 +165,18 @@ + + + kanbancard->region;?> + + +
+
kanbancard->lane;?>
+ +
+ + + story->title;?> diff --git a/module/task/control.php b/module/task/control.php index 77806ca7e0..6d9b4b1277 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -86,6 +86,20 @@ class task extends control $execution = $this->execution->getById($executionID); $taskLink = $this->createLink('execution', 'browse', "executionID=$executionID&tab=task"); + $this->loadModel('kanban'); + if($execution->type == 'kanban') + { + $regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'task'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } + /* Set menu. */ $this->execution->setMenu($execution->id); @@ -129,11 +143,19 @@ class task extends control $this->action->create('task', $taskID, 'Opened', ''); } - $this->loadModel('kanban'); + /* Create task in kanban. */ $kanbanID = $execution->type == 'kanban' ? $executionID : $_POST['execution']; - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($kanbanID, $output['laneID'], $output['columnID'], 'task', $taskID); - if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($kanbanID, 'task'); + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(!empty($_POST['lane'])) $laneID = $_POST['lane']; + + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'wait'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($kanbanID, $laneID, $columnID, 'task', $taskID); + if(empty($laneID) or empty($columnID)) $this->kanban->updateLane($kanbanID, 'task'); + + /* To do status. */ if($todoID > 0) { $this->dao->update(TABLE_TODO)->set('status')->eq('done')->where('id')->eq($todoID)->exec(); @@ -363,6 +385,23 @@ class task extends control $showAllModule = isset($this->config->execution->task->allModule) ? $this->config->execution->task->allModule : ''; $modules = $this->loadModel('tree')->getTaskOptionMenu($executionID, 0, 0, $showAllModule ? 'allModule' : ''); + if($execution->type == 'kanban') + { + $extra = str_replace(array(',', ' '), array('&', ''), $extra); + parse_str($extra, $output); + + $this->loadModel('kanban'); + $regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution'); + $regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs); + $lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'task'); + $laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs); + + $this->view->regionID = $regionID; + $this->view->laneID = $laneID; + $this->view->regionPairs = $regionPairs; + $this->view->lanePairs = $lanePairs; + } + $title = $execution->name . $this->lang->colon . $this->lang->task->batchCreate; $position[] = html::a($taskLink, $execution->name); $position[] = $this->lang->task->common; diff --git a/module/task/js/batchcreate.js b/module/task/js/batchcreate.js index 1c4416ea19..1d7c70c856 100755 --- a/module/task/js/batchcreate.js +++ b/module/task/js/batchcreate.js @@ -184,6 +184,27 @@ function markStoryTask() }); } +/** + * Set lane. + * + * @param int $regionID + * @param int $num + * @access public + * @return void + */ +function setLane(regionID, num) +{ + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=task&field=lanes&i=' + num); + $.get(laneLink, function(lanes) + { + if(!lanes) lanes = ''; + $('#lanes' + num).replaceWith(lanes); + $("#lanes" + num + "_chosen").remove(); + $("#lanes" + num).next('.picker').remove(); + $("#lanes" + num).chosen(); + }); +} + $(document).on('chosen:showing_dropdown', 'select[name^="story"],.chosen-with-drop', function() { var select = $(this).closest('td').find('select'); diff --git a/module/task/js/create.js b/module/task/js/create.js index 94edf7d8c6..e92db596cf 100644 --- a/module/task/js/create.js +++ b/module/task/js/create.js @@ -270,6 +270,26 @@ function loadModuleRelated() setStories(moduleID, executionID); } +/** + * Set lane. + * + * @param int $regionID + * @access public + * @return void + */ +function setLane(regionID) +{ + laneLink = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=task&field=lane'); + $.get(laneLink, function(lane) + { + if(!lane) lane = ""; + $('#lane').replaceWith(lane); + $("#lane" + "_chosen").remove(); + $("#lane").next('.picker').remove(); + $("#lane").chosen(); + }); +} + /* Get select of stories.*/ function setStories(moduleID, executionID) { diff --git a/module/task/model.php b/module/task/model.php index 9aab48e3b9..24904c4c58 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -64,7 +64,7 @@ class taskModel extends model ->cleanINT('execution,story,module') ->stripTags($this->config->task->editor->create['id'], $this->config->allowedTags) ->join('mailto', ',') - ->remove('after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams,contactListMenu,selectTestStory,testStory,testPri,testEstStarted,testDeadline,testAssignedTo,testEstimate,sync,otherLane,region') + ->remove('after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams,contactListMenu,selectTestStory,testStory,testPri,testEstStarted,testDeadline,testAssignedTo,testEstimate,sync,otherLane,region,lane') ->add('version', 1) ->get(); @@ -331,6 +331,7 @@ class taskModel extends model if($assignedTo) $data[$i]->assignedDate = $now; if(strpos($this->config->task->create->requiredFields, 'estStarted') !== false and empty($estStarted)) $data[$i]->estStarted = ''; if(strpos($this->config->task->create->requiredFields, 'deadline') !== false and empty($deadline)) $data[$i]->deadline = ''; + if(isset($tasks->lanes[$i])) $data[$i]->laneID = $tasks->lanes[$i]; foreach($extendFields as $extendField) { @@ -387,6 +388,13 @@ class taskModel extends model foreach($data as $i => $task) { + $laneID = isset($output['laneID']) ? $output['laneID'] : 0; + if(isset($task->laneID)) + { + $laneID = $task->laneID; + unset($task->laneID); + } + $task->version = 1; $this->dao->insert(TABLE_TASK)->data($task) ->autoCheck() @@ -418,7 +426,10 @@ class taskModel extends model } else { - if(isset($output['laneID']) and isset($output['columnID'])) $this->kanban->addKanbanCell($executionID, $output['laneID'], $output['columnID'], 'task', $taskID); + $columnID = $this->kanban->getColumnIDByLaneID($laneID, 'wait'); + if(empty($columnID)) $columnID = isset($output['columnID']) ? $output['columnID'] : 0; + + if(!empty($laneID) and !empty($columnID)) $this->kanban->addKanbanCell($executionID, $laneID, $columnID, 'task', $taskID); } $actionID = $this->action->create('task', $taskID, 'Opened', ''); diff --git a/module/task/view/batchcreate.html.php b/module/task/view/batchcreate.html.php index 3611a5b4a1..010e9daf70 100644 --- a/module/task/view/batchcreate.html.php +++ b/module/task/view/batchcreate.html.php @@ -64,6 +64,10 @@ '>task->story;?> task->name;?> + type == 'kanban'):?> + kanbancard->region;?> + kanbancard->lane;?> + typeAB;?> '>task->assignedTo;?> '>task->estimateAB;?> @@ -85,9 +89,9 @@ $modules['ditto'] = $lang->task->ditto; if($execution->type == 'ops') $colspan = $colspan - 1; ?> - task->batchCreate; $i++):?> + task->batchCreate; $i++):?> - + style='overflow:visible'> id, $i)'")?> @@ -129,6 +133,10 @@
+ type == 'kanban'):?> + + + task->typeList, $type, 'class=form-control');?> style='overflow:visible'> > @@ -136,7 +144,7 @@
0 ? "checked" : '') . " /> {$lang->task->ditto}"; + if($i != 1) echo " 1 ? "checked" : '') . " /> {$lang->task->ditto}"; ?>
@@ -144,7 +152,7 @@
0 ? "checked" : '') . " /> {$lang->task->ditto}"; + if($i != 1) echo " 1 ? "checked" : '') . " /> {$lang->task->ditto}"; ?>
diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php index 82d8fb1b46..ddcd1db77c 100644 --- a/module/task/view/create.html.php +++ b/module/task/view/create.html.php @@ -77,6 +77,16 @@ + type == 'kanban'):?> + + kanbancard->region;?> + + + + kanbancard->lane;?> + + + task->status;?>