Merge branch 'master' into 'Fixbug'
# Conflicts: # module/kanban/js/view.js
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
|
||||
if(!function_exists('getWebRoot')){function getWebRoot(){}}
|
||||
|
||||
/* 基本设置。Basic settings. */
|
||||
$config->version = '16.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->version = '16.3'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
|
||||
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
|
||||
$config->timezone = 'Asia/Shanghai'; // 时区设置。 The time zone setting, for more see http://www.php.net/manual/en/timezones.php.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1,5 +1,6 @@
|
||||
ALTER TABLE `zt_kanbanspace` ADD `type` varchar(50) NOT NULL AFTER `name`;
|
||||
UPDATE `zt_kanbanspace` SET `type` = 'cooperation', `whitelist` = '' WHERE `type` = '';
|
||||
UPDATE `zt_kanbanspace` SET `type` = 'cooperation' WHERE `type` = '';
|
||||
UPDATE `zt_kanban` SET `team` = CONCAT(team, ',', whitelist) where `whitelist` != '';
|
||||
|
||||
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`;
|
||||
|
||||
@@ -629,6 +629,8 @@ CREATE TABLE IF NOT EXISTS `zt_job` (
|
||||
`server` mediumint(8) unsigned NOT NULL,
|
||||
`pipeline` varchar(500) NOT NULL,
|
||||
`triggerType` varchar(255) NOT NULL,
|
||||
`sonarqubeServer` mediumint(8) unsigned NOT NULL,
|
||||
`projectKey` varchar(255) NOT NULL,
|
||||
`svnDir` varchar(255) NOT NULL,
|
||||
`atDay` varchar(255) DEFAULT NULL,
|
||||
`atTime` varchar(10) DEFAULT NULL,
|
||||
@@ -676,9 +678,11 @@ CREATE TABLE `zt_kanban` (
|
||||
`acl` char(30) NOT NULL DEFAULT 'open',
|
||||
`whitelist` text NOT NULL,
|
||||
`archived` enum('0', '1') NOT NULL DEFAULT '0',
|
||||
`performable` enum ('0', '1') NOT NULL DEFAULT '0',
|
||||
`status` enum('active','closed') NOT NULL default 'active',
|
||||
`order` mediumint(8) NOT NULL DEFAULT '0',
|
||||
`displayCards` smallint(6) NOT NULL default '0',
|
||||
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
|
||||
`object` varchar(255) NOT NULL,
|
||||
`createdBy` char(30) NOT NULL,
|
||||
`createdDate` datetime NOT NULL,
|
||||
@@ -712,6 +716,7 @@ CREATE TABLE `zt_kanbancard` (
|
||||
`fromID` mediumint(8) unsigned NOT NULL,
|
||||
`fromType` varchar(30) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`status` varchar(30) NOT NULL,
|
||||
`pri` mediumint(8) unsigned NOT NULL,
|
||||
`assignedTo` text NOT NULL,
|
||||
`desc` text NOT NULL,
|
||||
@@ -1025,6 +1030,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
|
||||
`whitelist` text NOT NULL,
|
||||
`order` mediumint(8) unsigned NOT NULL,
|
||||
`displayCards` smallint(6) NOT NULL default '0',
|
||||
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `parent` (`parent`),
|
||||
|
||||
@@ -1,3 +1,62 @@
|
||||
2022-01-26 16.3
|
||||
完成的需求
|
||||
29706 研发看板相关操作支持平滑刷新方式呈现
|
||||
30102 我的空间调整为私人空间
|
||||
30103 空间检索标签增加新的空间类型和看板维度的标签
|
||||
30197 数据归并页面中产品线列表增加滚动条功能
|
||||
29490 实现列的拖动排序功能
|
||||
30125 泳道组中创建卡片时可以选择所属泳道
|
||||
30126 泳道组中支持批量创建卡片
|
||||
30131 通用看板支持列宽度设置功能
|
||||
30132 任务看板支持列宽度设置功能
|
||||
30133 执行看板支持列宽度设置功能
|
||||
30134 通用看板支持导入功能设置
|
||||
30137 通用看板列中支持导入产品计划
|
||||
30138 实现产品计划卡片在看板中的展示方式
|
||||
30139 通用看板列中支持导入产品发布
|
||||
30140 实现产品发布卡片在看板中的展示方式
|
||||
30141 通用看板列中支持导入项目版本
|
||||
30142 实现版本卡片在看板中的展示方式
|
||||
30147 通用看板列中支持导入项目执行
|
||||
30149 实现执行卡片在看板中的展示方式
|
||||
30156 通用看板列中支持转入卡片
|
||||
30167 通用看板支持完成功能设置
|
||||
30170 在看板中实现卡片完成状态的展示方式
|
||||
30171 卡片的设置菜单中增加完成/激活卡片操作
|
||||
29861 在禅道SonarQube项目列表页面中添加执行SonarQube按钮
|
||||
29860 实现禅道中删除SonarQube项目的功能
|
||||
29858 实现禅道中SonarQube项目列表页面的搜索功能
|
||||
29857 实现禅道SonarQube项目列表页面返回功能
|
||||
29856 实现禅道中SonarQube项目列表页面
|
||||
29850 在禅道SonarQube服务器列表页面添加SonarQube项目入口
|
||||
29848 实现禅道中删除SonarQube服务器功能
|
||||
29847 实现禅道中添加SonarQube服务器功能
|
||||
29846 实现禅道中SonarQube服务器列表页面
|
||||
29844 在禅道中添加管理SonarQube服务器的入口
|
||||
29227 在禅道版本库列表中添加执行SonarQube按钮
|
||||
29226 实现在禅道中编辑SonarQube服务器的功能
|
||||
26572 实现禅道中配置SonarQube构建任务的功能
|
||||
30314 实现在禅道中检查禅道用户是否与GitLab用户绑定的功能
|
||||
30312 实现禅道中删除GitLab合并请求权限与GitLab保持一致的功能
|
||||
30311 实现禅道中编辑GitLab合并请求权限与GitLab保持一致的功能
|
||||
30302 实现在禅道中创建合并请求服务器权限控制功能
|
||||
30301 实现在禅道中创建合并请求项目权限控制功能
|
||||
30228 实现禅道中GitLab合并请求数据按权限展示的功能
|
||||
30227 创建禅道GitLab服务器时需验证Token是否具有GitLab管理员权限
|
||||
30226 使用禅道所绑定的GitLab用户进行合并请求的创建和审批操作
|
||||
30099 实现禅道中编辑GitLab群组权限与GitLab保持一致的功能
|
||||
30098 实现禅道中删除GitLab群组权限与GitLab保持一致的功能
|
||||
30097 实现禅道中GitLab群组的可见权限功能
|
||||
30096 实现禅道中标签保护管理权限与GitLab权限保持一致的功能
|
||||
30095 实现禅道中删除GitLab项目权限与GitLab保持一致的功能
|
||||
30094 实现禅道中分支保护管理权限与GitLab权限保持一致的功能
|
||||
30093 实现禅道中编辑GitLab项目权限与GitLab保持一致的功能
|
||||
30092 实现禅道中GitLab项目的可见权限功能
|
||||
26573 实现在禅道中查看Sonar代码检查结果的功能
|
||||
修复的BUG
|
||||
19014 有时登录后 session 失效登出的问题
|
||||
19015 在未打开客户端集成时,不展示右下角的聊天入口
|
||||
|
||||
2022-01-17 16.2
|
||||
28397 选择项目管理方式弹窗中增加专业研发看板
|
||||
28398 实现专业研发看板项目的创建功能
|
||||
|
||||
@@ -956,7 +956,7 @@ class bugModel extends model
|
||||
{
|
||||
$this->loadModel('kanban');
|
||||
if(!isset($output['toColID'])) $this->kanban->updateLane($oldBug->execution, 'bug', $bugID);
|
||||
if(isset($output['toColID'])) $this->kanban->moveCard($bugID, $output['fromColID'], $output['toColID'], $output['fromLaneID'], $output['toLaneID']);
|
||||
if(isset($output['toColID'])) $this->kanban->moveCard($bugID, $output['fromColID'], $output['toColID'], $output['fromLaneID'], $output['toLaneID'], $oldBug->execution);
|
||||
}
|
||||
return common::createChanges($oldBug, $bug);
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@ class buildModel extends model
|
||||
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id')
|
||||
->leftJoin(TABLE_BRANCH)->alias('t4')->on('t1.branch = t4.id')
|
||||
->where('t1.project')->eq((int)$projectID)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->where('t1.deleted')->eq(0)
|
||||
->andWhere('t1.project')->ne(0)
|
||||
->beginIF($projectID)->andWhere('t1.project')->eq((int)$projectID)->fi()
|
||||
->beginIF($type == 'product' and $param)->andWhere('t1.product')->eq($param)->fi()
|
||||
->beginIF($type == 'bysearch')->andWhere($param)->fi()
|
||||
->orderBy($orderBy)
|
||||
@@ -121,21 +121,23 @@ class buildModel extends model
|
||||
* @param string $type all|product|bysearch
|
||||
* @param int|string $param productID|buildQuery
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getExecutionBuilds($executionID, $type = '', $param = '', $orderBy = 't1.date_desc,t1.id_desc')
|
||||
public function getExecutionBuilds($executionID, $type = '', $param = '', $orderBy = 't1.date_desc,t1.id_desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.name as executionName, t3.name as productName, t4.name as branchName')
|
||||
->from(TABLE_BUILD)->alias('t1')
|
||||
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id')
|
||||
->leftJoin(TABLE_BRANCH)->alias('t4')->on('t1.branch = t4.id')
|
||||
->where('t1.execution')->eq((int)$executionID)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->where('t1.deleted')->eq(0)
|
||||
->beginIF($executionID)->andWhere('t1.execution')->eq((int)$executionID)->fi()
|
||||
->beginIF($type == 'product' and $param)->andWhere('t1.product')->eq($param)->fi()
|
||||
->beginIF($type == 'bysearch')->andWhere($param)->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
|
||||
@@ -3610,17 +3610,18 @@ class execution extends control
|
||||
* @param string $enterTime
|
||||
* @param string $browseType
|
||||
* @param string $groupBy
|
||||
* @param string $from execution|RD
|
||||
* @access public
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '')
|
||||
public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution')
|
||||
{
|
||||
$enterTime = date('Y-m-d H:i:s', $enterTime);
|
||||
$lastEditedTime = $this->dao->select("max(lastEditedTime) as lastEditedTime")->from(TABLE_KANBANLANE)->where('execution')->eq($executionID)->fetch('lastEditedTime');
|
||||
|
||||
if($lastEditedTime > $enterTime or $groupBy != 'default')
|
||||
{
|
||||
$kanbanGroup = $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy);
|
||||
$kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy);
|
||||
die(json_encode($kanbanGroup));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
.kanban-card > .actions > a {display: block; float: left; width: 20px; height: 20px; line-height: 20px; text-align: center; border-radius: 4px; opacity: .7;}
|
||||
.kanban-card > .actions > a:hover {background-color: rgba(0,0,0,.075); opacity: 1;}
|
||||
|
||||
#kanban .kanban-card[data-scale-size="4"] {padding: 8px;}
|
||||
#kanban .kanban-card[data-scale-size="4"] {padding: 8px !important; min-height: 47px !important; height: 47px !important;}
|
||||
#kanban .kanban-card[data-scale-size="3"] {padding: 3px 4px;}
|
||||
#kanban .kanban-card[data-scale-size="3"] > .title {white-space: normal; max-height: 100%;}
|
||||
#kanban .kanban-card[data-scale-size="2"] {padding: 3px 4px; overflow: hidden;}
|
||||
|
||||
@@ -1294,6 +1294,27 @@ $(function()
|
||||
if(sortType == 'lane') $cards.show();
|
||||
}
|
||||
});
|
||||
|
||||
/* Ajax update kanban. */
|
||||
if(groupBy == 'default')
|
||||
{
|
||||
var lastUpdateData;
|
||||
setInterval(function()
|
||||
{
|
||||
$.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD'), function(data)
|
||||
{
|
||||
if(data && lastUpdateData !== data)
|
||||
{
|
||||
lastUpdateData = data;
|
||||
kanbanData = $.parseJSON(data);
|
||||
for(var region in kanbanData)
|
||||
{
|
||||
updateRegion(region, kanbanData[region]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 10000);
|
||||
}
|
||||
});
|
||||
|
||||
/** Calculate column height */
|
||||
|
||||
@@ -41,6 +41,7 @@ js::set('laneCount', $laneCount);
|
||||
js::set('userList', $userList);
|
||||
js::set('noAssigned', $lang->kanbancard->noAssigned);
|
||||
js::set('users', $users);
|
||||
js::set('entertime', time());
|
||||
js::set('displayCards', $execution->displayCards);
|
||||
js::set('fluidBoard', $execution->fluidBoard);
|
||||
js::set('colorListLang', $lang->kanbancard->colorList);
|
||||
@@ -136,7 +137,7 @@ js::set('hasTaskButton', $hasTaskButton);
|
||||
if(common::hasPriv('execution', 'delete')) $kanbanActions .= '<li>' . html::a(helper::createLink('execution', 'delete', "executionID=$execution->id"), '<i class="icon icon-trash"></i>' . $lang->delete, 'hiddenwin', "class='btn btn-link text-left'") . '</li>';
|
||||
if($kanbanActions)
|
||||
{
|
||||
$actions .= ((common::hasPriv('kanban', 'createRegion') or common::hasPriv('kanban', 'setLaneHeight')) and (common::hasPriv('execution', 'edit') or common::hasPriv('execution', 'delete') or !empty($executionActions))) ? "<div class='divider'></div>" . $kanbanActions : $kanbanActions;
|
||||
$actions .= ((common::hasPriv('kanban', 'createRegion') or common::hasPriv('kanban', 'setLaneHeight') or common::hasPriv('kanban', 'setColumnWidth')) and (common::hasPriv('execution', 'edit') or common::hasPriv('execution', 'delete') or !empty($executionActions))) ? "<div class='divider'></div>" . $kanbanActions : $kanbanActions;
|
||||
}
|
||||
$actions .= "</ul>";
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
$width = $this->app->getClientLang() == 'en' ? '70%' : '60%';
|
||||
echo '<li>' .html::a($this->createLink('kanban', 'setLaneHeight', "executionID=$executionID&from=execution", '', true), "<i class='icon icon-size-height'></i> " . $lang->kanban->laneHeight, '', "class='iframe btn btn-link' title='{$lang->kanban->laneHeight}' data-width=$width") . '</li>';
|
||||
}
|
||||
if(common::hasPriv('kanban', 'setColumnWidth')) echo '<li>' .html::a($this->createLink('kanban', 'setColumnWidth', "executionID=$executionID&from=execution", '', true), "<i class='icon icon-size-width'></i> " . $lang->kanban->columnWidth, '', "class='iframe btn btn-link' title='{$lang->kanban->laneHeight}' data-width=30%") . '</li>';
|
||||
if(common::hasPriv('kanban', 'setColumnWidth')) echo '<li>' .html::a($this->createLink('kanban', 'setColumnWidth', "executionID=$executionID&from=execution", '', true), "<i class='icon icon-size-width'></i> " . $lang->kanban->columnWidth, '', "class='iframe btn btn-link' title='{$lang->kanban->columnWidth}' data-width=30%") . '</li>';
|
||||
if(common::hasPriv('execution', 'printKanban')) echo '<li>' .html::a($this->createLink('execution', 'printKanban', "executionID=$executionID"), "<i class='icon icon-printer muted'></i> " . $lang->execution->printKanban, '', "class='iframe btn btn-link' id='printKanban' title='{$lang->execution->printKanban}' data-width='500'") . '</li>';
|
||||
echo '<li>' .html::a('javascript:fullScreen()', "<i class='icon icon-fullscreen muted'></i> " . $lang->execution->fullScreen, '', "class='btn btn-link' title='{$lang->execution->fullScreen}' data-width='500'") . '</li>';
|
||||
echo '</ul></div>';
|
||||
|
||||
@@ -314,15 +314,15 @@ class gitlab extends control
|
||||
}
|
||||
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, $orderBy);
|
||||
$adminGroups = $this->gitlab->apiGetGroups($gitlabID, $orderBy, $this->config->gitlab->accessLevel['owner']);
|
||||
$adminGroups = $this->gitlab->apiGetGroups($gitlabID, $orderBy, 'owner');
|
||||
|
||||
$adminGropuIDList = array();
|
||||
foreach($adminGroups as $group) $adminGropuIDList[] = $group->id;
|
||||
$adminGroupIDList = array();
|
||||
foreach($adminGroups as $group) $adminGroupIDList[] = $group->id;
|
||||
|
||||
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseGroup;
|
||||
$this->view->gitlabID = $gitlabID;
|
||||
$this->view->gitlabGroupList = $groups;
|
||||
$this->view->adminGropuIDList = $adminGropuIDList;
|
||||
$this->view->adminGroupIDList = $adminGroupIDList;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->display();
|
||||
}
|
||||
@@ -656,7 +656,7 @@ class gitlab extends control
|
||||
|
||||
/* Get group id list by gitlab user that the user is maintainer. */
|
||||
$groupIDList = array(0 => 0);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', $this->config->gitlab->accessLevel['maintainer']);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', 'maintainer');
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
|
||||
foreach($result['projects'] as $key => $project)
|
||||
|
||||
+28
-12
@@ -61,15 +61,24 @@ class gitlabModel extends model
|
||||
/**
|
||||
* Get gitlab api base url by gitlab id.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $gitlabID
|
||||
* @param bool $sudo
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getApiRoot($id)
|
||||
public function getApiRoot($gitlabID, $sudo = true)
|
||||
{
|
||||
$gitlab = $this->getByID($id);
|
||||
$gitlab = $this->getByID($gitlabID);
|
||||
if(!$gitlab) return '';
|
||||
return rtrim($gitlab->url, '/') . '/api/v4%s' . "?private_token={$gitlab->token}";
|
||||
|
||||
$sudoParam = '';
|
||||
if($sudo == true and !$this->app->user->admin)
|
||||
{
|
||||
$openID = $this->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
|
||||
if($openID) $sudoParam = "&sudo={$openID}";
|
||||
}
|
||||
|
||||
return rtrim($gitlab->url, '/') . '/api/v4%s' . "?private_token={$gitlab->token}" . $sudoParam;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,11 +601,18 @@ class gitlabModel extends model
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function apiGetGroups($gitlabID, $orderBy, $minAccessLevel = 0)
|
||||
public function apiGetGroups($gitlabID, $orderBy, $minRole = '')
|
||||
{
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$url = sprintf($apiRoot, "/groups");
|
||||
if($minAccessLevel > 0) $url .= "&min_access_level=$minAccessLevel";
|
||||
if($minRole == 'owner')
|
||||
{
|
||||
$url .= '&owned=true';
|
||||
}
|
||||
elseif(!empty($minRole))
|
||||
{
|
||||
$url .= "&min_access_level=$this->config->gitlab->accessLevel[$minRole]";
|
||||
}
|
||||
|
||||
list($order, $sort) = explode('_', $orderBy);
|
||||
|
||||
@@ -1088,7 +1104,7 @@ class gitlabModel extends model
|
||||
*/
|
||||
public function apiGetHooks($gitlabID, $projectID)
|
||||
{
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$apiRoot = $this->getApiRoot($gitlabID, false);
|
||||
$apiPath = "/projects/{$projectID}/hooks";
|
||||
$url = sprintf($apiRoot, $apiPath);
|
||||
|
||||
@@ -1107,7 +1123,7 @@ class gitlabModel extends model
|
||||
*/
|
||||
public function apiGetHook($gitlabID, $projectID, $hookID)
|
||||
{
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$apiRoot = $this->getApiRoot($gitlabID, false);
|
||||
$apiPath = "/projects/$projectID/hooks/$hookID)";
|
||||
$url = sprintf($apiRoot, $apiPath);
|
||||
|
||||
@@ -1133,7 +1149,7 @@ class gitlabModel extends model
|
||||
|
||||
foreach($hook as $index => $item) $newHook->$index= $item;
|
||||
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$apiRoot = $this->getApiRoot($gitlabID, false);
|
||||
$url = sprintf($apiRoot, "/projects/{$projectID}/hooks");
|
||||
|
||||
return json_decode(commonModel::http($url, $newHook));
|
||||
@@ -1151,7 +1167,7 @@ class gitlabModel extends model
|
||||
*/
|
||||
public function apiDeleteHook($gitlabID, $projectID, $hookID)
|
||||
{
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$apiRoot = $this->getApiRoot($gitlabID, false);
|
||||
$url = sprintf($apiRoot, "/projects/{$projectID}/hooks/{$hookID}");
|
||||
|
||||
return json_decode(commonModel::http($url, null, array(CURLOPT_CUSTOMREQUEST => 'delete')));
|
||||
@@ -1210,7 +1226,7 @@ class gitlabModel extends model
|
||||
*/
|
||||
public function apiUpdateHook($gitlabID, $projectID, $hookID, $hook)
|
||||
{
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$apiRoot = $this->getApiRoot($gitlabID, false);
|
||||
|
||||
if(!isset($hook->url)) return false;
|
||||
|
||||
@@ -2777,7 +2793,7 @@ class gitlabModel extends model
|
||||
{
|
||||
if(empty($groupIDList))
|
||||
{
|
||||
$groups = $this->apiGetGroups($gitlabID, 'name_asc', $accessLevel);
|
||||
$groups = $this->apiGetGroups($gitlabID, 'name_asc', $maxRole);
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
<?php else:?>
|
||||
<?php echo '<span class="text-red">' . $lang->gitlab->bindedError . '</span>';?>
|
||||
<?php endif;?>
|
||||
<?php else:?>
|
||||
<?php echo $lang->gitlab->notBind;?>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<td class='text' title='<?php echo substr($gitlabGroup->created_at, 0, 10);?>'><?php echo substr($gitlabGroup->created_at, 0, 10);?></td>
|
||||
<td class='c-actions text-left'>
|
||||
<?php
|
||||
$adminClass = ($app->user->admin or in_array($gitlabGroup->id, $adminGropuIDList)) ? '' : 'disabled';
|
||||
$adminClass = ($app->user->admin or in_array($gitlabGroup->id, $adminGroupIDList)) ? '' : 'disabled';
|
||||
common::printLink('gitlab', 'manageGroupMembers', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", "<i class='icon icon-team'></i> ", '',"title='{$lang->gitlab->group->manageMembers}' class='btn btn-primary'");
|
||||
common::printLink('gitlab', 'editGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", "<i class='icon icon-edit'></i> ", '', "title='{$lang->gitlab->group->edit}' class='btn btn-primary {$adminClass}'");
|
||||
if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'deleteGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->gitlab->deleteGroup}' class='btn {$adminClass}'");
|
||||
|
||||
@@ -669,8 +669,6 @@ $lang->resource->kanban->assigntoCard = 'assigntoCard';
|
||||
//$lang->resource->kanban->copyCard = 'copyCard';
|
||||
$lang->resource->kanban->deleteCard = 'deleteCard';
|
||||
$lang->resource->kanban->moveCard = 'moveCard';
|
||||
$lang->resource->kanban->finishCard = 'finishCard';
|
||||
$lang->resource->kanban->activateCard = 'activateCard';
|
||||
$lang->resource->kanban->setCardColor = 'setCardColor';
|
||||
$lang->resource->kanban->laneMove = 'laneMove';
|
||||
$lang->resource->kanban->viewArchivedColumn = 'viewArchivedColumn';
|
||||
|
||||
@@ -21,6 +21,8 @@ class jobModel extends model
|
||||
public function getByID($id)
|
||||
{
|
||||
$job = $this->dao->select('*')->from(TABLE_JOB)->where('id')->eq($id)->fetch();
|
||||
if(empty($job)) return new stdClass();
|
||||
|
||||
if(strtolower($job->engine) == 'gitlab')
|
||||
{
|
||||
$pipeline = json_decode($job->pipeline);
|
||||
|
||||
+29
-19
@@ -168,7 +168,7 @@ class kanban extends control
|
||||
unset($this->lang->kanbanspace->featureBar['involved']);
|
||||
|
||||
$space = $this->kanban->getSpaceById($spaceID);
|
||||
$spaceUsers = $spaceID == 0 ? ',' : trim($space->owner) . ',' . trim($space->team) . ',' . trim($space->whitelist);
|
||||
$spaceUsers = $spaceID == 0 ? ',' : trim($space->owner) . ',' . trim($space->team);
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
|
||||
|
||||
$this->view->users = $users;
|
||||
@@ -204,11 +204,11 @@ class kanban extends control
|
||||
|
||||
$kanban = $this->kanban->getByID($kanbanID);
|
||||
$space = $this->kanban->getSpaceById($kanban->space);
|
||||
$spaceUsers = trim($space->owner) . ',' . trim($space->team) . ',' . trim($space->whitelist);
|
||||
$spaceUsers = trim($space->owner) . ',' . trim($space->team);
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
|
||||
|
||||
$this->view->users = $users;
|
||||
$this->view->spacePairs = array(0 => '') + $this->kanban->getSpacePairs($space->type);
|
||||
$this->view->spacePairs = array(0 => '') + array($kanban->space => $space->name) + $this->kanban->getSpacePairs($space->type);
|
||||
$this->view->kanban = $kanban;
|
||||
$this->view->type = $space->type;
|
||||
|
||||
@@ -801,7 +801,11 @@ class kanban extends control
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $backLink));
|
||||
}
|
||||
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
|
||||
$kanban = $this->kanban->getByID($kanbanID);
|
||||
$space = $this->kanban->getSpaceById($kanban->space);
|
||||
$spaceUsers = $kanban->space == 0 ? ',' : trim($space->owner) . ',' . trim($space->team);
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
|
||||
|
||||
$lanePairs = $this->kanban->getLanePairsByGroup($groupID);
|
||||
|
||||
$lanePairs['ditto'] = $this->lang->kanbancard->ditto;
|
||||
@@ -941,7 +945,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID)
|
||||
public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0)
|
||||
{
|
||||
$this->kanban->moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
@@ -963,7 +967,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedKanbanID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1)
|
||||
public function importCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedKanbanID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -1016,7 +1020,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importPlan($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1)
|
||||
public function importPlan($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
@@ -1068,7 +1072,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importRelease($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1)
|
||||
public function importRelease($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
@@ -1090,10 +1094,7 @@ class kanban extends control
|
||||
$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->products = array($this->lang->kanban->allProducts) + $this->product->getPairs();
|
||||
$this->view->selectedProductID = $selectedProductID;
|
||||
$this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
|
||||
$this->view->releases2Imported = $this->release->getList($selectedProductID, 'all', 'all', 't1.date_desc', $pager);
|
||||
@@ -1120,7 +1121,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importBuild($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1)
|
||||
public function importBuild($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
@@ -1135,20 +1136,29 @@ class kanban extends control
|
||||
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;
|
||||
$builds2Imported = array();
|
||||
$projects = array($this->lang->kanban->allProjects);
|
||||
if($this->config->systemMode == 'classic')
|
||||
{
|
||||
$projects += $this->loadModel('execution')->getPairs();
|
||||
$builds2Imported = $this->build->getExecutionBuilds($selectedProjectID, '', '', 't1.date_desc,t1.id_desc', $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$projects += $this->loadModel('project')->getPairsByProgram('', 'all', false, 'order_asc', 'kanban');
|
||||
$builds2Imported = $this->build->getProjectBuilds($selectedProjectID, 'all', 0, 't1.date_desc,t1.id_desc', $pager);
|
||||
}
|
||||
|
||||
$this->view->projects = $projectPairs;
|
||||
$this->view->projects = $projects;
|
||||
$this->view->selectedProjectID = $selectedProjectID;
|
||||
$this->view->builds2Imported = $builds2Imported;
|
||||
$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;
|
||||
@@ -1173,7 +1183,7 @@ class kanban extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importExecution($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 30, $pageID = 1)
|
||||
public function importExecution($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
.checked > .icon {display: inline-block;}
|
||||
.p-10px {padding: 10px}
|
||||
#kanbanActionMenu li a {text-align: left}
|
||||
|
||||
.importModal {min-height: 300px;}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
.region .kanban-lane-items {overflow: overlay !important; padding-bottom: 10px;}
|
||||
|
||||
.region .kanban-item {position: relative}
|
||||
.region .kanban-item > .kanban-card > .title {line-height: 18px;}
|
||||
.region .kanban-item > .kanban-card > .title {display: block; line-height: 18px;}
|
||||
.region .kanban-item > .kanban-card > .title:hover {color: #2272eb}
|
||||
.region .kanban-item > .kanban-card > .info {margin-top: 4px; position: relative;}
|
||||
.region .kanban-item > .kanban-card > .info > .pri {height: 14px; border-width: 1px; font-size: 12px; line-height: 12px; min-width: 14px; padding: 0 1px;}
|
||||
@@ -103,11 +103,12 @@
|
||||
.kanban-card .header .executionName {display: flex; width: 100%; float: left;}
|
||||
.kanban-card .header .executionName .title {padding-right: 0px; margin-right: 5px; overflow: hidden; white-space: nowrap;}
|
||||
.kanban-card .header .executionName > span {flex: none;}
|
||||
.execInfo, .releaseInfo, .productplanInfo {margin-top: 23px;}
|
||||
.execInfo, .releaseInfo, .productplanInfo {margin-top: 22px;}
|
||||
.label-wait {background: #EFEFEF !important; color: #838A9D;}
|
||||
.label-doing {background: #f8d2d2 !important; color: #e64b4c;}
|
||||
.label-suspended {background: #fff3d9 !important; color: #ff9800;}
|
||||
.label-future {background: #EFEFEF !important; color: #838A9D; border-radius: 9px}
|
||||
.label-done {background: #dfe9d8 !important; color: #429b16;}
|
||||
.label-closed, .label-terminate {background: #e5e5e5 !important; color: #b8b8b8;}
|
||||
.label-deleted {background: #ff5d5d !important; color: #fff;}
|
||||
.label-normal {background: #e1e8d9 !important; color: #9abe76;}
|
||||
|
||||
@@ -68,3 +68,20 @@ function setTargetLane(targetLaneID)
|
||||
{
|
||||
$('#targetLane').val(targetLaneID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Jump to the view page.
|
||||
*
|
||||
* @param string $module
|
||||
* @param int $objectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function locateView(module, objectID)
|
||||
{
|
||||
var dataApp = 'kanban';
|
||||
if(module == 'productplan' || module == 'release') dataApp = 'product';
|
||||
if(module == 'execution') dataApp = 'execution';
|
||||
if(module == 'build') dataApp = 'project';
|
||||
parent.$.apps.open(createLink(module, 'view', 'objectID=' + objectID), dataApp);
|
||||
}
|
||||
|
||||
+16
-13
@@ -332,7 +332,9 @@ function renderKanbanItem(item, $item)
|
||||
$title.text(item.name).css('color', '');
|
||||
$item.children('.label').hide();
|
||||
}
|
||||
if(printMoreBtn)
|
||||
|
||||
var $actions = $item.children('.actions');
|
||||
if(printMoreBtn && !$actions.length)
|
||||
{
|
||||
$(
|
||||
[
|
||||
@@ -438,9 +440,10 @@ function renderExecutionItem(item, $item)
|
||||
var $title = $titleBox.children('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
var icon = mode == 'new' ? 'run' : 'project';
|
||||
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 = $('<div class="title"><i class="icon icon-run"></i>' + item.name + '</div>').appendTo($titleBox);
|
||||
if(privs.includes('viewExecution') && item.deleted == '0') $title = $('<a class="title"><i class="icon icon-' + icon + '"></i>' + item.name + '</a>').appendTo($titleBox).attr('href', createLink('execution', viewMethod, 'executionID=' + item.fromID));
|
||||
if(!privs.includes('viewExecution') || item.deleted == '1') $title = $('<div class="title"><i class="icon icon-' + icon + '"></i>' + item.name + '</div>').appendTo($titleBox);
|
||||
}
|
||||
$title.attr('title', item.name);
|
||||
|
||||
@@ -511,7 +514,7 @@ function renderReleaseItem(item, $item)
|
||||
var $title = $item.children('.releaseTitle');
|
||||
if(!$title.length)
|
||||
{
|
||||
if(privs.includes('viewRelease') && item.deleted == '0') $title = $('<a class="releaseTitle"><i class="icon icon-publish"></i>' + item.name + '</a>').appendTo($item).attr('href', createLink('release', 'view', 'releaseID=' + item.fromID));
|
||||
if(privs.includes('viewRelease') && item.deleted == '0') $title = $('<a class="releaseTitle title"><i class="icon icon-publish"></i>' + item.name + '</a>').appendTo($item).attr('href', createLink('release', 'view', 'releaseID=' + item.fromID));
|
||||
if(!privs.includes('viewRelease') || item.deleted == '1') $title = $('<div class="releaseTitle"><i class="icon icon-publish"></i>' + item.name + '</div>').appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.name);
|
||||
@@ -570,7 +573,7 @@ function renderProductplanItem(item, $item)
|
||||
var $title = $item.children('.productplanTitle');
|
||||
if(!$title.length)
|
||||
{
|
||||
if(privs.includes('viewPlan') && item.deleted == '0') $title = $('<a class="productplanTitle"><i class="icon icon-delay"></i>' + item.title + '</a>').appendTo($item).attr('href', createLink('productplan', 'view', 'productplanID=' + item.fromID));
|
||||
if(privs.includes('viewPlan') && item.deleted == '0') $title = $('<a class="productplanTitle title"><i class="icon icon-delay"></i>' + item.title + '</a>').appendTo($item).attr('href', createLink('productplan', 'view', 'productplanID=' + item.fromID));
|
||||
if(!privs.includes('viewPlan') || item.deleted == '1') $title = $('<div class="productplanTitle"><i class="icon icon-delay"></i>' + item.title + '</div>').appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title);
|
||||
@@ -600,7 +603,7 @@ function renderProductplanItem(item, $item)
|
||||
var begin = $.zui.createDate(item.begin);
|
||||
var end = $.zui.createDate(item.end);
|
||||
var today = new Date();
|
||||
var labelType = end.toLocaleDateString() == today.toLocaleDateString() ? 'danger' : 'wait';
|
||||
var labelType = (item.begin <= $.zui.formatDate(today, 'yyyy-MM-dd') && item.end >= $.zui.formatDate(today, 'yyyy-MM-dd')) ? 'danger' : 'wait';
|
||||
var labelTitle = $.zui.formatDate(begin, 'MM-dd') + ' ' + productplanLang.to + ' ' + $.zui.formatDate(end, 'MM-dd');
|
||||
|
||||
if((item.begin == '2030-01-01' || item.end == '2030-01-01'))
|
||||
@@ -638,7 +641,7 @@ function renderBuildItem(item, $item)
|
||||
var $title = $item.children('.buildTitle');
|
||||
if(!$title.length)
|
||||
{
|
||||
if(privs.includes('viewBuild') && item.deleted == '0') $title = $('<a class="buildTitle"><i class="icon icon-ver"></i>' + item.name + '</a>').appendTo($item).attr('href', createLink('build', 'view', 'buildID=' + item.fromID));
|
||||
if(privs.includes('viewBuild') && item.deleted == '0') $title = $('<a class="buildTitle" data-app="project"><i class="icon icon-ver"></i>' + item.name + '</a>').appendTo($item).attr('href', createLink('build', 'view', 'buildID=' + item.fromID));
|
||||
if(!privs.includes('viewBuild') || item.deleted == '1') $title = $('<div class="buildTitle"><i class="icon icon-ver"></i>' + item.name + '</div>').appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.name);
|
||||
@@ -1082,9 +1085,9 @@ function createCardMenu(options)
|
||||
|
||||
var items = [];
|
||||
if(privs.includes('editCard')) items.push({label: kanbanLang.editCard, icon: 'edit', url: createLink('kanban', 'editCard', 'cardID=' + card.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
|
||||
if(kanban.performable == 1)
|
||||
if(privs.includes('performable') && kanban.performable == 1)
|
||||
{
|
||||
if(privs.includes('activateCard') && card.status != 'doing')
|
||||
if(card.status != 'doing')
|
||||
{
|
||||
items.push({label: kanbanLang.activateCard, icon: 'magic', onClick: function(){activateCard(card.id, card.kanban, card.region);}});
|
||||
}
|
||||
@@ -1311,10 +1314,10 @@ $(function()
|
||||
var columnID = $(this).closest('.kanban-col').data('id');
|
||||
|
||||
/* The submenu of import. */
|
||||
var importPlanLink = kanban.object.indexOf('plans') != -1 ? "<li><a class='iframe' data-toggle='modal' data-width='80%' href='" + createLink('kanban', 'importPlan', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importPlan + '</a></li>' : '';
|
||||
var importReleaseLink = kanban.object.indexOf('releases') != -1 ? "<li><a class='iframe' data-toggle='modal' data-width='80%' href='" + createLink('kanban', 'importRelease', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importRelease + '</a></li>' : '';
|
||||
var importExecutionLink = kanban.object.indexOf('executions') != -1 ? "<li><a class='iframe' data-toggle='modal' data-width='80%' href='" + createLink('kanban', 'importExecution', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importExecution + '</a></li>' : '';
|
||||
var importBuildLink = kanban.object.indexOf('builds') != -1 ? "<li><a class='iframe' data-toggle='modal' data-width='80%' href='" + createLink('kanban', 'importBuild', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importBuild + '</a></li>' : '';
|
||||
var importPlanLink = kanban.object.indexOf('plans') != -1 ? "<li><a class='iframe' data-toggle='modal'' href='" + createLink('kanban', 'importPlan', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importPlan + '</a></li>' : '';
|
||||
var importReleaseLink = kanban.object.indexOf('releases') != -1 ? "<li><a class='iframe' data-toggle='modal'' href='" + createLink('kanban', 'importRelease', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importRelease + '</a></li>' : '';
|
||||
var importExecutionLink = kanban.object.indexOf('executions') != -1 ? "<li><a class='iframe' data-toggle='modal' href='" + createLink('kanban', 'importExecution', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importExecution + '</a></li>' : '';
|
||||
var importBuildLink = kanban.object.indexOf('builds') != -1 ? "<li><a class='iframe' data-toggle='modal' href='" + createLink('kanban', 'importBuild', 'kanbanID=' + kanban.id + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importBuild + '</a></li>' : '';
|
||||
var importSubmenu = '<ul class="dropdown-menu">' + importPlanLink + importReleaseLink + importExecutionLink + importBuildLink +'</ul>';
|
||||
$('.import').parent().append(importSubmenu);
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ $lang->kanban->editLane = 'Edit Lane';
|
||||
$lang->kanban->sortLane = 'Sort Lane';
|
||||
$lang->kanban->laneHeight = 'Lane Height';
|
||||
$lang->kanban->setLaneHeight = 'Set Lane Height';
|
||||
$lang->kanban->columnWidth = 'Column Height';
|
||||
$lang->kanban->setColumnWidth = 'Set Column Height';
|
||||
$lang->kanban->columnWidth = 'Column Width';
|
||||
$lang->kanban->setColumnWidth = 'Set Column Width';
|
||||
$lang->kanban->deleteLane = 'Delete Lane';
|
||||
$lang->kanban->createColumn = 'Create Column';
|
||||
$lang->kanban->editColumn = 'Edit Column';
|
||||
@@ -74,7 +74,7 @@ $lang->kanban->importRelease = 'Release';
|
||||
$lang->kanban->importExecution = $lang->execution->common;
|
||||
$lang->kanban->importBuild = 'Build';
|
||||
$lang->kanban->allKanban = 'All Kanban';
|
||||
$lang->kanban->allProjects = 'All Projects';
|
||||
$lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Projects');
|
||||
$lang->kanban->allProducts = 'All Products';
|
||||
|
||||
/* Fields. */
|
||||
@@ -107,7 +107,7 @@ $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->selectedProject = 'Please select ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Project');
|
||||
$lang->kanban->selectedLane = 'Target Lane';
|
||||
|
||||
$lang->kanban->aclGroup['open'] = 'Open';
|
||||
|
||||
@@ -74,7 +74,7 @@ $lang->kanban->importRelease = '发布';
|
||||
$lang->kanban->importExecution = $lang->execution->common;
|
||||
$lang->kanban->importBuild = '版本';
|
||||
$lang->kanban->allKanban = '所有看板';
|
||||
$lang->kanban->allProjects = '所有项目';
|
||||
$lang->kanban->allProjects = '所有' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : '项目');
|
||||
$lang->kanban->allProducts = '所有产品';
|
||||
|
||||
/* Fields. */
|
||||
@@ -107,7 +107,7 @@ $lang->kanban->cardCountTip = '请输入卡片数量';
|
||||
|
||||
$lang->kanban->selectedKanban = '请选择看板';
|
||||
$lang->kanban->selectedProduct = '请选择产品';
|
||||
$lang->kanban->selectedProject = '请选择项目';
|
||||
$lang->kanban->selectedProject = '请选择' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : '项目');
|
||||
$lang->kanban->selectedLane = '目标泳道';
|
||||
|
||||
$lang->kanban->aclGroup['open'] = '公开';
|
||||
|
||||
+28
-14
@@ -1036,7 +1036,7 @@ class kanbanModel extends model
|
||||
->andWhere('type')->eq('common')
|
||||
->fetchAll();
|
||||
|
||||
$actions = array('editCard', 'finishCard', 'activateCard', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard', 'viewExecution', 'viewPlan', 'viewRelease', 'viewBuild');
|
||||
$actions = array('editCard', 'performable', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard', 'viewExecution', 'viewPlan', 'viewRelease', 'viewBuild');
|
||||
$cardGroup = array();
|
||||
foreach($cellList as $cell)
|
||||
{
|
||||
@@ -1677,7 +1677,7 @@ class kanbanModel extends model
|
||||
foreach($objects as $objectID => $object)
|
||||
{
|
||||
$remove = true;
|
||||
if($param == 'public') continue;
|
||||
if($objectType == 'kanbanspace' and $object->type == 'public') continue;
|
||||
|
||||
if($object->owner == $account) $remove = false;
|
||||
if(strpos(",{$object->team},", ",$account,") !== false) $remove = false;
|
||||
@@ -2807,11 +2807,11 @@ class kanbanModel extends model
|
||||
|
||||
/**
|
||||
* Set column width.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param string $from
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param string $from
|
||||
* @access public
|
||||
* @return bool|void
|
||||
* @return bool|void
|
||||
*/
|
||||
public function setColumnWidth($kanbanID, $from = 'kanban')
|
||||
{
|
||||
@@ -2830,6 +2830,9 @@ class kanbanModel extends model
|
||||
*/
|
||||
public function setHeaderActions($kanban)
|
||||
{
|
||||
$btnColor = '';
|
||||
if($this->app->cookie->theme == 'blue') $btnColor = 'style="color:#000000"';
|
||||
|
||||
$printSetHeightBtn = false;
|
||||
if(common::hasPriv('kanban', 'setLaneHeight'))
|
||||
{
|
||||
@@ -2845,17 +2848,18 @@ class kanbanModel extends model
|
||||
|
||||
$actions = '';
|
||||
$actions .= "<div class='btn-group'>";
|
||||
$actions .= "<a href='javascript:fullScreen();' id='fullScreenBtn' class='btn btn-link'><i class='icon icon-fullscreen'></i> {$this->lang->kanban->fullScreen}</a>";
|
||||
$actions .= "<a href='javascript:fullScreen();' id='fullScreenBtn' $btnColor class='btn btn-link'><i class='icon icon-fullscreen'></i> {$this->lang->kanban->fullScreen}</a>";
|
||||
|
||||
$printSettingBtn = (common::hasPriv('kanban', 'createRegion') or $printSetHeightBtn or common::hasPriv('kanban', 'performable') or common::hasPriv('kanban', 'edit') or common::hasPriv('kanban', 'close') or common::hasPriv('kanban', 'enableArchived') or common::hasPriv('kanban', 'delete'));
|
||||
|
||||
if($printSettingBtn)
|
||||
{
|
||||
$actions .= "<a data-toggle='dropdown' class='btn btn-link dropdown-toggle setting' type='button'>" . '<i class="icon icon-cog-outline"></i> ' . $this->lang->kanban->setting . '</a>';
|
||||
$actions .= "<a data-toggle='dropdown' $btnColor class='btn btn-link dropdown-toggle setting' type='button'>" . '<i class="icon icon-cog-outline"></i> ' . $this->lang->kanban->setting . '</a>';
|
||||
$actions .= "<ul id='kanbanActionMenu' class='dropdown-menu text-left'>";
|
||||
if(common::hasPriv('kanban', 'createRegion')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$kanban->id", '', true), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createRegion, '', "class='iframe btn btn-link'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'import')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'import', "kanbanID=$kanban->id", '', true), '<i class="icon icon-import"></i>' . $this->lang->kanban->import, '', "class='iframe btn btn-link'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'enableArchived')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'enableArchived', "kanbanID=$kanban->id", '', true), '<i class="icon icon-card-archive"></i>' . $this->lang->kanban->archived, '', "class='iframe btn btn-link'") . '</li>';
|
||||
$importWidth = $this->app->getClientLang() == 'en' ? '70%' : '50%';
|
||||
if(common::hasPriv('kanban', 'import')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'import', "kanbanID=$kanban->id", '', true), '<i class="icon icon-import"></i>' . $this->lang->kanban->import, '', "class='iframe btn btn-link' data-width=$importWidth") . '</li>';
|
||||
if(common::hasPriv('kanban', 'enableArchived')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'enableArchived', "kanbanID=$kanban->id", '', true), '<i class="icon icon-card-archive"></i>' . $this->lang->kanban->archived, '', "class='iframe btn btn-link' data-width=20%") . '</li>';
|
||||
if($printSetHeightBtn)
|
||||
{
|
||||
$width = $this->app->getClientLang() == 'en' ? '70%' : '60%';
|
||||
@@ -2863,7 +2867,7 @@ class kanbanModel extends model
|
||||
|
||||
}
|
||||
if(common::hasPriv('kanban', 'setColumnWidth')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'setColumnWidth', "kanbanID=$kanban->id", '', true), '<i class="icon icon-size-width"></i>' . $this->lang->kanban->columnWidth, '', "class='iframe btn btn-link' data-width=30%") . '</li>';
|
||||
if(common::hasPriv('kanban', 'performable')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '<i class="icon icon-checked"></i>' . $this->lang->kanban->doneFunction, '', "class='iframe btn btn-link'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'performable')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '<i class="icon icon-checked"></i>' . $this->lang->kanban->doneFunction, '', "class='iframe btn btn-link' data-width=20%") . '</li>';
|
||||
|
||||
$kanbanActions = '';
|
||||
$attr = $kanban->status == 'closed' ? "disabled='disabled'" : '';
|
||||
@@ -2872,7 +2876,7 @@ class kanbanModel extends model
|
||||
if(common::hasPriv('kanban', 'delete')) $kanbanActions .= '<li>' . html::a(helper::createLink('kanban', 'delete', "kanbanID=$kanban->id"), '<i class="icon icon-trash"></i>' . $this->lang->kanban->delete, 'hiddenwin', "class='btn btn-link'") . '</li>';
|
||||
if($kanbanActions)
|
||||
{
|
||||
$actions .= ((common::hasPriv('kanban', 'createRegion') or $printSetHeight or common::hasPriv('kanban', 'performable')) and (common::hasPriv('kanban', 'edit') or common::hasPriv('kanban', 'close') or common::hasPriv('kanban', 'enableArchived') or common::hasPriv('kanban', 'delete'))) ? "<div class='divider'></div>" . $kanbanActions : $kanbanActions;
|
||||
$actions .= ((common::hasPriv('kanban', 'createRegion') or $printSetHeightBtn or common::hasPriv('kanban', 'performable') or common::hasPriv('kanban', 'setColumnWidth')) and (common::hasPriv('kanban', 'edit') or common::hasPriv('kanban', 'close') or common::hasPriv('kanban', 'enableArchived') or common::hasPriv('kanban', 'delete'))) ? "<li class='divider'></li>" . $kanbanActions : $kanbanActions;
|
||||
}
|
||||
$actions .= "</ul>";
|
||||
}
|
||||
@@ -2943,12 +2947,14 @@ class kanbanModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID)
|
||||
public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0)
|
||||
{
|
||||
$fromCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($fromLaneID)->andWhere('`column`')->eq($fromColID)->fetch('cards');
|
||||
$toCell = $this->dao->select('*')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch();
|
||||
$toCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch('cards');
|
||||
|
||||
$kanbanID = $kanbanID == 0 ? $toCell->kanban : $kanbanID;
|
||||
|
||||
if(!$toCell) $this->addKanbanCell($kanbanID, $toLaneID, $toColID, 'common');
|
||||
|
||||
$fromCardList = str_replace(",$cardID,", ',', $fromCellCards);
|
||||
@@ -3048,7 +3054,15 @@ class kanbanModel extends model
|
||||
|
||||
foreach($parentCells as $cell)
|
||||
{
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq($cell->cards)
|
||||
$cards = $this->dao->select('cards')->from(TABLE_KANBANCELL)
|
||||
->where('lane')->eq($cell->lane)
|
||||
->andWhere('`column`')->eq($columnID)
|
||||
->andWhere('type')->eq('common')
|
||||
->fetch('cards');
|
||||
|
||||
$cards = $cards ? $cards . ltrim($cell->cards, ',') : $cell->cards;
|
||||
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq($cards)
|
||||
->where('lane')->eq($cell->lane)
|
||||
->andWhere('`column`')->eq($columnID)
|
||||
->andWhere('type')->eq('common')
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<form class='main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanban->archive;?></th>
|
||||
<th class='w-70px'><?php echo $lang->kanban->archive;?></th>
|
||||
<td><?php echo nl2br(html::radio('archived', $lang->kanban->archiveList, $kanban->archived));?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
<div id='mainContent' class='main-content importModal'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->kanban->importBuild;?></h2>
|
||||
<h2><?php echo $lang->kanban->importAB . $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' data-drop_direction='down'");?></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' data-drop_direction='down'");?></div>
|
||||
<div class='input-group space'>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedProject;?></span>
|
||||
<?php echo html::select('project', $projects, $selectedProjectID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
|
||||
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
<?php if($builds2Imported):?>
|
||||
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importBuildForm'>
|
||||
<table class='table table-fixed' id='buildList'>
|
||||
<thead>
|
||||
@@ -42,7 +41,7 @@
|
||||
</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-name'><?php echo $lang->execution->common;?></th>
|
||||
<th class='c-date'><?php echo $lang->build->date;?></th>
|
||||
<th class='c-user'><?php echo $lang->build->builder;?></th>
|
||||
</tr>
|
||||
@@ -59,7 +58,9 @@
|
||||
</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>
|
||||
<td title='<?php echo $build->name;?>'>
|
||||
<a href='javascript:void(0);' onclick="locateView('build', <?php echo $build->id;?>)"><?php echo $build->name;?></a>
|
||||
</td>
|
||||
<?php else:?>
|
||||
<td title='<?php echo $build->name;?>'><?php echo $build->name;?></td>
|
||||
<?php endif;?>
|
||||
@@ -71,13 +72,15 @@
|
||||
<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>
|
||||
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importAB, '', 'btn btn-default');?></div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
<?php else:?>
|
||||
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<style>#project_chosen {width: 45% !important}</style>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -22,14 +22,13 @@
|
||||
<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' data-drop_direction='down'");?></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' data-drop_direction='down'");?></div>
|
||||
<div class='input-group space'>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedKanban;?></span>
|
||||
<?php echo html::select('kanban', $kanbanPairs, $selectedKanbanID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
|
||||
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
<?php if($cards2Imported):?>
|
||||
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importCardForm'>
|
||||
<table class='table table-fixed' id='cardList'>
|
||||
<thead>
|
||||
@@ -71,13 +70,15 @@
|
||||
<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>
|
||||
<?php else:?>
|
||||
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<style>#kanban_chosen {width: 45% !important}</style>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -19,17 +19,18 @@
|
||||
<div id='mainContent' class='main-content importModal'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->kanban->importExecution;?></h2>
|
||||
<h2><?php echo $lang->kanban->importAB . $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' data-drop_direction='down'");?></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' data-drop_direction='down'");?></div>
|
||||
<div class='input-group space'>
|
||||
<?php if($config->systemMode == 'new'):?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedProject;?></span>
|
||||
<?php echo html::select('project', $projects, $selectedProjectID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
<?php endif;?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
|
||||
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
<?php if($executions2Imported):?>
|
||||
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importExecutionForm'>
|
||||
<table class='table table-fixed' id='executionList'>
|
||||
<thead>
|
||||
@@ -60,7 +61,9 @@
|
||||
<?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>
|
||||
<td title='<?php echo $execution->name;?>'>
|
||||
<a href='javascript:void(0);' onclick="locateView('execution', <?php echo $execution->id;?>)"><?php echo $execution->name;?></a>
|
||||
</td>
|
||||
<?php else:?>
|
||||
<td title='<?php echo $execution->name;?>'><?php echo $execution->name;?></td>
|
||||
<?php endif;?>
|
||||
@@ -75,13 +78,19 @@
|
||||
<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>
|
||||
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importAB, '', 'btn btn-default');?></div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
<?php else:?>
|
||||
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php if($config->systemMode == 'classic'):?>
|
||||
<style>.input-group {width: 45% !important}</style>
|
||||
<?php else:?>
|
||||
<style>#project_chosen {width: 45% !important}</style>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
<div id='mainContent' class='main-content importModal'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->kanban->importPlan;?></h2>
|
||||
<h2><?php echo $lang->kanban->importAB . $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' data-drop_direction='down'");?></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' data-drop_direction='down'");?></div>
|
||||
<div class='input-group space'>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedProduct;?></span>
|
||||
<?php echo html::select('product', $products, $selectedProductID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
|
||||
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
<?php if($plans2Imported):?>
|
||||
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importPlanForm'>
|
||||
<table class='table table-fixed' id='planList'>
|
||||
<thead>
|
||||
@@ -60,7 +59,9 @@
|
||||
<?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>
|
||||
<td title='<?php echo $plan->title;?>'>
|
||||
<a href='javascript:void(0);' onclick="locateView('productplan', <?php echo $plan->id;?>)"><?php echo $plan->title;?></a>
|
||||
</td>
|
||||
<?php else:?>
|
||||
<td title='<?php echo $plan->title;?>'><?php echo $plan->title;?></td>
|
||||
<?php endif;?>
|
||||
@@ -75,13 +76,15 @@
|
||||
<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>
|
||||
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importAB, '', 'btn btn-default');?></div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
<?php else:?>
|
||||
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<style>#product_chosen {width: 45% !important}</style>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
<div id='mainContent' class='main-content importModal'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->kanban->importRelease;?></h2>
|
||||
<h2><?php echo $lang->kanban->importAB . $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' data-drop_direction='down'");?></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' data-drop_direction='down'");?></div>
|
||||
<div class='input-group space'>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedProduct;?></span>
|
||||
<?php echo html::select('product', $products, $selectedProductID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
|
||||
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
<?php if($releases2Imported):?>
|
||||
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importReleaseForm'>
|
||||
<table class='table table-fixed' id='releaseList'>
|
||||
<thead>
|
||||
@@ -41,7 +40,9 @@
|
||||
<?php echo $lang->idAB;?>
|
||||
</th>
|
||||
<th class='c-name'><?php echo $lang->release->name;?></th>
|
||||
<?php if($config->systemMode == 'new'):?>
|
||||
<th class='c-name'><?php echo $lang->release->project;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-name'><?php echo $lang->release->build;?></th>
|
||||
<th class='c-date'><?php echo $lang->release->date;?></th>
|
||||
</tr>
|
||||
@@ -57,11 +58,15 @@
|
||||
<?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>
|
||||
<td title='<?php echo $release->name;?>'>
|
||||
<a href='javascript:void(0);' onclick="locateView('release', <?php echo $release->id;?>)"><?php echo $release->name;?></a>
|
||||
</td>
|
||||
<?php else:?>
|
||||
<td title='<?php echo $release->name;?>'><?php echo $release->name;?></td>
|
||||
<?php endif;?>
|
||||
<?php if($config->systemMode == 'new'):?>
|
||||
<td title='<?php echo $release->projectName;?>'><?php echo $release->projectName;?></td>
|
||||
<?php endif;?>
|
||||
<td title='<?php echo $release->buildName;?>'><?php echo $release->buildName;?></td>
|
||||
<td title='<?php echo $release->date;?>'><?php echo $release->date;?></td>
|
||||
</tr>
|
||||
@@ -69,13 +74,15 @@
|
||||
<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>
|
||||
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importAB, '', 'btn btn-default');?></div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
<?php else:?>
|
||||
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<style>#product_chosen {width: 45% !important}</style>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<form class='main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-110px'><?php echo $lang->kanban->doneFunction;?></th>
|
||||
<th class='w-70px text-left'><?php echo $lang->kanban->doneFunction;?></th>
|
||||
<td><?php echo nl2br(html::radio('performable', $lang->kanban->enableFinished, $kanban->performable));?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php $width = $this->app->getClientLang() == 'en' ? 'w-120px' : 'w-80px';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
@@ -19,7 +20,7 @@
|
||||
<form class='main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanban->columnWidth;?></th>
|
||||
<th class='<?php echo $width;?>'><?php echo $lang->kanban->columnWidth;?></th>
|
||||
<td><?php echo nl2br(html::radio('fluidBoard', $lang->kanbancolumn->fluidBoardList, $kanban->fluidBoard));?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<style>
|
||||
.table-form>tbody>tr>th {width: 90px;}
|
||||
</style>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
|
||||
@@ -38,6 +38,7 @@ js::set('colorListLang', $lang->kanbancard->colorList);
|
||||
js::set('colorList', $this->config->kanban->cardColorList);
|
||||
js::set('displayCards', $kanban->displayCards);
|
||||
js::set('fluidBoard', $kanban->fluidBoard);
|
||||
js::set('mode', $config->systemMode);
|
||||
|
||||
js::set('priv',
|
||||
array(
|
||||
|
||||
@@ -94,6 +94,7 @@ $lang->misc->feature->downloadFile = 'Download introduction';
|
||||
$lang->misc->feature->tutorialDesc = '<p>ZenTao 15.0 has new functions, and you know how to use it through the "<strong>Tutorial</strong>".</p><p>Click your [<span style="color: #0c60e1">Avatar-Theme-Young Blue</span>] to set it.</p>';
|
||||
$lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.</p><p>Click your [<span style="color: #0c60e1">Avatar-Theme-Young Blue</span>] to set it.</p>';
|
||||
|
||||
$lang->misc->releaseDate['16.3'] = '2022-01-26';
|
||||
$lang->misc->releaseDate['16.2'] = '2022-01-17';
|
||||
$lang->misc->releaseDate['16.1'] = '2022-01-11';
|
||||
$lang->misc->releaseDate['16.0'] = '2021-12-24';
|
||||
@@ -166,6 +167,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['16.3'][] = array('title' => 'Kanban adds related plan/release/version/iteration functions, and the detail experience is optimized, fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.2'][] = array('title' => 'Add kanban model project, fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.1'][] = array('title' => 'Plan to add status management and Kanban view, upgrade process optimization, fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.0'][] = array('title' => 'New general board, improve branch management, fix bugs.', 'desc' => '');
|
||||
|
||||
@@ -94,6 +94,7 @@ $lang->misc->feature->downloadFile = '下载新版本功能介绍文档';
|
||||
$lang->misc->feature->tutorialDesc = "<p>禅道15系列新增了多项功能,您可以通过“<strong>新手引导教程</strong>”快速了解禅道的基本使用方法。</p><p>通过鼠标经过 [<span style='color: #0c60e1'>头像-新手引导</span>],点击新手引导,即可进入新手引导教程。</p>";
|
||||
$lang->misc->feature->themeDesc = "<p>禅道15系列上线了全新的“青春蓝”主题,页面呈现更加美观,体验更加友好。</p><p>通过鼠标经过 [<span style='color: #0c60e1'>头像-主题-青春蓝</span>],点击青春蓝,即可设置成功。</p>";
|
||||
|
||||
$lang->misc->releaseDate['16.3'] = '2022-01-26';
|
||||
$lang->misc->releaseDate['16.2'] = '2022-01-17';
|
||||
$lang->misc->releaseDate['16.1'] = '2022-01-11';
|
||||
$lang->misc->releaseDate['16.0'] = '2021-12-24';
|
||||
@@ -166,6 +167,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['16.3'][] = array('title' => '看板增加关联计划/发布/版本/迭代功能,细节体验优化。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.2'][] = array('title' => '新增专业研发看板,可以创建看板模型项目,修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.1'][] = array('title' => '计划增加状态管理和看板视图,升级流程优化,修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.0'][] = array('title' => '新增通用看板,完善分支管理,修复Bug。', 'desc' => '');
|
||||
|
||||
+10
-2
@@ -247,6 +247,13 @@ class mr extends control
|
||||
$sourceBranch = $this->gitlab->apiGetSingleBranch($MR->gitlabID, $MR->sourceProject, $MR->sourceBranch);
|
||||
$targetBranch = $this->gitlab->apiGetSingleBranch($MR->gitlabID, $MR->targetProject, $MR->targetBranch);
|
||||
|
||||
$projectOwner = true;
|
||||
if(isset($MR->gitlabID) and !$this->app->user->admin)
|
||||
{
|
||||
$openID = $this->gitlab->getUserIDByZentaoAccount($MR->gitlabID, $this->app->user->account);
|
||||
if(!$projectOwner and isset($sourceProject->owner->id) and $sourceProject->owner->id == $openID) $projectOwner = true;
|
||||
}
|
||||
|
||||
$this->view->sourceProjectName = $sourceProject->name_with_namespace;
|
||||
$this->view->targetProjectName = $targetProject->name_with_namespace;
|
||||
$this->view->sourceProjectURL = isset($sourceBranch->web_url) ? $sourceBranch->web_url : '';
|
||||
@@ -260,8 +267,9 @@ class mr extends control
|
||||
$this->app->loadLang('productplan');
|
||||
$product = $this->mr->getMRProduct($MR);
|
||||
|
||||
$this->view->compile = $this->loadModel('compile')->getById($MR->compileID);
|
||||
$this->view->compileJob = $MR->jobID ? $this->job->getById($MR->jobID) : false;
|
||||
$this->view->compile = $this->loadModel('compile')->getById($MR->compileID);
|
||||
$this->view->compileJob = $MR->jobID ? $this->job->getById($MR->jobID) : false;
|
||||
$this->view->projectOwner = $projectOwner;
|
||||
|
||||
$this->view->title = $this->lang->mr->view;
|
||||
$this->view->MR = $MR;
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ class mrModel extends model
|
||||
foreach($filterProjects as $gitlabID => $projects)
|
||||
{
|
||||
$projectIDList = array_keys($projects);
|
||||
if(!empty($projectIDList)) $filterProjectSql .= "(gitlabID = {$gitlabID} and sourceProject ".helper::dbIN($projectIDList).") or ";
|
||||
if(!empty($projectIDList)) $filterProjectSql .= "(gitlabID = {$gitlabID} and sourceProject " . helper::dbIN($projectIDList) . ") or ";
|
||||
}
|
||||
|
||||
if($filterProjectSql) $filterProjectSql = '(' . substr($filterProjectSql, 0, -3) . ')'; // Remove last or.
|
||||
@@ -164,7 +164,7 @@ class mrModel extends model
|
||||
if(!empty($pipeline->queue))
|
||||
{
|
||||
$compile = $this->loadModel('compile')->getByQueue($pipeline->queue);
|
||||
$MR->compileID = $compile->id;
|
||||
$MR->compileID = $compile->id;
|
||||
$MR->compileStatus = $compile->status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +64,13 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($MRList as $MR):?>
|
||||
<?php $sourceProject = isset($projects[$MR->gitlabID][$MR->sourceProject]) ? $projects[$MR->gitlabID][$MR->sourceProject]->name_with_namespace . ':' . $MR->sourceBranch : $MR->sourceProject . ':' . $MR->sourceBranch; ?>
|
||||
<?php $targetProject = isset($projects[$MR->gitlabID][$MR->targetProject]) ? $projects[$MR->gitlabID][$MR->targetProject]->name_with_namespace . ':' . $MR->targetBranch : $MR->targetProject . ':' . $MR->targetBranch; ?>
|
||||
<tr>
|
||||
<td class='text'><?php echo $MR->id;?></td>
|
||||
<td class='text'><?php echo html::a(inlink('view', "mr={$MR->id}"), $MR->title);?></td>
|
||||
<td class='text' title='<?php echo $projects[$MR->gitlabID][$MR->sourceProject]->name_with_namespace . ':' . $MR->sourceBranch;?>'><?php echo $projects[$MR->gitlabID][$MR->sourceProject]->name_with_namespace . ':' . $MR->sourceBranch;?></td>
|
||||
<td class='text' title='<?php echo $projects[$MR->gitlabID][$MR->targetProject]->name_with_namespace . ':' . $MR->targetBranch;?>'><?php echo $projects[$MR->gitlabID][$MR->targetProject]->name_with_namespace . ':' . $MR->targetBranch;?></td>
|
||||
<td class='text' title='<?php echo $sourceProject;?>'><?php echo $sourceProject;?></td>
|
||||
<td class='text' title='<?php echo $targetProject;?>'><?php echo $targetProject;?></td>
|
||||
<?php if($MR->status == 'closed'):?>
|
||||
<td class='text'><?php echo zget($lang->mr->statusList, $MR->status);?></td>
|
||||
<?php else:?>
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
<?php common::printIcon('mr', 'edit', "mr=$MR->id", $MR, 'button', 'edit');?>
|
||||
<?php endif;?>
|
||||
<?php if($MR->synced and $rawMR->state == 'closed') common::printIcon('mr', 'reopen', "mr=$MR->id", $MR, 'button', 'restart', 'hiddenwin', 'mergeButton'); ?>
|
||||
<?php common::printIcon('mr', 'delete', "mr=$MR->id", $MR, 'button', 'trash', 'hiddenwin');?>
|
||||
<?php if($projectOwner) common::printIcon('mr', 'delete', "mr=$MR->id", $MR, 'button', 'trash', 'hiddenwin');?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,9 +139,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->compile->atTime;?></th>
|
||||
<td><?php echo $compileJob ? $compileJob->lastExec : $lang->mr->compileUnexecuted;?></td>
|
||||
<td><?php echo $compile->createdDate;?></td>
|
||||
</tr>
|
||||
<?php if($compileJob):?>
|
||||
<?php if($compileJob and !empty($compileJob->id)):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->compile->result;?></th>
|
||||
<td>
|
||||
|
||||
@@ -480,10 +480,11 @@ class projectModel extends model
|
||||
* @param status $status all|wait|doing|suspended|closed|noclosed
|
||||
* @param bool $isQueryAll
|
||||
* @param string $orderBy
|
||||
* @param string $excludedModel
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getPairsByProgram($programID = '', $status = 'all', $isQueryAll = false, $orderBy = 'order_asc')
|
||||
public function getPairsByProgram($programID = '', $status = 'all', $isQueryAll = false, $orderBy = 'order_asc', $excludedModel = '')
|
||||
{
|
||||
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectPairs();
|
||||
return $this->dao->select('id, name')->from(TABLE_PROJECT)
|
||||
@@ -491,6 +492,7 @@ class projectModel extends model
|
||||
->andWhere('deleted')->eq(0)
|
||||
->beginIF($programID !== '')->andWhere('parent')->eq($programID)->fi()
|
||||
->beginIF($status != 'all' && $status != 'noclosed')->andWhere('status')->eq($status)->fi()
|
||||
->beginIF($excludedModel)->andWhere('model')->ne($excludedModel)->fi()
|
||||
->beginIF($status == 'noclosed')->andWhere('status')->ne('closed')->fi()
|
||||
->beginIF(!$this->app->user->admin and !$isQueryAll)->andWhere('id')->in($this->app->user->view->projects)->fi()
|
||||
->orderBy($orderBy)
|
||||
|
||||
@@ -58,10 +58,10 @@ class releaseModel extends model
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
|
||||
->leftJoin(TABLE_BUILD)->alias('t3')->on('t1.build = t3.id')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.project = t4.id')
|
||||
->where('t1.product')->eq((int)$productID)
|
||||
->where('t1.deleted')->eq(0)
|
||||
->beginIF($productID)->andWhere('t1.product')->eq((int)$productID)->fi()
|
||||
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
|
||||
->beginIF($type != 'all')->andWhere('t1.status')->eq($type)->fi()
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
|
||||
@@ -44,14 +44,14 @@ $lang->sonarqube->projectKey = 'Project Key';
|
||||
$lang->sonarqube->projectName = 'Project Name';
|
||||
$lang->sonarqube->projectlastAnalysis = 'Last analysis time';
|
||||
|
||||
$lang->sonarqube->reprot = new stdclass();
|
||||
$lang->sonarqube->reprot->bugs = 'Bugs';
|
||||
$lang->sonarqube->reprot->vulnerabilities = 'Vulnerabilities';
|
||||
$lang->sonarqube->reprot->security_hotspots_reviewed = 'Hotspots Reviewed';
|
||||
$lang->sonarqube->reprot->code_smells = 'Code Smells';
|
||||
$lang->sonarqube->reprot->coverage = 'Coverage';
|
||||
$lang->sonarqube->reprot->duplicated_lines_density = 'Duplications';
|
||||
$lang->sonarqube->reprot->ncloc = 'Lines';
|
||||
$lang->sonarqube->report = new stdclass();
|
||||
$lang->sonarqube->report->bugs = 'Bugs';
|
||||
$lang->sonarqube->report->vulnerabilities = 'Vulnerabilities';
|
||||
$lang->sonarqube->report->security_hotspots_reviewed = 'Hotspots Reviewed';
|
||||
$lang->sonarqube->report->code_smells = 'Code Smells';
|
||||
$lang->sonarqube->report->coverage = 'Coverage';
|
||||
$lang->sonarqube->report->duplicated_lines_density = 'Duplications';
|
||||
$lang->sonarqube->report->ncloc = 'Lines';
|
||||
|
||||
$lang->sonarqube->qualitygateList = array();
|
||||
$lang->sonarqube->qualitygateList['OK'] = 'Passed';
|
||||
|
||||
@@ -26,7 +26,6 @@ $lang->sonarqube->private = 'MD5验证';
|
||||
|
||||
$lang->sonarqube->createServer = '添加SonarQube服务器';
|
||||
$lang->sonarqube->editServer = '修改SonarQube服务器';
|
||||
$lang->sonarqube->desc = '描述';
|
||||
$lang->sonarqube->createSuccess = "创建成功";
|
||||
|
||||
$lang->sonarqube->placeholder = new stdclass;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
removeDitto();//Remove 'ditto' in first row.
|
||||
if($('#batchCreateForm table thead tr th.c-title').width() < 150) $('#batchCreateForm table thead tr th.c-title').width('150');
|
||||
if($('#batchCreateForm table thead tr th.c-title').width() < 170) $('#batchCreateForm table thead tr th.c-title').width('170');
|
||||
|
||||
$(document).keydown(function(event)
|
||||
{
|
||||
|
||||
@@ -1668,7 +1668,13 @@ class treeModel extends model
|
||||
{
|
||||
$this->dao->update(TABLE_MODULE)->set('root')->eq($module->root)->where('id')->in($childs)->exec();
|
||||
$this->dao->update(TABLE_MODULE)->set('branch')->eq($module->branch)->where('id')->in($childs)->exec();
|
||||
if($self->type == 'doc') $this->dao->update(TABLE_DOC)->set('`lib`')->eq($module->root)->where('module')->eq($moduleID)->exec();
|
||||
if($self->type == 'doc')
|
||||
{
|
||||
$this->dao->update(TABLE_DOC)->set('`lib`')->eq($module->root)
|
||||
->where('module')->eq($moduleID)
|
||||
->orWhere('module')->in($childs)
|
||||
->exec();
|
||||
}
|
||||
}
|
||||
$this->fixModulePath(isset($module->root) ? $module->root : $self->root, $self->type);
|
||||
if(isset($module->root) and $module->root != $self->root) $this->changeRoot($moduleID, $self->root, $module->root, $self->type);
|
||||
|
||||
+29
-27
@@ -158,6 +158,7 @@ class tutorialModel extends model
|
||||
$project->whitelist = '';
|
||||
$project->budget = 0;
|
||||
$project->displayCards = 0;
|
||||
$project->fluidBoard = 0;
|
||||
$project->deleted = '0';
|
||||
|
||||
return $project;
|
||||
@@ -268,33 +269,34 @@ class tutorialModel extends model
|
||||
public function getExecution()
|
||||
{
|
||||
$execution = new stdclass();
|
||||
$execution->id = 3;
|
||||
$execution->project = 2;
|
||||
$execution->type = 'sprint';
|
||||
$execution->name = 'Test execution';
|
||||
$execution->code = 'test';
|
||||
$execution->lifetime = '';
|
||||
$execution->begin = date('Y-m-d', strtotime('-7 days'));
|
||||
$execution->end = date('Y-m-d', strtotime('+7 days'));
|
||||
$execution->days = 10;
|
||||
$execution->status = 'wait';
|
||||
$execution->pri = '1';
|
||||
$execution->desc = '';
|
||||
$execution->goal = '';
|
||||
$execution->acl = 'open';
|
||||
$execution->parent = 2;
|
||||
$execution->path = ',2,3,';
|
||||
$execution->grade = 1;
|
||||
$execution->PM = $this->app->user->account;
|
||||
$execution->PO = $this->app->user->account;
|
||||
$execution->QD = $this->app->user->account;
|
||||
$execution->RD = $this->app->user->account;
|
||||
$execution->deleted = '0';
|
||||
$execution->totalConsumed = 0;
|
||||
$execution->totalLeft = 0;
|
||||
$execution->totalHours = 0;
|
||||
$execution->totalEstimate = 0;
|
||||
$execution->displayCards = 0;
|
||||
$execution->id = 3;
|
||||
$execution->project = 2;
|
||||
$execution->type = 'sprint';
|
||||
$execution->name = 'Test execution';
|
||||
$execution->code = 'test';
|
||||
$execution->lifetime = '';
|
||||
$execution->begin = date('Y-m-d', strtotime('-7 days'));
|
||||
$execution->end = date('Y-m-d', strtotime('+7 days'));
|
||||
$execution->days = 10;
|
||||
$execution->status = 'wait';
|
||||
$execution->pri = '1';
|
||||
$execution->desc = '';
|
||||
$execution->goal = '';
|
||||
$execution->acl = 'open';
|
||||
$execution->parent = 2;
|
||||
$execution->path = ',2,3,';
|
||||
$execution->grade = 1;
|
||||
$execution->PM = $this->app->user->account;
|
||||
$execution->PO = $this->app->user->account;
|
||||
$execution->QD = $this->app->user->account;
|
||||
$execution->RD = $this->app->user->account;
|
||||
$execution->deleted = '0';
|
||||
$execution->totalConsumed = 0;
|
||||
$execution->totalLeft = 0;
|
||||
$execution->totalHours = 0;
|
||||
$execution->totalEstimate = 0;
|
||||
$execution->displayCards = 0;
|
||||
$execution->fluidBoard = 0;
|
||||
return $execution;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,3 +150,4 @@ $lang->upgrade->fromVersions['15_7_1'] = '15.7.1';
|
||||
$lang->upgrade->fromVersions['16_0_beta1'] = '16.0.beta1';
|
||||
$lang->upgrade->fromVersions['16_0'] = '16.0';
|
||||
$lang->upgrade->fromVersions['16_1'] = '16.1';
|
||||
$lang->upgrade->fromVersions['16_2'] = '16.2';
|
||||
|
||||
@@ -753,7 +753,8 @@ class upgradeModel extends model
|
||||
case '16_2':
|
||||
$this->saveLogs('Execute 16_2');
|
||||
$this->execSQL($this->getUpgradeFile('16.2'));
|
||||
$this->addSpaceTeam();
|
||||
$this->updateSpaceTeam();
|
||||
$this->updateDocField();
|
||||
$this->appendExec('16_2');
|
||||
}
|
||||
|
||||
@@ -964,6 +965,7 @@ class upgradeModel extends model
|
||||
case '16_0_beta1': $confirmContent .= file_get_contents($this->getUpgradeFile('16.0.beta1'));
|
||||
case '16_0': $confirmContent .= file_get_contents($this->getUpgradeFile('16.0'));
|
||||
case '16_1': $confirmContent .= file_get_contents($this->getUpgradeFile('16.1'));
|
||||
case '16_2': $confirmContent .= file_get_contents($this->getUpgradeFile('16.2'));
|
||||
}
|
||||
return str_replace('zt_', $this->config->db->prefix, $confirmContent);
|
||||
}
|
||||
@@ -5458,8 +5460,8 @@ class upgradeModel extends model
|
||||
*/
|
||||
public function updateSpaceTeam()
|
||||
{
|
||||
$kanbanUsers = $this->dao->select("space, CONCAT(owner, ',', team) as users") ->from(TABLE_KANBAN)->fetchAll('space');
|
||||
$spaceUsers = $this->dao->select("id, CONCAT(owner, ',', team) as users")->from(TABLE_KANBANSPACE)->fetchAll('id');
|
||||
$kanbanUsers = $this->dao->select("space, CONCAT(owner, ',', team, ',', whitelist) as users") ->from(TABLE_KANBAN)->fetchAll('space');
|
||||
$spaceUsers = $this->dao->select("id, CONCAT(owner, ',', team, ',', whitelist) as users")->from(TABLE_KANBANSPACE)->fetchAll('id');
|
||||
|
||||
foreach($kanbanUsers as $spaceID => $kanban)
|
||||
{
|
||||
@@ -5473,6 +5475,8 @@ class upgradeModel extends model
|
||||
|
||||
$this->dao->update(TABLE_KANBANSPACE)->set('`team`')->eq($team)->where('id')->eq($spaceID)->exec();
|
||||
}
|
||||
$this->dao->update(TABLE_KANBANSPACE)->set('`whitelist`')->eq('')->exec();
|
||||
$this->dao->update(TABLE_KANBAN)->set('`whitelist`')->eq('')->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5580,4 +5584,23 @@ class upgradeModel extends model
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Document library for updating documents.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateDocField()
|
||||
{
|
||||
$hasModuleDocs = $this->dao->select('*')->from(TABLE_DOC)->where('module')->ne(0)->fetchAll('id');
|
||||
$docModules = $this->dao->select('*')->from(TABLE_MODULE)->where('type')->eq('doc')->fetchAll('id');
|
||||
foreach($hasModuleDocs as $doc)
|
||||
{
|
||||
$libID = isset($docModules[$doc->module]->root) ? $docModules[$doc->module]->root : 0;
|
||||
if(!$libID or $libID == $doc->lib) continue;
|
||||
$this->dao->update(TABLE_DOC)->set('lib')->eq($libID)->where('id')->eq($doc->id)->exec();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试productModel->getLatestProject();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
}
|
||||
|
||||
public function testGetLatestProject($productID)
|
||||
{
|
||||
$project = $this->product->getLatestProject($productID);
|
||||
if($project == false) return '没有数据';
|
||||
return $project;
|
||||
}
|
||||
}
|
||||
|
||||
$z = new Tester('admin');
|
||||
|
||||
r($z->testGetLatestProject(25)) && p('id') && e('315'); // 测试产品25关联的最后一个未关闭的项目,按begin字段排序
|
||||
r($z->testGetLatestProject(38)) && p('id') && e('688'); // 测试产品38关联的最后一个未关闭的项目,按begin字段排序
|
||||
r($z->testGetLatestProject(101)) && p() && e('没有数据'); // 传入不存在的产品
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env php
|
||||
<?php include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=productModel->getProjectListByProduct();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
}
|
||||
|
||||
public function getAllProjectsByProduct($productID)
|
||||
{
|
||||
$projects = $this->product->getProjectListByProduct($productID, 'all');
|
||||
if($projects == array()) return '没有数据';
|
||||
return $projects;
|
||||
}
|
||||
|
||||
public function getProjectsByStatus($productID, $status)
|
||||
{
|
||||
$projects = $this->product->getProjectListByProduct($productID, $browseType);
|
||||
if($projects == array()) return '没有数据';
|
||||
return $projects;
|
||||
}
|
||||
}
|
||||
|
||||
$tester = new Tester('admin');
|
||||
r($tester->getAllProjectsByProduct(1)) && p('21:name') && e('项目11'); // 返回产品1关联的项目11名字
|
||||
r($tester->getAllProjectsByProduct(1)) && p('11:name') && e('项目1'); // 返回产品1关联的项目21名字
|
||||
r($tester->getAllProjectsByProduct(101)) && p() && e('没有数据'); // 传入不存在的产品
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=productModel->getProjectPairsByProduct();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
}
|
||||
|
||||
public function getProjectPairsByProductID($productID)
|
||||
{
|
||||
$projects = $this->product->getProjectPairsByProduct($productID, 0, 0);
|
||||
if($projects == array()) return '没有数据';
|
||||
return $projects;
|
||||
}
|
||||
|
||||
public function getAppendProject($projectID)
|
||||
{
|
||||
$project = $this->product->getProjectPairsByProduct(10086, 0, $projectID);
|
||||
if($project == array()) return '没有数据';
|
||||
return $project;
|
||||
}
|
||||
}
|
||||
|
||||
$tester = new Tester('admin');
|
||||
|
||||
r($tester->getProjectPairsByProductID(1)) && p('11') && e('项目1'); // 返回产品1关联的项目11名字
|
||||
r($tester->getProjectPairsByProductID(1)) && p('21') && e('项目11'); // 返回产品1关联的项目21名字
|
||||
r($tester->getProjectPairsByProductID(101)) && p() && e('没有数据'); // 传入不存在的产品
|
||||
|
||||
r($tester->getAppendProject(15)) && p('15') && e('项目5'); // 返回id为15的项目名
|
||||
r($tester->getAppendProject(701)) && p() && e('没有数据'); // 传入不存在的项目id
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试productModel->isClickable();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
}
|
||||
|
||||
public function testIsClickable($productID, $status)
|
||||
{
|
||||
$product = $this->product->getById($productID);
|
||||
$isClick = $this->product->isClickable($product, $status);
|
||||
return $isClick == false ? 'false' : 'true';
|
||||
}
|
||||
}
|
||||
|
||||
$adminTester = new Tester('admin');
|
||||
|
||||
r($adminTester->testIsClickable(2, 'close')) && p() && e('true'); // status为normal,action为close
|
||||
r($adminTester->testIsClickable(75, 'close')) && p() && e('false'); // status为close,action为close
|
||||
r($adminTester->testIsClickable(2, 'start')) && p() && e('true'); // status为normal,action为start
|
||||
r($adminTester->testIsClickable(75, 'start')) && p() && e('true'); // status为close,action为start
|
||||
File diff suppressed because one or more lines are too long
@@ -30,15 +30,19 @@ $(document).on('showapp', function(e, app)
|
||||
<?php
|
||||
$this->loadModel('im');
|
||||
|
||||
$xuanConfig = new stdclass();
|
||||
$token = $this->im->userGetAuthToken($this->app->user->id, 'zentaoweb');
|
||||
$clientUrl = isset($this->config->webClientUrl) ? $this->config->webClientUrl : 'data/xuanxuan/web/';
|
||||
if(isset($this->config->xuanxuan->turnon) && $this->config->xuanxuan->turnon)
|
||||
{
|
||||
$xuanConfig = new stdclass();
|
||||
$token = $this->im->userGetAuthToken($this->app->user->id, 'zentaoweb');
|
||||
$clientUrl = isset($this->config->webClientUrl) ? $this->config->webClientUrl : 'data/xuanxuan/web/';
|
||||
$backendUrl = $this->im->getServer('zentao');
|
||||
|
||||
$xuanConfig->clientUrl = $clientUrl;
|
||||
$xuanConfig->server = $this->im->getServer('zentao');
|
||||
$xuanConfig->account = $this->app->user->account;
|
||||
$xuanConfig->authKey = $token->token;
|
||||
$xuanConfig->debug = $this->config->debug;
|
||||
$xuanConfig->clientUrl = $clientUrl;
|
||||
$xuanConfig->server = parse_url($backendUrl, PHP_URL_HOST);
|
||||
$xuanConfig->account = $this->app->user->account;
|
||||
$xuanConfig->authKey = $token->token;
|
||||
$xuanConfig->debug = $this->config->debug;
|
||||
}
|
||||
?>
|
||||
<?php if(isset($xuanConfig)): ?>
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user