diff --git a/db/update16.2.sql b/db/update16.2.sql index 1939846fa6..b83636466a 100644 --- a/db/update16.2.sql +++ b/db/update16.2.sql @@ -1,12 +1,12 @@ ALTER TABLE `zt_kanbanspace` ADD `type` varchar(50) NOT NULL AFTER `name`; -UPDATE `zt_kanbanspace` SET `type` = 'cooperation'; +UPDATE `zt_kanbanspace` SET `type` = 'cooperation', `whitelist` = ''; -ALTER TABLE `zt_kanban` ADD `importObject` varchar(255) NOT NULL AFTER `displayCards`; +ALTER TABLE `zt_kanban` ADD `object` varchar(255) NOT NULL AFTER `displayCards`; ALTER TABLE `zt_kanban` ADD `performable` enum ('0', '1') NOT NULL DEFAULT '0' AFTER `archived`; ALTER TABLE `zt_kanbancard` ADD `status` varchar(30) NOT NULL AFTER `name`; -ALTER TABLE `zt_kanbancard` ADD `fromID` int(8) NOT NULL AFTER `group`; -ALTER TABLE `zt_kanbancard` ADD `fromType` varchar(50) NOT NULL AFTER `fromID`; +ALTER TABLE `zt_kanbancard` ADD `fromID` mediumint(8) unsigned NOT NULL AFTER `group`; +ALTER TABLE `zt_kanbancard` ADD `fromType` varchar(30) NOT NULL AFTER `fromID`; ALTER TABLE `zt_job` ADD `sonarqubeServer` mediumint(8) unsigned NOT NULL AFTER `triggerType`; -ALTER TABLE `zt_job` ADD `projectKey` varchar(255) NOT NULL AFTER `sonarqubeServer`; +ALTER TABLE `zt_job` ADD `projectKey` varchar(255) NOT NULL AFTER `sonarqubeServer`; \ No newline at end of file diff --git a/db/zentao.sql b/db/zentao.sql index 0726ec6bd9..9fcaf3a999 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -679,7 +679,7 @@ CREATE TABLE `zt_kanban` ( `status` enum('active','closed') NOT NULL default 'active', `order` mediumint(8) NOT NULL DEFAULT '0', `displayCards` smallint(6) NOT NULL default '0', - `importObject` varchar(255) NOT NULL, + `object` varchar(255) NOT NULL, `createdBy` char(30) NOT NULL, `createdDate` datetime NOT NULL, `lastEditedBy` char(30) NOT NULL, @@ -709,6 +709,8 @@ CREATE TABLE `zt_kanbancard` ( `kanban` mediumint(8) unsigned NOT NULL, `region` mediumint(8) unsigned NOT NULL, `group` mediumint(8) unsigned NOT NULL, + `fromID` mediumint(8) undigned NOT NULL, + `fromType` varchar(30) NOT NULL, `name` varchar(255) NOT NULL, `pri` mediumint(8) unsigned NOT NULL, `assignedTo` text NOT NULL, diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 4c1e7b54e7..fc2d284de4 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -193,6 +193,11 @@ $lang->action->desc->syncexecution = '$date, starting the task sets the e $lang->action->desc->importfromgitlab = '$date, Issue associate created from gitlab by $actor.' . "\n"; $lang->action->desc->archived = '$date, archived by $actor.' . "\n"; $lang->action->desc->restore = '$date, restore by $actor.' . "\n"; +$lang->action->desc->importedcard = '$date, imported to $extra by $actor.' . "\n"; +$lang->action->desc->importedproductplan = '$date, imported to $extra by $actor.' . "\n"; +$lang->action->desc->importedrelease = '$date, imported to $extra by $actor.' . "\n"; +$lang->action->desc->importedexecution = '$date, imported to $extra by $actor.' . "\n"; +$lang->action->desc->importedbuild = '$date, imported to $extra by $actor.' . "\n"; /* Used to describe the history of operations related to parent-child tasks. */ $lang->action->desc->createchildren = '$date, $actor created a child task $extra。' . "\n"; @@ -332,6 +337,11 @@ $lang->action->label->closedbychild = 'closed'; $lang->action->label->activatedbychild = 'activated'; $lang->action->label->createchild = 'activated'; $lang->action->label->executed = 'executed'; +$lang->action->label->importedcard = 'imported'; +$lang->action->label->importedproductplan = 'imported'; +$lang->action->label->importedrelease = 'imported'; +$lang->action->label->importedexecution = 'imported'; +$lang->action->label->importedbuild = 'imported'; /* Dynamic information is grouped by object. */ $lang->action->dynamicAction = new stdclass; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 4442e8c448..8958d859e8 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -193,6 +193,11 @@ $lang->action->desc->syncexecution = '$date, 系统判断由于任务开 $lang->action->desc->importfromgitlab = '$date, 由 $actor 从Gitlab的Issue关联创建。' . "\n"; $lang->action->desc->archived = '$date, 由 $actor 归档。' . "\n"; $lang->action->desc->restore = '$date, 由 $actor 还原。' . "\n"; +$lang->action->desc->importedcard = '$date, 由 $actor 从看板 $extra 导入。' . "\n"; +$lang->action->desc->importedproductplan = '$date, 由 $actor 从产品计划 $extra 导入。' . "\n"; +$lang->action->desc->importedrelease = '$date, 由 $actor 从产品发布 $extra 导入。' . "\n"; +$lang->action->desc->importedexecution = '$date, 由 $actor 从项目执行 $extra 导入。' . "\n"; +$lang->action->desc->importedbuild = '$date, 由 $actor 从项目版本 $extra 导入。' . "\n"; /* 用来描述和父子任务相关的操作历史记录。*/ $lang->action->desc->createchildren = '$date, 由 $actor 创建子任务 $extra。' . "\n"; @@ -332,6 +337,11 @@ $lang->action->label->closedbychild = '关闭了'; $lang->action->label->activatedbychild = '激活了'; $lang->action->label->createchild = '激活了'; $lang->action->label->executed = '执行了'; +$lang->action->label->importedcard = '导入了'; +$lang->action->label->importedproductplan = '导入了'; +$lang->action->label->importedrelease = '导入了'; +$lang->action->label->importedexecution = '导入了'; +$lang->action->label->importedbuild = '导入了'; /* 动态信息按照对象分组 */ $lang->action->dynamicAction = new stdclass(); diff --git a/module/action/model.php b/module/action/model.php index 594e839a21..f379663975 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -435,6 +435,11 @@ class actionModel extends model $title = $this->dao->select('title')->from(TABLE_STORY)->where('id')->eq($action->extra)->fetch('title'); if($title) $action->extra = common::hasPriv('story', 'view') ? html::a(helper::createLink('story', 'view', "storyID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title; } + elseif($actionName == 'importedcard') + { + $title = $this->dao->select('name')->from(TABLE_KANBAN)->where('id')->eq($action->extra)->fetch('name'); + if($title) $action->extra = common::hasPriv('kanban', 'view') ? html::a(helper::createLink('kanban', 'view', "kanbanID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title; + } elseif($actionName == 'createchildren') { $names = $this->dao->select('id,name')->from(TABLE_TASK)->where('id')->in($action->extra)->fetchPairs('id', 'name'); @@ -1048,6 +1053,13 @@ class actionModel extends model $user = $this->dao->select('id,realname')->from(TABLE_USER)->where('id')->eq($action->objectID)->fetch(); if($user) $action->objectName = $user->realname; } + elseif($action->objectType == 'kanbancard' and strpos($action->action, 'imported') !== false and $action->action != 'importedcard') + { + $objectType = str_replace('imported', '', $action->action); + $objectTable = zget($this->config->objectTables, $objectType); + $objectName = $objectType == 'productplan' ? 'title' : 'name'; + $action->objectName = $this->dao->select($objectName)->from($objectTable)->where('id')->eq($action->extra)->fetch($objectName); + } $projectID = isset($relatedProjects[$action->objectType][$action->objectID]) ? $relatedProjects[$action->objectType][$action->objectID] : 0; diff --git a/module/build/model.php b/module/build/model.php index c6e9424310..525a6772dc 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -56,10 +56,11 @@ class buildModel extends model * @param string $type * @param int $param * @param string $orderBy + * @param object $pager * @access public * @return array */ - public function getProjectBuilds($projectID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc') + public function getProjectBuilds($projectID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc', $pager = null) { return $this->dao->select('t1.*, t2.name as executionName, t2.id as executionID, t3.name as productName, t4.name as branchName') ->from(TABLE_BUILD)->alias('t1') @@ -72,6 +73,7 @@ class buildModel extends model ->beginIF($type == 'product' and $param)->andWhere('t1.product')->eq($param)->fi() ->beginIF($type == 'bysearch')->andWhere($param)->fi() ->orderBy($orderBy) + ->page($pager) ->fetchAll('id'); } @@ -243,7 +245,7 @@ class buildModel extends model $branchName = $allBuilds[$buildID]->branchName ? $allBuilds[$buildID]->branchName : $this->lang->branch->main; $builds[$buildID] = (strpos($params, 'withbranch') !== false ? $branchName . '/' : '') . $releaseName; } - } + } return $sysBuilds + $builds + $selectedBuilds; } diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index 5c33bb7baa..47faf1c6e1 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -679,6 +679,7 @@ $lang->resource->kanban->restoreCard = 'restoreCard'; $lang->resource->kanban->setLaneHeight = 'setLaneHeight'; $lang->resource->kanban->batchCreateCard = 'batchCreateCard'; $lang->resource->kanban->import = 'import'; +$lang->resource->kanban->enableArchived = 'enableArchived'; $lang->kanban->methodOrder[5] = 'space'; $lang->kanban->methodOrder[10] = 'createSpace'; @@ -726,6 +727,7 @@ $lang->kanban->methodorder[210] = 'restoreCard'; $lang->kanban->methodorder[215] = 'setLaneHeight'; $lang->kanban->methodOrder[220] = 'batchCreateCard'; $lang->kanban->methodorder[225] = 'import'; +$lang->kanban->methodorder[230] = 'enableArchived'; /* Execution. */ $lang->resource->execution = new stdclass(); diff --git a/module/kanban/config.php b/module/kanban/config.php index 8c8339cdae..fe33b047f2 100644 --- a/module/kanban/config.php +++ b/module/kanban/config.php @@ -44,6 +44,12 @@ $config->kanban->editor->close = array('id' => 'comment', 'tools' => 'simp $config->kanban->editor->editcard = array('id' => 'desc', 'tools' => 'simpleTools'); $config->kanban->editor->viewcard = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->kanban->fromType = array('execution', 'productplan', 'release', 'build'); +$config->kanban->executionField = array('name', 'status', 'end', 'PM', 'type', 'deleted'); +$config->kanban->productplanField = array(); +$config->kanban->releaseField = array(); +$config->kanban->buildField = array(); + $config->kanban->default = new stdclass(); $config->kanban->default->story = new stdclass(); $config->kanban->default->story->name = $lang->SRCommon; diff --git a/module/kanban/control.php b/module/kanban/control.php index 5f1a031eda..bb52678ed1 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -884,6 +884,266 @@ class kanban extends control die(json_encode($kanbanGroup)); } + /** + * Import card. + * + * @param int $kanbanID + * @param int $regionID + * @param int $groupID + * @param int $columnID + * @param int $selectedKanbanID + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedKanbanID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1) + { + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $cards2Imported = $this->kanban->getCards2Import($selectedKanbanID, $kanbanID, $pager); + + if($_POST) + { + $importedIDList = $this->kanban->importCard($kanbanID, $regionID, $groupID, $columnID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + foreach($importedIDList as $cardID) + { + $this->loadModel('action')->create('kanbancard', $cardID, 'importedcard', '', $cards2Imported[$cardID]->kanban); + } + + return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent')); + } + + /* Find Kanban other than this kanban. */ + $kanbanPairs = $this->kanban->getKanbanPairs(); + unset($kanbanPairs[$kanbanID]); + + $this->view->cards2Imported = $cards2Imported; + $this->view->kanbanPairs = array($this->lang->kanban->allKanban) + $kanbanPairs; + $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); + $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted'); + $this->view->pager = $pager; + $this->view->selectedKanbanID = $selectedKanbanID; + $this->view->kanbanID = $kanbanID; + $this->view->regionID = $regionID; + $this->view->groupID = $groupID; + $this->view->columnID = $columnID; + + $this->display(); + } + + /** + * Import plan. + * + * @param int $kanbanID + * @param int $regionID + * @param int $groupID + * @param int $columnID + * @param int $selectedProductID + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importPlan($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1) + { + if($_POST) + { + $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'productplan'); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + foreach($importedIDList as $cardID => $planID) + { + $this->loadModel('action')->create('kanbancard', $cardID, 'importedProductplan', '', $planID); + } + + return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent')); + } + + $this->loadModel('product'); + $this->loadModel('productplan'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $productPairs = $this->product->getPairs(); + $selectedProductID = empty($selectedProductID) ? key($productPairs) : $selectedProductID; + + $this->view->products = $productPairs; + $this->view->selectedProductID = $selectedProductID; + $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); + $this->view->plans2Imported = $this->productplan->getList($selectedProductID, 0, 'all', $pager); + $this->view->pager = $pager; + $this->view->kanbanID = $kanbanID; + $this->view->regionID = $regionID; + $this->view->groupID = $groupID; + $this->view->columnID = $columnID; + + $this->display(); + } + + /** + * Import release. + * + * @param int $kanbanID + * @param int $regionID + * @param int $groupID + * @param int $columnID + * @param int $selectedProductID + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importRelease($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1) + { + if($_POST) + { + $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'release'); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + foreach($importedIDList as $cardID => $releaseID) + { + $this->loadModel('action')->create('kanbancard', $cardID, 'importedRelease', '', $releaseID); + } + + return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent')); + } + + $this->loadModel('product'); + $this->loadModel('release'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $productPairs = $this->product->getPairs(); + $selectedProductID = empty($selectedProductID) ? key($productPairs) : $selectedProductID; + + $this->view->products = $productPairs; + $this->view->selectedProductID = $selectedProductID; + $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); + $this->view->releases2Imported = $this->release->getList($selectedProductID, 'all', 'all', 't1.date_desc', $pager); + $this->view->pager = $pager; + $this->view->kanbanID = $kanbanID; + $this->view->regionID = $regionID; + $this->view->groupID = $groupID; + $this->view->columnID = $columnID; + + $this->display(); + } + + /** + * Import build. + * + * @param int $kanbanID + * @param int $regionID + * @param int $groupID + * @param int $columnID + * @param int $selectedProjectID + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importBuild($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1) + { + if($_POST) + { + $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'build'); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + foreach($importedIDList as $cardID => $buildID) + { + $this->loadModel('action')->create('kanbancard', $cardID, 'importedBuild', '', $buildID); + } + + return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent')); + } + + $this->loadModel('project'); + $this->loadModel('build'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $projectPairs = $this->project->getPairsByProgram(); + $selectedProjectID = empty($selectedProjectID) ? key($projectPairs) : $selectedProjectID; + + $this->view->projects = $projectPairs; + $this->view->selectedProjectID = $selectedProjectID; + $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); + $this->view->builds2Imported = $this->build->getProjectBuilds($selectedProjectID, 'all', 0, 't1.date_desc,t1.id_desc', $pager);; + $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted'); + $this->view->pager = $pager; + $this->view->kanbanID = $kanbanID; + $this->view->regionID = $regionID; + $this->view->groupID = $groupID; + $this->view->columnID = $columnID; + + $this->display(); + } + + /** + * Import execution. + * + * @param int $kanbanID + * @param int $regionID + * @param int $groupID + * @param int $columnID + * @param int $selectedProjectID + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importExecution($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1) + { + if($_POST) + { + $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'execution'); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + foreach($importedIDList as $cardID => $executionID) + { + $this->loadModel('action')->create('kanbancard', $cardID, 'importedExecution', '', $executionID); + } + + return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent')); + } + + $this->loadModel('project'); + $this->loadModel('execution'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $this->view->projects = $this->project->getPairsByProgram(); + $this->view->selectedProjectID = $selectedProjectID; + $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); + $this->view->executions2Imported = $this->project->getStats($selectedProjectID, 'undone', 0, 0, 30, 'id_asc', $pager); + $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted'); + $this->view->pager = $pager; + $this->view->kanbanID = $kanbanID; + $this->view->regionID = $regionID; + $this->view->groupID = $groupID; + $this->view->columnID = $columnID; + + $this->display(); + } + /** * Set a card's color. * @@ -1381,8 +1641,8 @@ class kanban extends control $kanban = $this->kanban->getByID($kanbanID); - $this->view->enableImport = empty($kanban->importObject) ? 'off' : 'on'; - $this->view->importObjects = empty($kanban->importObject) ? array() : explode(',', $kanban->importObject); + $this->view->enableImport = empty($kanban->object) ? 'off' : 'on'; + $this->view->importObjects = empty($kanban->object) ? array() : explode(',', $kanban->object); $this->display(); } diff --git a/module/kanban/css/closespace.css b/module/kanban/css/closespace.css new file mode 100644 index 0000000000..9235410476 --- /dev/null +++ b/module/kanban/css/closespace.css @@ -0,0 +1 @@ +#mainContent .c-comment {width: 50px} diff --git a/module/kanban/css/common.css b/module/kanban/css/common.css index b957733002..0196d3fe8e 100644 --- a/module/kanban/css/common.css +++ b/module/kanban/css/common.css @@ -1,3 +1,4 @@ .color-picker-item {width: 20px; height: 20px; margin-right: 10px; border-radius: 50% 50%; float: left; cursor: pointer; text-align: center; line-height: 20px;} .color-picker-item > .icon {color: #fff; display: none} .checked > .icon {display: inline-block;} +.p-10px {padding: 10px} diff --git a/module/kanban/css/space.css b/module/kanban/css/space.css index 43f6d7d70e..ef41c8d6b4 100644 --- a/module/kanban/css/space.css +++ b/module/kanban/css/space.css @@ -7,6 +7,7 @@ #spaceList .spaceActions > a{margin-left: 10px;} .space .menu {margin-left: 5px; margin-right:5px;} .space .table-empty-tip {padding: 40px 10px;} +.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 255px)} .kanbans > .col {width: 25% !important;} @media screen and (max-width: 1500px) {.kanbans > .col {width: 25%;}} diff --git a/module/kanban/css/view.css b/module/kanban/css/view.css index 1a4c04e8e6..db3016aa6c 100644 --- a/module/kanban/css/view.css +++ b/module/kanban/css/view.css @@ -98,5 +98,19 @@ .kanban-col[data-type=ADD] {display: none;} .kanban-col[data-type=EMPTY] {display: none;} -.kanban-item:hover .title {padding-right: 10px;} +.kanban-item .title {padding-right: 10px;} .gray .actions {display:none;} + +.kanban-card .header .executionName {display: flex; width: 100%; float: left; white-space: nowrap; overflow: hidden;} +.kanban-card .header .executionName .title {padding-right: 0px; margin-right: 5px; white-space: nowrap; overflow: hidden;} +.kanban-card .header .executionName .title .icon {padding-right: 5px;} +.kanban-card .header .executionName > span {flex: none;} +.execInfo {margin-top: 23px;} +.execInfo .execStatus{margin-right: 20px;} +.execInfo .label-wait {background: #EFEFEF !important; color: #838A9D;} +.execInfo .label-doing {background: #f8d2d2 !important; color: #e64b4c;} +.execInfo .label-suspended {background: #fff3d9 !important; color: #ff9800;} +.execInfo .label-closed {background: #e5e5e5 !important; color: #b8b8b8;} +.execInfo .label-deleted {background: #ff5d5d !important; color: #fff;} +.region .kanban-item > .kanban-card > .execInfo > .user {position: absolute; right: 10px; bottom: -2px} +.region .kanban-item > .kanban-card > .execInfo > .user > .avatar {display: inline-block; width: 24px; height: 24px; line-height: 24px; margin-right: 0px; margin-left: 2px} diff --git a/module/kanban/js/common.js b/module/kanban/js/common.js index fc66b36f5b..c9177e6d58 100644 --- a/module/kanban/js/common.js +++ b/module/kanban/js/common.js @@ -45,3 +45,26 @@ function initColorPicker() }) } +/** + * Reload object list. + * + * @param int $targetID + * @access public + * @return void + */ +function reloadObjectList(targetID) +{ + location.href = createLink('kanban', methodName, 'kanbanID=' + kanbanID + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID + '&targetID=' + targetID); +} + +/** + * Set target lane ID. + * + * @param int $targetLaneID + * @access public + * @return void + */ +function setTargetLane(targetLaneID) +{ + $('#targetLane').val(targetLaneID); +} diff --git a/module/kanban/js/view.js b/module/kanban/js/view.js index 5aa4017a8b..a1e3933463 100644 --- a/module/kanban/js/view.js +++ b/module/kanban/js/view.js @@ -197,6 +197,17 @@ function renderCount($count, count, column) } } +/** + * Render lane name. + * + * @param object $lane + * @param object lane + * @param object $kanban + * @param object columns + * @param object kanban + * @access public + * @return void + */ function renderLaneName($lane, lane, $kanban, columns, kanban) { var canSet = lane.actions.includes('setLane'); @@ -265,99 +276,190 @@ function renderUsersAvatar(users, itemID, size) */ function renderKanbanItem(item, $item) { - var $title = $item.children('.title'); - var privs = item.actions; - var printMoreBtn = (privs.includes('editCard') || privs.includes('finishCard') || privs.includes('activateCard') ||privs.includes('archiveCard') || privs.includes('copyCard') || privs.includes('deleteCard') || privs.includes('moveCard') || privs.includes('setCardColor')); - - if(kanban.performable == 1 && item.status == 'done' ) + if(item.fromType == 'execution') { - $item.closest('.kanban-card').css({'filter' : 'opacity(0.5)', 'text-decoration' : 'line-through'}); + renderExecutionItem(item, $item); } else { - $item.closest('.kanban-card').css({'filter' : '', 'text-decoration' : ''}); - } + var $title = $item.children('.title'); + var privs = item.actions; + var printMoreBtn = (privs.includes('editCard') || privs.includes('archiveCard') || privs.includes('copyCard') || privs.includes('deleteCard') || privs.includes('moveCard') || privs.includes('setCardColor')); - if(privs.includes('sortCard')) $item.parent().addClass('sort'); - if(!$title.length) - { - if(privs.includes('viewCard')) $title = $('').appendTo($item).attr('href', createLink('kanban', 'viewCard', 'cardID=' + item.id, '', true)); - if(!privs.includes('viewCard')) $title = $('
').appendTo($item); - } + if(kanban.performable == 1 && item.status == 'done' ) + { + $item.closest('.kanban-card').css({'filter' : 'opacity(0.5)', 'text-decoration' : 'line-through'}); + } + else + { + $item.closest('.kanban-card').css({'filter' : '', 'text-decoration' : ''}); + } - $title.text(item.name).attr('title', item.name); + if(privs.includes('sortCard')) $item.parent().addClass('sort'); + if(!$title.length) + { + if(privs.includes('viewCard')) $title = $('').appendTo($item).attr('href', createLink('kanban', 'viewCard', 'cardID=' + item.id, '', true)); + if(!privs.includes('viewCard')) $title = $('').appendTo($item); + } - if(printMoreBtn) - { - $( + $title.text(item.name).attr('title', item.name); + + if(printMoreBtn) + { + $( + [ + '