Merge branch 'sprint/183_xieqiyu_47995new'

This commit is contained in:
孙广明
2022-01-24 15:29:27 +08:00
30 changed files with 1224 additions and 100 deletions
+5 -5
View File
@@ -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`;
+3 -1
View File
@@ -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,
+10
View File
@@ -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 <strong>$actor</strong>.' . "\n";
$lang->action->desc->archived = '$date, archived by <strong>$actor</strong>.' . "\n";
$lang->action->desc->restore = '$date, restore by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedcard = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\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;
+10
View File
@@ -193,6 +193,11 @@ $lang->action->desc->syncexecution = '$date, 系统判断由于任务开
$lang->action->desc->importfromgitlab = '$date, 由 <strong>$actor</strong> 从Gitlab的Issue关联创建。' . "\n";
$lang->action->desc->archived = '$date, 由 <strong>$actor</strong> 归档。' . "\n";
$lang->action->desc->restore = '$date, 由 <strong>$actor</strong> 还原。' . "\n";
$lang->action->desc->importedcard = '$date, 由 <strong>$actor</strong> 从看板 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedproductplan = '$date, 由 <strong>$actor</strong> 从产品计划 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedrelease = '$date, 由 <strong>$actor</strong> 从产品发布 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedexecution = '$date, 由 <strong>$actor</strong> 从项目执行 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedbuild = '$date, 由 <strong>$actor</strong> 从项目版本 <strong>$extra</strong> 导入。' . "\n";
/* 用来描述和父子任务相关的操作历史记录。*/
$lang->action->desc->createchildren = '$date, 由 <strong>$actor</strong> 创建子任务 <strong>$extra</strong>。' . "\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();
+12
View File
@@ -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;
+4 -2
View File
@@ -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;
}
+2
View File
@@ -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();
+6
View File
@@ -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;
+262 -2
View File
@@ -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();
}
+1
View File
@@ -0,0 +1 @@
#mainContent .c-comment {width: 50px}
+1
View File
@@ -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}
+1
View File
@@ -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%;}}
+15 -1
View File
@@ -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}
+23
View File
@@ -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 + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID + '&targetID=' + targetID);
}
/**
* Set target lane ID.
*
* @param int $targetLaneID
* @access public
* @return void
*/
function setTargetLane(targetLaneID)
{
$('#targetLane').val(targetLaneID);
}
+192 -68
View File
@@ -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 = $('<a class="title iframe" data-toggle="modal" data-width="80%"></a>').appendTo($item).attr('href', createLink('kanban', 'viewCard', 'cardID=' + item.id, '', true));
if(!privs.includes('viewCard')) $title = $('<p class="title"></p>').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 = $('<a class="title iframe" data-toggle="modal" data-width="80%"></a>').appendTo($item).attr('href', createLink('kanban', 'viewCard', 'cardID=' + item.id, '', true));
if(!privs.includes('viewCard')) $title = $('<p class="title"></p>').appendTo($item);
}
if(printMoreBtn)
{
$(
$title.text(item.name).attr('title', item.name);
if(printMoreBtn)
{
$(
[
'<div class="actions" title="' + kanbanLang.more + '">',
'<a data-contextmenu="card" data-id="' + item.id + '">',
'<i class="icon icon-ellipsis-v"></i>',
'</a>',
'</div>'
].join('')).appendTo($item);
}
var $info = $item.children('.info');
if(!$info.length) $info = $(
[
'<div class="actions" title="' + kanbanLang.more + '">',
'<a data-contextmenu="card" data-id="' + item.id + '">',
'<i class="icon icon-ellipsis-v"></i>',
'</a>',
'<div class="info">',
'<span class="pri"></span>',
'<span class="estimate label label-light"></span>',
'<span class="time label label-light"></span>',
'<div class="user"></div>',
'</div>'
].join('')).appendTo($item);
}
var $info = $item.children('.info');
if(!$info.length) $info = $(
$item.data('card', item);
$info.children('.estimate').text(item.estimate + kanbancardLang.lblHour);
if(item.estimate == 0) $info.children('.estimate').hide();
$info.children('.pri')
.attr('class', 'pri label-pri label-pri-' + item.pri)
.text(item.pri);
$item.css('background-color', item.color);
$item.toggleClass('has-color', item.color != '#fff' && item.color != '');
$item.find('.info > .label-light').css('background-color', item.color);
var $time = $info.children('.time');
if(item.end == '0000-00-00' && item.begin == '0000-00-00')
{
$time.hide();
}
else
{
var today = new Date();
var begin = $.zui.createDate(item.begin);
var end = $.zui.createDate(item.end);
var needRemind = (begin.toLocaleDateString() == today.toLocaleDateString() || end.toLocaleDateString() == today.toLocaleDateString());
if(item.end == '0000-00-00' && item.begin != '0000-00-00')
{
$time.text($.zui.formatDate(begin, 'MM/dd') + ' ' + kanbancardLang.beginAB).attr('title', $.zui.formatDate(begin, 'yyyy/MM/dd') + ' ' +kanbancardLang.beginAB).show();
}
else if(item.begin == '0000-00-00' && item.end != '0000-00-00')
{
$time.text($.zui.formatDate(end, 'MM/dd') + ' ' + kanbancardLang.deadlineAB).attr('title', $.zui.formatDate(end, 'yyyy/MM/dd') + ' ' + kanbancardLang.deadlineAB).show();
}
else if(item.begin != '0000-00-00' && item.end != '0000-00-00')
{
$time.text($.zui.formatDate(begin, 'MM/dd') + ' ' + kanbancardLang.to + ' ' + $.zui.formatDate(end, 'MM/dd')).attr('title', $.zui.formatDate(begin, 'yyyy/MM/dd') + kanbancardLang.to + $.zui.formatDate(end, 'yyyy/MM/dd')).show();
}
if(!$item.hasClass('has-color') && needRemind) $time.css('background-color', 'rgba(210, 50, 61, 0.3)');
if($item.hasClass('has-color') && needRemind) $time.css('background-color', 'rgba(255, 255, 255, 0.3)');
if(!needRemind) $time.css('background-color', 'rgba(0, 0, 0, 0.15)');
}
/* Display avatars of assignedTo. */
var assignedTo = item.assignedTo.split(',');
var $user = $info.children('.user');
var title = [];
for(i = 0; i < assignedTo.length; i++) title.push(users[assignedTo[i]]);
$user.html(renderUsersAvatar(assignedTo, item.id)).attr('title', title);
}
}
/**
* Render execution item.
*
* @param object item
* @param object $item
* @access public
* @return void
*/
function renderExecutionItem(item, $item)
{
/* Output header information. */
var privs = item.actions;
var $header = $item.children('.header');
if(!$header.length) $header = $(
[
'<div class="info">',
'<span class="pri"></span>',
'<span class="estimate label label-light"></span>',
'<span class="time label label-light"></span>',
'<div class="user"></div>',
'<div class="header">',
'</div>'
].join('')).appendTo($item);
var $titleBox = $header.children('.executionName');
if(!$titleBox.length) $titleBox = $(
[
'<div class="executionName">',
'</div>'
].join('')).appendTo($header);
/* Print execution name. */
var $title = $titleBox.children('.title');
if(!$title.length)
{
var viewMethod = item.execType == 'kanban' ? 'kanban' : 'view';
if(privs.includes('viewExecution') && item.deleted == '0') $title = $('<a class="title"><i class="icon icon-run"></i>' + item.name + '</a>').appendTo($titleBox).attr('href', createLink('execution', viewMethod, 'executionID=' + item.fromID));
if(!privs.includes('viewExecution') || item.deleted == '1') $title = $('<a class="title"><i class="icon icon-run"></i>' + item.name + '</a>').appendTo($titleBox);
}
$title.attr('title', item.name);
if(item.delay)
{
$delayed = $titleBox.children('.delayed');
if(!$delayed.length)
{
$('<span class="delayed label label-danger label-badge">' + executionLang.delayed + '</span>').appendTo($titleBox);
}
}
$item.data('card', item);
$info.children('.estimate').text(item.estimate + kanbancardLang.lblHour);
if(item.estimate == 0) $info.children('.estimate').hide();
var $info = $item.children('.execInfo');
if(!$info.length) $info = $(
[
'<div class="execInfo">',
'</div>'
].join('')).appendTo($item);
$info.children('.pri')
.attr('class', 'pri label-pri label-pri-' + item.pri)
.text(item.pri);
$item.css('background-color', item.color);
$item.toggleClass('has-color', item.color != '#fff' && item.color != '');
$item.find('.info > .label-light').css('background-color', item.color);
var $time = $info.children('.time');
if(item.end == '0000-00-00' && item.begin == '0000-00-00')
var $statusBox = $info.children('.execStatus');
if(!$statusBox.length)
{
$time.hide();
}
else
{
var today = new Date();
var begin = $.zui.createDate(item.begin);
var end = $.zui.createDate(item.end);
var needRemind = (begin.toLocaleDateString() == today.toLocaleDateString() || end.toLocaleDateString() == today.toLocaleDateString());
if(item.end == '0000-00-00' && item.begin != '0000-00-00')
if(item.deleted == '0')
{
$time.text($.zui.formatDate(begin, 'MM/dd') + ' ' + kanbancardLang.beginAB).attr('title', $.zui.formatDate(begin, 'yyyy/MM/dd') + ' ' +kanbancardLang.beginAB).show();
$statusBox = $('<span class="execStatus label label-' + item.status + '">' + executionLang.statusList[item.status] + '</span>').appendTo($info);
}
else if(item.begin == '0000-00-00' && item.end != '0000-00-00')
else
{
$time.text($.zui.formatDate(end, 'MM/dd') + ' ' + kanbancardLang.deadlineAB).attr('title', $.zui.formatDate(end, 'yyyy/MM/dd') + ' ' + kanbancardLang.deadlineAB).show();
$statusBox = $('<span class="execStatus label label-deleted">' + executionLang.deleted + '</span>').appendTo($info);
}
else if(item.begin != '0000-00-00' && item.end != '0000-00-00')
{
$time.text($.zui.formatDate(begin, 'MM/dd') + ' ' + kanbancardLang.to + ' ' + $.zui.formatDate(end, 'MM/dd')).attr('title', $.zui.formatDate(begin, 'yyyy/MM/dd') + kanbancardLang.to + $.zui.formatDate(end, 'yyyy/MM/dd')).show();
}
if(!$item.hasClass('has-color') && needRemind) $time.css('background-color', 'rgba(210, 50, 61, 0.3)');
if($item.hasClass('has-color') && needRemind) $time.css('background-color', 'rgba(255, 255, 255, 0.3)');
if(!needRemind) $time.css('background-color', 'rgba(0, 0, 0, 0.15)');
}
/* Display avatars of assignedTo. */
var assignedTo = item.assignedTo.split(',');
/* Display deadline of execution. */
var $date = $info.children('.date');
var end = $.zui.createDate(item.end);
var today = new Date();
var labelType = end.toLocaleDateString() == today.toLocaleDateString() ? 'danger' : 'wait';
if(!$date.length) $date = $('<span class="date label label-' + labelType + '"></span>').appendTo($info);
$date.text($.zui.formatDate(end, 'MM-dd') + ' ' + kanbancardLang.deadlineAB).attr('title', $.zui.formatDate(end, 'yyyy-MM-dd') + ' ' + kanbancardLang.deadlineAB).show();
/* Display avatars of PM. */
var $user = $info.children('.user');
var title = [];
for(i = 0; i < assignedTo.length; i++) title.push(users[assignedTo[i]]);
$user.html(renderUsersAvatar(assignedTo, item.id)).attr('title', title);
var user = [item.PM];
if(!$user.length) $user = $('<div class="user"></div>').appendTo($info);
$user.html(renderUsersAvatar(user, item.id)).attr('title', item.PM);
}
/**
@@ -865,8 +967,12 @@ function createColumnCreateMenu(options)
var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0;
var columnID = col.id;
if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('batchCreateCard')) items.push({label: kanbanLang.batchCreateCard, url: $.createLink('kanban', 'batchCreateCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&laneID=' + laneID + '&columnID=' + columnID), attrs: {'data-width': '80%'}});
if(privs.includes('import') && kanban.object.indexOf('cards') != -1) items.push({label: kanbanLang.importCard, url: $.createLink('kanban', 'importCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&laneID=' + laneID + '&columnID=' + columnID), attrs: {'data-width': '80%'}});
if(privs.includes('import') && kanban.object) items.push({className: 'parentDivider'});
if(privs.includes('import') && kanban.object) items.push({label: kanbanLang.importAB, className: 'import'});
return items;
}
@@ -984,6 +1090,18 @@ $(function()
if(!items || !items.length) return;
$.zui.ContextMenu.show(items, items.$options || {event: event});
$('.parentDivider').parent().addClass('divider');
$('.import').parent().addClass('dropdown-submenu top');
/* The submenu of import. */
var importPlanLink = kanban.object.indexOf('plan') != -1 ? '<li><a href="' + createLink('kanban', 'importPlan') + '">' + kanbanLang.importPlan + '</a></li>' : '';
var importReleaseLink = kanban.object.indexOf('release') != -1 ? '<li><a href="' + createLink('kanban', 'importRelease') + '">' + kanbanLang.importRelease + '</a></li>' : '';
var importExecutionLink = kanban.object.indexOf('execution') != -1 ? '<li><a href="' + createLink('kanban', 'importExecution') + '">' + kanbanLang.importExecution + '</a></li>' : '';
var importBuildLink = kanban.object.indexOf('build') != -1 ? '<li><a href="' + createLink('kanban', 'importBuild') + '">' + kanbanLang.importBuild + '</a></li>' : '';
var importSubmenu = '<ul class="dropdown-menu">' + importPlanLink + importReleaseLink + importExecutionLink + importBuildLink +'</ul>';
$('.import').parent().append(importSubmenu);
});
/* Adjust the add button position on window resize */
@@ -1097,6 +1215,11 @@ $(function()
hideKanbanAction();
}
if(sortType == 'column')
{
$('.kanban-item').addClass('hidden');
}
if(sortType == 'card')
{
oldLaneID = e.element.closest('.kanban-lane').data('id');
@@ -1160,6 +1283,7 @@ $(function()
{
updateRegion(regionID, response[regionID]);
}
$('.kanban-item').removeClass('hidden');
});
},
always: function(e)
+14
View File
@@ -63,7 +63,16 @@ $lang->kanban->restore = 'Restore';
$lang->kanban->child = 'Child';
$lang->kanban->batchCreateCard = 'Batchcreate Card';
$lang->kanban->import = 'Import';
$lang->kanban->importAB = 'Import';
$lang->kanban->showClosed = 'Closed';
$lang->kanban->importCard = 'Import Card';
$lang->kanban->importPlan = 'Import Plan';
$lang->kanban->importRelease = 'Import Release';
$lang->kanban->importExecution = 'Import ' . $lang->execution->common;
$lang->kanban->importBuild = 'Import Build';
$lang->kanban->allKanban = 'All Kanban';
$lang->kanban->allProjects = 'All Projects';
$lang->kanban->allProducts = 'All Products';
/* Fields. */
$lang->kanban->space = 'Space';
@@ -93,6 +102,11 @@ $lang->kanban->accessDenied = "You have no access to the kanban.";
$lang->kanban->confirmDelete = 'Do you want to delete this?';
$lang->kanban->cardCountTip = 'Please enter the number of cards';
$lang->kanban->selectedKanban = 'Please select Kanban';
$lang->kanban->selectedProduct = 'Please select Product';
$lang->kanban->selectedProject = 'Please select Project';
$lang->kanban->selectedLane = 'Target Lane';
$lang->kanban->aclGroup['open'] = 'Open';
$lang->kanban->aclGroup['private'] = 'Private';
$lang->kanban->aclGroup['extend'] = 'Extend';
+14
View File
@@ -63,7 +63,16 @@ $lang->kanban->restore = '还原';
$lang->kanban->child = '子';
$lang->kanban->batchCreateCard = '批量创建卡片';
$lang->kanban->import = '导入功能';
$lang->kanban->importAB = '导入';
$lang->kanban->showClosed = '显示已关闭';
$lang->kanban->importCard = '转入卡片';
$lang->kanban->importPlan = '导入产品计划';
$lang->kanban->importRelease = '导入产品发布';
$lang->kanban->importExecution = '导入项目' . $lang->execution->common;
$lang->kanban->importBuild = '导入项目版本';
$lang->kanban->allKanban = '所有看板';
$lang->kanban->allProjects = '所有项目';
$lang->kanban->allProducts = '所有产品';
/* Fields. */
$lang->kanban->space = '所属空间';
@@ -93,6 +102,11 @@ $lang->kanban->accessDenied = '您无权访问该看板';
$lang->kanban->confirmDelete = '您确认删除吗?';
$lang->kanban->cardCountTip = '请输入卡片数量';
$lang->kanban->selectedKanban = '请选择看板';
$lang->kanban->selectedProduct = '请选择产品';
$lang->kanban->selectedProject = '请选择项目';
$lang->kanban->selectedLane = '目标泳道';
$lang->kanban->aclGroup['open'] = '公开';
$lang->kanban->aclGroup['private'] = '私有';
$lang->kanban->aclGroup['extend'] = '继承空间';
+212 -7
View File
@@ -469,12 +469,87 @@ class kanbanModel extends model
}
/**
* Batch create kanban cards.
* Import card.
*
* @param int $kanbanID
* @param int $regionID
* @param int $groupID
* @param int $columnID
* @access public
* @return bool|array
*/
public function importCard($kanbanID, $regionID, $groupID, $columnID)
{
$data = fixer::input('post')->get();
$importIDList = $data->cards;
$targetLaneID = $data->targetLane;
$oldCardsKanban = $this->dao->select('id,kanban')->from(TABLE_KANBANCARD)->where('id')->in($importIDList)->fetchPairs();
$updateData = new stdClass();
$updateData->kanban = $kanbanID;
$updateData->region = $regionID;
$updateData->group = $groupID;
$this->dao->update(TABLE_KANBANCARD)->data($updateData)->where('id')->in($importIDList)->exec();
if(!dao::isError())
{
$this->removeKanbanCell('common', $importIDList, $oldCardsKanban);
$cards = implode(',', $importIDList);
$this->addKanbanCell($kanbanID, $targetLaneID, $columnID, 'common', $cards);
return $importIDList;
}
return false;
}
/**
* Import object.
*
* @param int $kanbanID
* @param int $regionID
* @param int $groupID
* @param int $columnID
* @param string $objectType
* @access public
* @return array
*/
public function importObject($kanbanID, $regionID, $groupID, $columnID, $objectType)
{
$data = fixer::input('post')->get();
$objectIDList = $data->{$objectType . 's'};
$targetLaneID = $data->targetLane;
$objectCards = array();
foreach($objectIDList as $objectID)
{
$cardData = new stdClass();
$cardData->kanban = $kanbanID;
$cardData->region = $regionID;
$cardData->group = $groupID;
$cardData->fromID = $objectID;
$cardData->fromType = $objectType;
$this->dao->insert(TABLE_KANBANCARD)->data($cardData)->exec();
$cardID = $this->dao->lastInsertID();
$objectCards[$cardID] = $objectID;
}
if(!dao::isError())
{
$cards = implode(',', array_keys($objectCards));
$this->addKanbanCell($kanbanID, $targetLaneID, $columnID, 'common', $cards);
return $objectCards;
}
return false;
}
/*
* Batch create kanban cards.
* @access public
* @return void
*/
@@ -567,7 +642,7 @@ class kanbanModel extends model
*
* @param int $kanbanID
* @access public
* @return void
* @return array
*/
public function getKanbanData($kanbanID)
{
@@ -886,7 +961,7 @@ class kanbanModel extends model
->orderBy($order)
->fetchGroup('group');
$actions = array('createColumn', 'setColumn', 'setWIP', 'archiveColumn', 'restoreColumn', 'deleteColumn', 'createCard', 'batchCreateCard', 'splitColumn', 'sortColumn');
$actions = array('createColumn', 'setColumn', 'setWIP', 'archiveColumn', 'restoreColumn', 'deleteColumn', 'createCard', 'batchCreateCard', 'splitColumn', 'import', 'sortColumn');
/* Group by parent. */
$parentColumnGroup = array();
@@ -940,18 +1015,25 @@ class kanbanModel extends model
public function getCardGroupByKanban($kanbanID)
{
/* Get card data.*/
$cards = $this->dao->select('*')->from(TABLE_KANBANCARD)->alias('t1')
$cards = $this->dao->select('*')->from(TABLE_KANBANCARD)
->where('deleted')->eq(0)
->andWhere('kanban')->eq($kanbanID)
->andWhere('archived')->eq(0)
->andWhere('fromID')->eq(0)
->fetchAll('id');
foreach($this->config->kanban->fromType as $fromType)
{
$cards = $this->getImportedCards($kanbanID, $cards, $fromType);
}
$cellList = $this->dao->select('*')->from(TABLE_KANBANCELL)
->where('kanban')->eq($kanbanID)
->andWhere('type')->eq('common')
->fetchAll();
$actions = array('editCard', 'finishCard', 'activateCard', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard');
$actions = array('editCard', 'finishCard', 'activateCard', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard', 'viewExecution');
$cardGroup = array();
foreach($cellList as $cell)
{
@@ -969,6 +1051,15 @@ class kanbanModel extends model
$card->actions = array();
foreach($actions as $action)
{
if($action == 'viewExecution')
{
if($card->fromType == 'execution')
{
if($card->execType == 'kanban' and common::hasPriv('execution', 'kanban')) $card->actions[] = $action;
if($card->execType != 'kanban' and common::hasPriv('execution', 'view')) $card->actions[] = $action;
}
continue;
}
if(common::hasPriv('kanban', $action)) $card->actions[] = $action;
}
@@ -979,6 +1070,54 @@ class kanbanModel extends model
return $cardGroup;
}
/**
* Get imported cards.
*
* @param int $kanbanID
* @param object $cards
* @param string $fromType
* @access public
* @return array
*/
public function getImportedCards($kanbanID, $cards, $fromType)
{
$objectCards = $this->dao->select('*')->from(TABLE_KANBANCARD)
->where('deleted')->eq(0)
->andWhere('kanban')->eq($kanbanID)
->andWhere('archived')->eq(0)
->andWhere('fromType')->eq($fromType)
->fetchAll('fromID');
if(!empty($objectCards))
{
$table = $this->config->objectTables[$fromType];
$objects = $this->dao->select('*')->from($table)
->where('id')->in(array_keys($objectCards))
->fetchAll('id');
foreach($objectCards as $objectCard)
{
$object = $objects[$objectCard->fromID];
$fieldType = $fromType . 'Field';
foreach($this->config->kanban->$fieldType as $field) $objectCard->$field = $object->$field;
if($fromType =='execution')
{
if($object->status != 'done' and $object->status != 'closed' and $object->status != 'suspended')
{
$delay = helper::diffDate(helper::today(), $object->end);
if($delay > 0) $objectCard->delay = $delay;
}
$objectCard->execType = $object->type;
}
$cards[$objectCard->id] = $objectCard;
}
}
return $cards;
}
/**
* Get RD column group by regions.
*
@@ -1470,6 +1609,23 @@ class kanbanModel extends model
->fetchPairs('id');
}
/**
* Get Kanban pairs.
*
* @access public
* @return void
*/
public function getKanbanPairs()
{
$kanbanIdList = $this->getCanViewObjects('kanban');
return $this->dao->select('id,name')->from(TABLE_KANBAN)
->where('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($kanbanIdList)->fi()
->orderBy('id_desc')
->fetchPairs('id');
}
/**
* Get can view objects.
*
@@ -2034,6 +2190,33 @@ class kanbanModel extends model
}
}
/**
* Remove kanban cell.
*
* @param string $type
* @param int|array $removeCardID
* @param array $kanbanList
* @access public
* @return void
*/
public function removeKanbanCell($type, $removeCardID, $kanbanList)
{
$removeIDList = is_array($removeCardID) ? $removeCardID : array($removeCardID);
foreach($removeIDList as $cardID)
{
if(empty($cardID)) continue;
$this->dbh->query("UPDATE " . TABLE_KANBANCELL. " SET `cards` = REPLACE(cards, ',$cardID,', ',') WHERE `type` = '$type' AND `kanban` = {$kanbanList[$cardID]}");
}
$this->dao->update(TABLE_KANBANCELL)
->set('cards')->eq('')
->where('cards')->eq(',')
->andWhere('type')->eq($type)
->andWhere('kanban')->in($kanbanList)
->exec();
}
/**
* Create a default RD kanban.
*
@@ -3100,7 +3283,7 @@ class kanbanModel extends model
* @access public
* @return array
*/
public function getCardsByObject($objectType = '', $objectID = 0, $archived = 0, $deleted = '0')
public function getCardsByObject($objectType = '', $objectID = 0, $archived = '0', $deleted = '0')
{
return $this->dao->select('*')->from(TABLE_KANBANCARD)
->where(true)
@@ -3111,6 +3294,28 @@ class kanbanModel extends model
->fetchAll('id');
}
/**
* Get cards to import.
*
* @param int $kanbanID
* @param int $excludedID
* @param obj $pager
* @access public
* @return array
*/
public function getCards2Import($kanbanID = 0, $excludedID = 0, $pager = null)
{
return $this->dao->select('*')->from(TABLE_KANBANCARD)
->where('deleted')->eq(0)
->andWhere('archived')->eq(0)
->andWhere('fromID')->eq(0)
->beginIF($kanbanID)->andWhere('kanban')->eq($kanbanID)->fi()
->beginIF($excludedID)->andWhere('kanban')->ne($excludedID)->fi()
->orderBy('order')
->page($pager)
->fetchAll('id');
}
/**
* Get Kanban cards menus by execution id.
*
@@ -3263,6 +3468,6 @@ class kanbanModel extends model
$importObjects = $_POST['import'] == 'off' ? array() : $_POST['importObjectList'];
$importObjectList = implode(',', $importObjects);
$this->dao->update(TABLE_KANBAN)->set('importObject')->eq($importObjectList)->where('id')->eq($kanbanID)->exec();
$this->dao->update(TABLE_KANBAN)->set('object')->eq($importObjectList)->where('id')->eq($kanbanID)->exec();
}
}
+3 -3
View File
@@ -23,11 +23,11 @@
<form method='post' enctype='multipart/form-data' target='hiddenwin'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->comment;?></th>
<td colspan='2'><?php echo html::textarea('comment', '', "rows='6'");?></td>
<th class='c-comment'><?php echo $lang->comment;?></th>
<td><?php echo html::textarea('comment', '', "rows='6'");?></td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
<td colspan='2' class='text-center form-actions'>
<?php echo html::submitButton($lang->kanban->closeSpace);?>
</td>
</tr>
-1
View File
@@ -43,7 +43,6 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, '', "class='form-control chosen' multiple data-drop_direction='down'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
</div>
</td>
</tr>
-1
View File
@@ -36,7 +36,6 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, $kanban->team, "class='form-control chosen' multiple data-drop_direction='down'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
</div>
</td>
</tr>
+83
View File
@@ -0,0 +1,83 @@
<?php
/**
* The import build view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importbuild.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importBuild;?></h2>
</div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedProject;?></h4></div>
<div class='table-col'><?php echo html::select('project', $projects, $selectedProjectID, "onchange='reloadObjectList(this.value)' class='form-control chosen'");?></div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedLane;?></h4></div>
<div class='table-col'><?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen'");?></div>
</div>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importBuildForm'>
<table class='table table-fixed' id='buildList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->build->product;?></th>
<th class='c-name'><?php echo $lang->build->name;?></th>
<th class='c-name'><?php echo $lang->executionCommon;?></th>
<th class='c-date'><?php echo $lang->build->date;?></th>
<th class='c-user'><?php echo $lang->build->builder;?></th>
</tr>
</thead>
<tbody>
<?php foreach($builds2Imported as $build):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='builds[]' value='<?php echo $build->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $build->id);?>
</td>
<td title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<?php if(common::hasPriv('build', 'view')):?>
<td title='<?php echo $build->name;?>'><?php common::printLink('build', 'view', "buildID=$build->id", $build->name, '', "class='iframe'", true, true);?></td>
<?php else:?>
<td title='<?php echo $build->name;?>'><?php echo $build->name;?></td>
<?php endif;?>
<td title='<?php echo $build->executionName;?>'><?php echo $build->executionName;?></td>
<td title='<?php echo $build->date;?>'><?php echo $build->date;?></td>
<td title='<?php echo zget($users, $build->builder);?>'><?php echo zget($users, $build->builder);?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<?php if($builds2Imported):?>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importBuild, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
+83
View File
@@ -0,0 +1,83 @@
<?php
/**
* The import card view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importcard.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importCard;?></h2>
</div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedKanban;?></h4></div>
<div class='table-col'><?php echo html::select('kanban', $kanbanPairs, $selectedKanbanID, "onchange='reloadObjectList(this.value)' class='form-control chosen'");?></div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedLane;?></h4></div>
<div class='table-col'><?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen'");?></div>
</div>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importCardForm'>
<table class='table table-fixed' id='cardList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->kanban->name;?></th>
<th class='c-pri'><?php echo $lang->priAB;?></th>
<th class='c-name'><?php echo $lang->kanbancard->name;?></th>
<th class='c-user'><?php echo $lang->kanbancard->assignedTo;?></th>
<th class='c-date'><?php echo $lang->kanbancard->end;?></th>
</tr>
</thead>
<tbody>
<?php foreach($cards2Imported as $card):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='cards[]' value='<?php echo $card->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $card->id);?>
</td>
<td title='<?php echo zget($kanbanPairs, $card->kanban);?>'><?php echo zget($kanbanPairs, $card->kanban);?></td>
<td><span class='label-pri <?php echo 'label-pri-' . $card->pri?>' title='<?php echo zget($lang->kanbancard->priList, $card->pri, $card->pri);?>'><?php echo zget($lang->kanbancard->priList, $card->pri, $card->pri);?></span></td>
<?php if(common::hasPriv('kanban', 'viewCard')):?>
<td title='<?php echo $card->name;?>'><?php common::printLink('kanban', 'viewCard', "cardID=$card->id", $card->name, '', "class='iframe'", true, true);?></td>
<?php else:?>
<td title='<?php echo $card->name;?>'><?php echo $card->name;?></td>
<?php endif;?>
<td title='<?php echo zget($users, $card->assignedTo);?>'><?php echo zget($users, $card->assignedTo);?></td>
<td title='<?php echo $card->end;?>'><?php echo $card->end;?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<?php if($cards2Imported):?>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importCard, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
@@ -0,0 +1,87 @@
<?php
/**
* The import execution view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importexecution.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importExecution;?></h2>
</div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedProject;?></h4></div>
<div class='table-col'><?php echo html::select('project', $projects, $selectedProjectID, "onchange='reloadObjectList(this.value)' class='form-control chosen'");?></div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedLane;?></h4></div>
<div class='table-col'><?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen'");?></div>
</div>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importExecutionForm'>
<table class='table table-fixed' id='executionList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->execution->name;?></th>
<th class='c-status'><?php echo $lang->execution->status;?></th>
<th class='c-user'><?php echo $lang->execution->owner;?></th>
<th class='c-date'><?php echo $lang->execution->end;?></th>
<th class='c-hour'><?php echo $lang->execution->totalEstimate;?></th>
<th class='c-hour'><?php echo $lang->execution->totalConsumed;?></th>
<th class='c-hour'><?php echo $lang->execution->totalLeft;?></th>
</tr>
</thead>
<tbody>
<?php foreach($executions2Imported as $execution):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='executions[]' value='<?php echo $execution->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $execution->id);?>
</td>
<?php if(common::hasPriv('execution', 'view')):?>
<td title='<?php echo $execution->name;?>'><?php common::printLink('execution', 'view', "executionID=$execution->id", $execution->name, '', "class='iframe'", true, true);?></td>
<?php else:?>
<td title='<?php echo $execution->name;?>'><?php echo $execution->name;?></td>
<?php endif;?>
<td title='<?php echo zget($lang->execution->statusList, $execution->status);?>'><?php echo zget($lang->execution->statusList, $execution->status);?></td>
<td title='<?php echo zget($users, $execution->PM);?>'><?php echo zget($users, $execution->PM);?></td>
<td title='<?php echo $execution->end;?>'><?php echo $execution->end;?></td>
<td title='<?php echo $execution->hours->totalEstimate;?>'><?php echo $execution->hours->totalEstimate;?></td>
<td title='<?php echo $execution->hours->totalConsumed;?>'><?php echo $execution->hours->totalConsumed;?></td>
<td title='<?php echo $execution->hours->totalLeft;?>'><?php echo $execution->hours->totalLeft;?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<?php if($executions2Imported):?>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importExecution, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
+87
View File
@@ -0,0 +1,87 @@
<?php
/**
* The import plan view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importplan.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importPlan;?></h2>
</div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedProduct;?></h4></div>
<div class='table-col'><?php echo html::select('product', $products, $selectedProductID, "onchange='reloadObjectList(this.value)' class='form-control chosen'");?></div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedLane;?></h4></div>
<div class='table-col'><?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen'");?></div>
</div>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importPlanForm'>
<table class='table table-fixed' id='planList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->productplan->title;?></th>
<th class='c-date'><?php echo $lang->productplan->begin;?></th>
<th class='c-date'><?php echo $lang->productplan->end;?></th>
<th class='w-90px'><?php echo $lang->productplan->stories;?></th>
<th class='w-80px'><?php echo $lang->productplan->bugs;?></th>
<th class='c-hour'><?php echo $lang->productplan->hour;?></th>
<th><?php echo $lang->productplan->desc;?></th>
</tr>
</thead>
<tbody>
<?php foreach($plans2Imported as $plan):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='productplans[]' value='<?php echo $plan->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $plan->id);?>
</td>
<?php if(common::hasPriv('productplan', 'view')):?>
<td title='<?php echo $plan->title;?>'><?php common::printLink('productplan', 'view', "planID=$plan->id", $plan->title, '', "class='iframe'", true, true);?></td>
<?php else:?>
<td title='<?php echo $plan->title;?>'><?php echo $plan->title;?></td>
<?php endif;?>
<td title='<?php echo $plan->begin;?>'><?php echo $plan->begin;?></td>
<td title='<?php echo $plan->end;?>'><?php echo $plan->end;?></td>
<td title='<?php echo $plan->stories;?>'><?php echo $plan->stories;?></td>
<td title='<?php echo $plan->bugs;?>'><?php echo $plan->bugs;?></td>
<td title='<?php echo $plan->hour;?>'><?php echo $plan->hour;?></td>
<td title='<?php echo $plan->desc;?>'><?php echo $plan->desc;?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<?php if($plans2Imported):?>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importPlan, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
+81
View File
@@ -0,0 +1,81 @@
<?php
/**
* The import release view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importrelease.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importRelease;?></h2>
</div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedProduct;?></h4></div>
<div class='table-col'><?php echo html::select('product', $products, $selectedProductID, "onchange='reloadObjectList(this.value)' class='form-control chosen'");?></div>
</div>
<div class='table-row p-10px'>
<div class='table-col w-150px text-center'><h4><?php echo $lang->kanban->selectedLane;?></h4></div>
<div class='table-col'><?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen'");?></div>
</div>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importReleaseForm'>
<table class='table table-fixed' id='releaseList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->release->name;?></th>
<th class='c-name'><?php echo $lang->release->project;?></th>
<th class='c-name'><?php echo $lang->release->build;?></th>
<th class='c-date'><?php echo $lang->release->date;?></th>
</tr>
</thead>
<tbody>
<?php foreach($releases2Imported as $release):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='releases[]' value='<?php echo $release->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $release->id);?>
</td>
<?php if(common::hasPriv('release', 'view')):?>
<td title='<?php echo $release->name;?>'><?php common::printLink('release', 'view', "releaseID=$release->id", $release->name, '', "class='iframe'", true, true);?></td>
<?php else:?>
<td title='<?php echo $release->name;?>'><?php echo $release->name;?></td>
<?php endif;?>
<td title='<?php echo $release->projectName;?>'><?php echo $release->projectName;?></td>
<td title='<?php echo $release->buildName;?>'><?php echo $release->buildName;?></td>
<td title='<?php echo $release->date;?>'><?php echo $release->date;?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<?php if($releases2Imported):?>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importRelease, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
+1 -1
View File
@@ -50,7 +50,7 @@
</div>
<div class='spaceActions pull-right'>
<?php $class = $space->status == 'closed' ? 'disabled' : '';?>
<?php if($space->status != 'closed' and $browseType != 'involved') common::printLink('kanban', 'create', "spaceID={$space->id}&type={$space->type}", '<i class="icon icon-plus"></i> ' . $lang->kanban->create, '', "class='iframe' data-width='75%'", '', true);?>
<?php if($space->status != 'closed' and $browseType != 'involved' and !empty($unclosedSpace)) common::printLink('kanban', 'create', "spaceID={$space->id}&type={$space->type}", '<i class="icon icon-plus"></i> ' . $lang->kanban->create, '', "class='iframe' data-width='75%'", '', true);?>
<?php common::printLink('kanban', 'editSpace', "spaceID={$space->id}", '<i class="icon icon-cog-outline"></i> ' . $lang->kanban->setting, '', "class='iframe' data-width='75%'", '', true);?>
<?php common::printLink('kanban', 'closeSpace', "spaceID={$space->id}", '<i class="icon icon-off"></i> ' . $lang->close, '', "class='iframe {$class}'", '', true);?>
<?php common::printLink('kanban', 'deleteSpace', "spaceID={$space->id}", '<i class="icon icon-trash"></i> ' . $lang->delete, 'hiddenwin', '', '', true);?>
+2
View File
@@ -14,6 +14,7 @@
<?php include '../../common/view/kanban.html.php';?>
<?php
$app->loadLang('execution');
$laneCount = 0;
foreach($regions as $region) $laneCount += $region->laneCount;
@@ -23,6 +24,7 @@ js::set('kanbanLang', $lang->kanban);
js::set('kanbanlaneLang', $lang->kanbanlane);
js::set('kanbancolumnLang', $lang->kanbancolumn);
js::set('kanbancardLang', $lang->kanbancard);
js::set('executionLang', $lang->execution);
js::set('kanbanID', $kanban->id);
js::set('laneCount', $laneCount);
js::set('userList', $userList);
+9 -7
View File
@@ -47,10 +47,11 @@ class releaseModel extends model
* @param int $branch
* @param string $type
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getList($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc')
public function getList($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc', $pager = null)
{
return $this->dao->select('t1.*, t2.name as productName, t3.id as buildID, t3.name as buildName, t3.project, t4.name as projectName')
->from(TABLE_RELEASE)->alias('t1')
@@ -62,6 +63,7 @@ class releaseModel extends model
->beginIF($type != 'all')->andWhere('t1.status')->eq($type)->fi()
->andWhere('t1.deleted')->eq(0)
->orderBy($orderBy)
->page($pager)
->fetchAll();
}
@@ -480,13 +482,13 @@ class releaseModel extends model
}
/**
* Judge btn is clickable or not.
*
* @param int $release
* @param string $action
* Judge btn is clickable or not.
*
* @param int $release
* @param string $action
* @static
* @access public
* @return bool
* @return bool
*/
public static function isClickable($release, $action)
{
@@ -498,7 +500,7 @@ class releaseModel extends model
/**
* Send mail to release related users.
*
*
* @param int $releaseID
* @access public
* @return void
+1 -1
View File
@@ -51,7 +51,7 @@ class todoModel extends model
if($todo->pri == 'low') $todo->pri = 3;
}
if($todo->type != 'custom')
if($todo->type != 'custom' and $todo->idvalue)
{
$type = $todo->type;
$object = $this->loadModel($type)->getByID($this->post->$type);